Pierre Jardinet
Pierre Jardinet

Reputation: 55

Add value to column and previous row if condition is met

Imagine I have a dataframe df with those columns

RT   Error Number
0.2  0     4
0.3  0     4
0.3  1     3
0.4  0     4
0.2  1     3
0.2  0     4      
0.3  0     3      

What I did is add a column which I do with

Df["ThirdColumn"] <- 0

Df:

RT   Error Number ThirdColumn
0.2  0     4      0
0.3  0     4      0
0.3  1     3      0
0.4  0     4      0
0.2  1     3      0  
0.2  0     4      0
0.3  0     3      0

Now I would like to modify the 0's in ThirdColumn that precede an Error ==1 & Number == 3 with 8 and the 0's in ThirdColumn that precede an Error ==0 with Number == 3 with 9

Expected result

RT   Error Number ThirdColumn
0.2  0     4      0
0.3  0     4      8
0.3  1     3      0
0.4  0     4      8
0.2  1     3      0  
0.2  0     4      9
0.3  0     3      0

I tried several if statements but I keep getting errors.

Upvotes: 0

Views: 167

Answers (3)

Ronak Shah
Ronak Shah

Reputation: 388862

We can use lead from dplyr to get leading values of columns.

library(dplyr)
Df$ThirdColumn <- with(Df, ifelse(lead(Error) == 1 & lead(Number == 3), 8, 
                           ifelse(lead(Error) == 0 & lead(Number) == 3, 9, 0)))

The last number would return NA in this case which can be later changed to 0 easily.

Df$ThirdColumn[nrow(Df)] <- 0

Df
#   RT Error Number ThirdColumn
#1 0.2     0      4           0
#2 0.3     0      4           8
#3 0.3     1      3           0
#4 0.4     0      4           8
#5 0.2     1      3           0
#6 0.2     0      4           9
#7 0.3     0      3           0

Upvotes: 0

Spacedman
Spacedman

Reputation: 94182

Which rows satisfy the criteria?

> W = which((Df$Error==1 | Df$Error==0) & Df$Number==3)

Now set the value in rows W-1 and use 9-Df$Error to get 9 when Error is 0 and 8 when Error is 1:

> Df$ThirdColumn[W-1] = 9-Df$Error[W]
> 
> Df
   RT Error Number ThirdColumn
1 0.2     0      4           0
2 0.3     0      4           8
3 0.3     1      3           0
4 0.4     0      4           8
5 0.2     1      3           0
6 0.2     0      4           9
7 0.3     0      3           0

Upvotes: 1

akrun
akrun

Reputation: 886998

We can do this with which

library(data.table)
setDT(Df)[which(Error==1 & Number==3)-1, ThirdColumn := 8]
Df[which(Error==0 & Number==3)-1, ThirdColumn := 9]
Df
#    RT Error Number ThirdColumn
#1: 0.2     0      4           0
#2: 0.3     0      4           8
#3: 0.3     1      3           0
#4: 0.4     0      4           8
#5: 0.2     1      3           0
#6: 0.2     0      4           9
#7: 0.3     0      3           0

We can also do this with base R

i1 <- with(Df, which(Error ==1 & Number == 3)-1)
i2 <- with(Df, which(Error ==0 & Number == 3)-1)
Df$ThirdColumn[i1] <- 8
Df$ThirdColumn[i2] <- 9

Upvotes: 0

Related Questions