I want to create a new column in a data.table
with some nested ifelse()
statements: I included a control with stop()
at the end, which should never be reached. In my exampled either condition_a
or condition_b
has to be "Y"
. The stop()
should never be reached, but it does. Can someone explain this to me?
Example code:
library(data.table)
condition_a <- c("Y", "Y", "Y", "Y", "Y", "Y")
condition_b <- c("Y", "Y", "Y", "Y", "Y", "N")
dt <- data.table(condition_a, condition_b)
dt <-
dt[, conditions := ifelse(test = ((condition_a == "Y") &
(condition_b == "Y")),
yes = "a_and_b",
no = ifelse(test = ((condition_a == "N") &
(condition_b == "Y")),
yes = "b",
no = ifelse(test = ((condition_a == "Y") &
(condition_b == "N")),
yes = "a",
no = ifelse(test = ((condition_a == "N") &
(condition_b == "N")),
yes = stop('double "N" found'),
no = stop("this should not happen")))))]
Thanks for your help :).
CodePudding user response:
You obtained an error because ifelse
often evaluates all its arguments (but not always: there are edges cases where there is no evaluation like in ifelse(test=c(1, NA)==c(NA, 1), stop("notEval"), stop("notEavl"))
; note that in this particular case, the test
argument evaluates to only NA
s).
If you would like to evaluate an argument only when it's necessary, you should use the data.table function fcase
, which is a nice and smart implementation of nested ifelse.
dt[, conditions := fcase(condition_a == "Y" & condition_b == "Y", "a_and_b",
condition_a == "N" & condition_b == "Y", "b",
condition_a == "Y" & condition_b == "N", "a",
condition_a == "N" & condition_b == "N", stop('double "N" found'))]
In this case, the statement with stop
will never be evaluated because the there is no case where condition_a == "N" & condition_b == "N"
evaluates to TRUE
in dt
.
Also note that data.table works by reference; so, there is no need to reassign your data.table when using :=
. that is, dt[, conditions := ...]
will add a new column to dt
. you don't need to use the assignment operator <-
like in dt <- dt[, conditions := ...]
.