Boone
Boone

Reputation: 137

Add Conditional Calculated Column to R Dataframe

I'm needing to add a column to a dataframe that marks "X" if column 1 is greater than 0 and the preceding row's column 1 was less than 0.

So given:

c1 = c(0,1,-1,1,2,0,1)

testdf <- data.frame(c1)

I'd like to add column "new" to testdf as:

| c1 | new |

+----+-----+

|  0 |     |

|  1 |     |

| -1 |     |

|  1 | X   |

|  2 |     |

|  0 |     |

|  1 |     |

I believe it will need the usage shift(), which I understand enough to create a subset with the command subsetdf <- subset(testdf,c1>0 & shift(c1,1)<0)

Upvotes: 0

Views: 248

Answers (3)

akrun
akrun

Reputation: 887028

We can try

i1 <- with(testdf, c(FALSE,c1[-1] >0 & c1[-length(c1)] < 0 ))
testdf$new <- ifelse(i1, 'X', '')
testdf$new 
#[1] ""  ""  ""  "X" ""  ""  "" 

Or using dplyr

library(dplyr)
testdf %>%
       mutate(new=c("", "X")[(c1>0 & lag(c1)< 0)+1L])

In the mutate call we can also use ifelse as in the other post.

Upvotes: 1

Gopala
Gopala

Reputation: 10473

Easy to do such column mutation with dplyr package and lag operator as follows:

library(dplyr)
testdf <- testdf %>% mutate(new = ifelse(c1 > 0 & lag(c1) < 0, 'X', ''))

Upvotes: 0

Derek Damron
Derek Damron

Reputation: 338

If you did want use shift from data.table, you could go about it this way:

library(data.table)
testdf$c1_lag <- shift(testdf$c1, n=1L)
testdf$new <- ifelse(testdf$c1 > 0 & testdf$c1_lag < 0, "X", "")
testdf
#   c1 c1_lag new
# 1  0     NA    
# 2  1      0    
# 3 -1      1    
# 4  1     -1   X
# 5  2      1    
# 6  0      2    
# 7  1      0    

Upvotes: 0

Related Questions