Ujjawal Bhandari
Ujjawal Bhandari

Reputation: 1372

case_when breaks in multiple conditions

I have sample dataframe having ID against Var and lagged variable of var LagVar.

sd <- read.table(header = T, text = "ID Var LagVar
A 1 NA
A 2 1
A 4 2
A 6 4
")

I am checking if LagVar is same as Var or (Var -1). It is returning FALSE against last 2 rows.

I want Flag to set FALSE for first 2 rows and TRUE for last 2 rows.

Upvotes: 1

Views: 956

Answers (1)

akrun
akrun

Reputation: 886938

The issue is with the order of statements and also the general property of %in% which does check for all the values in the column or the created vector with c and thus returns all TRUE as these values in 'LagVar' are present in 'Var' columns

library(dplyr)
sd %>%
     mutate(Flag = ((LagVar %in% c(Var, Var - 1)) | (Var == 1)))

-output

ID Var LagVar Flag
1 P2   1     NA TRUE
2 P2   2      1 TRUE
3 P2   4      2 TRUE
4 P2   6      4 TRUE

returns all TRUE, thus it checks on that alone instead of going into next ones

If we use a simple example

v1 <- 1:5
case_when(v1 <= 5 ~ FALSE, TRUE ~ TRUE)
[1] FALSE FALSE FALSE FALSE FALSE

The first condition returns all TRUE, thus it wouldn't execute the next condition. The ~ is assigning the value based on the condition and not the condition itself. If we want to execute the next condition, the first one should return FALSE and not by assignment

case_when(v1 > 5~  FALSE, TRUE ~ TRUE)
[[1] TRUE TRUE TRUE TRUE TRUE

There is a confusion among the actual condition and the return value as both are logical


When we do the %in%, it checks all the rows unless grouped. We could add rowwise attribute to prevent the check for all the rows

sd %>% 
    rowwise %>% 
    mutate(Flag = !(LagVar %in% c(Var, Var-1)|(Var == 1))) %>%
    ungroup
# A tibble: 4 x 4
  ID      Var LagVar Flag 
  <chr> <int>  <int> <lgl>
1 P2        1     NA FALSE
2 P2        2      1 FALSE
3 P2        4      2 TRUE 
4 P2        6      4 TRUE 

Or we may need to add one more condition with == and | as == does elementwise comparison

sd %>%
    mutate(Flag = !(LagVar == Var| LagVar == (Var - 1)|(Var == 1)))
ID Var LagVar  Flag
1 P2   1     NA FALSE
2 P2   2      1 FALSE
3 P2   4      2  TRUE
4 P2   6      4  TRUE

Upvotes: 2

Related Questions