Update values in next row if condition is met

Viewed 1223

I have a situation where I want the next row's value to be picked up for updating a column instead of the row in which the condition is met. So the conventional ifelse is not working for me.

For example, if the value of column C is greater than 80 then I want the value of column D to be updated with the value of column A, but in the next row. The dummy data set is

A   B  C   D

10 11  12  0
1  13  14  0
3   4  85  0
78  56 56  0
70  80 16  0
60  67 86  0
50  65 77  0

The expected dataset is

A   B  C   D

10 11  12  0
1  13  14  0
3   4  85  0
78  56 56  78
70  80 16  0
60  67 86  0
50  65 77  50
2 Answers

We can use an ifelse

library(tidyverse)
df1 %>% 
    mutate(D = lag(ifelse(C > 80, lead(A), D), default = first(D)))
#   A  B  C  D
#1 10 11 12  0
#2  1 13 14  0
#3  3  4 85  0
#4 78 56 56 78
#5 70 80 16  0
#6 60 67 86  0
#7 50 65 77 50

Or multiply with logical index

df1 %>% 
   mutate(D = lag((C > 80) * lead(A, default = last(A)), default = first(D)))

It can be also done in base R

df1$D <-  with(df1, c(D[1], head((C > 80) * c(A[-1], A[length(A)]), -1)))

data

df1 <- structure(list(A = c(10L, 1L, 3L, 78L, 70L, 60L, 50L), B = c(11L, 
13L, 4L, 56L, 80L, 67L, 65L), C = c(12L, 14L, 85L, 56L, 16L, 
86L, 77L), D = c(0L, 0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", 
 row.names = c(NA, -7L))

We could get the indices where C is greater than 80, increment it by 1. Get the corresponding A values and update it in D.

inds <- which(df$C > 80) + 1
df$D[inds] <- df$A[inds]


df
#   A  B  C  D
#1 10 11 12  0
#2  1 13 14  0
#3  3  4 85  0
#4 78 56 56 78
#5 70 80 16  0
#6 60 67 86  0
#7 50 65 77 50

As mentioned by @G. Grothendieck, this would return an error if the last value in C is greater than 80. In such cases we update only those inds which are less than or equal to number of rows in the dataframe.

df$D[inds[inds <= nrow(df)]] <- df$A[inds[inds <= nrow(df)]]
Related