case_when
has a specificity - it evaluates all the RHS then filter according the to LHS. In your case, it is why you see the all the combination because
- all the
print
are evaluated (printed to console)
- nothing is return by the filter because print return invisibly
To illustrate,
If you assign the result of case_when
to y
, you'll still have the values printed and when printing y
, you'll have only the last returned value invisibly by print.
library(tidyverse)
x <- Sys.info() %>% pluck("sysname")
y <- case_when(x == "Linux" ~{
print("L1")
print("L2")
},
x == "Windows" ~ {
print("W1")
print("W2")
},
TRUE ~ {
("Not Linux or Windows")
})
#> [1] "L1"
#> [1] "L2"
#> [1] "W1"
#> [1] "W2"
# you only get the last value return in expression
# like any other function
y
#> [1] "W2"
If you do not print, but build a vector of what you want using c()
and print directly the result of case_when
, you'll have the correct result.
library(tidyverse)
x <- Sys.info() %>% pluck("sysname")
case_when(
x == "Linux" ~ c("L1","L2"),
x == "Windows" ~ c("W1", "W2"),
TRUE ~ "Not Linux or Windows"
)
#> [1] "W1" "W2"
Created on 2018-11-06 by the reprex package (v0.2.1)
Is it clearer ?
for what you want to achieve, switch
could be the solution. Not everything has to be transform in tidyverse
One big advantage is that it is vectorised with a default value if nothin found - unlike switch - and this is very practical in data.frame manipulation.
library(tidyverse)
x <- c("Windows", "Linux", "other")
case_when(
x == "Linux" ~ "L1",
x == "Windows" ~ "W1",
TRUE ~ "Not Linux or Windows"
)
#> [1] "W1" "L1" "Not Linux or Windows"
switch(x,
Linux = "L1",
Windows = "W1"
)
#> Error in switch(x, Linux = "L1", Windows = "W1") : EXPR must be a length 1 vector
case_when
is also kind of string as you can replace value only by the same type.