Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can dplyr::case_when return mix of NAs and non-NAs? [duplicate]

Tags:

r

dplyr

Can case_when() in dplyr return a mix of NA and non-NA values?

When I ask it to return NA in response to one statement, but an non-NA value in response to another statement, it throws an evaluation error:

E.g, I want 1 for all values of cyl >= 6, and NA for values of cyl < 6

> library("dplyr")
> mtcars %>% mutate(thing = case_when(cyl >= 6 ~ 1, cyl < 6 ~ NA ))

Error in mutate_impl(.data, dots) : Evaluation error: must be type double, not logical.

Alone, both of the statements evaluate fine.

This problem isn't present if asking for all NAs to be returned, but not a mixture of NAs and non-NAs.

E.g.: Return NA for all values of cyl >= 6

> mtcars %>% mutate(thing = case_when(cyl >= 6 ~ NA))
  cyl thing
1   6    NA
2   6    NA
3   4    NA

Looks good.

> mtcars %>% mutate(thing = case_when(cyl >= 6 ~ NA, cyl < 6 ~ NA ))
  cyl thing
1   6    NA
2   6    NA
3   4    NA

Cool.

> mtcars[1:3,] %>% mutate(thing = case_when(cyl == 6 ~ 1, cyl < 6 ~ NA, cyl > 6 ~ NA ))

Error in mutate_impl(.data, dots) : Evaluation error: must be type double, not logical.

Not cool.

NB: for clarity returned items in the examples are all from mtcars[1:3,] with %>% select(cyl, thing) at the end of the expression.

like image 611
Scransom Avatar asked Oct 20 '17 05:10

Scransom


1 Answers

Here is the problem with class. We need NA_real to match the numeric type

mtcars %>% 
      mutate(thing = case_when(cyl >= 6 ~ 1,
                               cyl < 6 ~ NA_real_ )) 

Also, for the second case

mtcars[1:3,] %>% 
       mutate(thing = case_when(cyl == 6 ~ 1, 
                                cyl < 6 ~ NA_real_, 
                                cyl > 6 ~ NA_real_ ))  %>%
       select(cyl, thing)
# cyl thing
#   6     1
#   6     1
#   4    NA
like image 131
akrun Avatar answered Nov 14 '22 23:11

akrun