Andres Mora
Andres Mora

Reputation: 1106

How to conditionally assign data to a column

My sample dataset

df= structure(list(v1 = c("OK", "NOT OK", "OK", "OK", "NOT OK"), 
                   v2 = c(NA, NA, NA, NA, NA), 
                   v3 = c(NA, NA, NA, NA, NA), 
                   v4 = structure(c(1633046400, 1638403200, 1634083200, 1634169600, 1635120000), 
                                  class = c("POSIXct", "POSIXt"), 
                                  tzone = "UTC")), 
              row.names = c(NA, -5L), 
              class = c("tbl_df", "tbl", "data.frame"))

my desired output

df = structure(list(v1 = c("OK", "NOT OK", "OK", "OK", "NOT OK"), 
                            v2 = structure(c(NA, 1638403200, NA, NA, 1635120000), 
                                           class = c("POSIXct", "POSIXt"), 
                                           tzone = "UTC"), 
                            v3 = structure(c(1633046400, NA, 1634083200, 1634169600, NA), 
                                           class = c("POSIXct", "POSIXt"), 
                                           tzone = "UTC")), 
                       row.names = c(NA, -5L), 
                       class = c("tbl_df", "tbl", "data.frame"))

I require to set v2 and v3 variables conditionally based on v1 with the data from v4

if v1 == "OK", v4 data should be passed to v2
if v1 == "NOT OK", v4 data should be passed to v3

i have initially thought this approach but im missing something

for (i in df$v1) {
   if (i=="OK")     
     df$v2= df$v4.temp
   else {
     df$v3= df$v4.temp
   }

Upvotes: 0

Views: 47

Answers (2)

Uwe
Uwe

Reputation: 42544

For the sake of completeness, here are two solutions

1. Create new dataset using fifelse()

library(data.table)
setDT(df)[, .(v1, v2 = fifelse(v1 == "OK", v4, NA), v3 = fifelse(v1 == "NOT OK", v4, NA))]
       v1         v2         v3
1:     OK 2021-10-01       <NA>
2: NOT OK       <NA> 2021-12-02
3:     OK 2021-10-13       <NA>
4:     OK 2021-10-14       <NA>
5: NOT OK       <NA> 2021-10-25

2. Update by reference

library(data.table)
setDT(df)[, c("v2", "v3") := NULL][v1 == "OK", v2 := v4][v1 == "NOT OK", v3 := v4][, v4 := NULL]
df

or

library(data.table)
cols <- c("v2", "v3")
setDT(df)[, (cols) := lapply(.SD, as.POSIXct, tz = "UTC"), .SDcols = cols][
  v1 == "OK", v2 := v4][
    v1 == "NOT OK", v3 := v4][, v4 := NULL]
df
       v1         v2         v3
1:     OK 2021-10-01       <NA>
2: NOT OK       <NA> 2021-12-02
3:     OK 2021-10-13       <NA>
4:     OK 2021-10-14       <NA>
5: NOT OK       <NA> 2021-10-25

Upvotes: 0

ThomasIsCoding
ThomasIsCoding

Reputation: 101373

A base R option using replace

transform(
  df,
  v2 = replace(v4, v1 != "OK", NA),
  v3 = replace(v4, v1 == "OK", NA)
)

gives

      v1         v2         v3         v4
1     OK 2021-10-01       <NA> 2021-10-01
2 NOT OK       <NA> 2021-12-02 2021-12-02
3     OK 2021-10-13       <NA> 2021-10-13
4     OK 2021-10-14       <NA> 2021-10-14
5 NOT OK       <NA> 2021-10-25 2021-10-25

Upvotes: 1

Related Questions