Taha
Taha

Reputation: 65

How to pass a vector of column names in case_when

I am using case_when to summarise a data frame using rowwise in dplyr. I have a sample data frame as shown below

structure(list(A = c(NA, 1, 0, 0, 0, 0, 0), B = c(NA, 0, 0, 1, 
0, 0, 0), C = c(NA, 1, 0, 0, 0, 0, 0), D = c(NA, 1, 0, 1, 0, 
0, 1), E = c(NA, 1, 0, 1, 0, 0, 1)), row.names = c(NA, -7L), class = "data.frame")

The code works when I mention all the names

df %>%                                         
  rowwise() %>%                                   
  mutate(New =  case_when(any(c(A,B,C,D,E) == 1)  ~ 1,
                       all(c(A,B,C,D,E) == 0 ) ~ 0
                       ))

Can I pass the names in a vector, e.g cols <- colnames(df), and then that in case_when

Upvotes: 3

Views: 575

Answers (3)

akrun
akrun

Reputation: 887241

In base R, we can do this with

df$New <- +( rowSums(df) > 0)

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 389055

To answer your question you can use cur_data() in dplyr 1.0.0 or c_across()

library(dplyr)

df %>%                                         
  rowwise() %>%                                   
  mutate(New  =  case_when(any(cur_data() == 1)  ~ 1,
                          all(cur_data() == 0 ) ~ 0))

#     A     B     C     D     E   New
#  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1    NA    NA    NA    NA    NA    NA
#2     1     0     1     1     1     1
#3     0     0     0     0     0     0
#4     0     1     0     1     1     1
#5     0     0     0     0     0     0
#6     0     0     0     0     0     0
#7     0     0     0     1     1     1

With c_across() :

df %>%                                         
  rowwise() %>%                                   
  mutate(New =  case_when(any(c_across()== 1)  ~ 1,
                          all(c_across()== 0 ) ~ 0))

But you can also solve this using rowSums :

df %>%                                         
 mutate(New = case_when(rowSums(. == 1, na.rm = TRUE) > 0 ~ 1, 
                        rowSums(. == 0, na.rm = TRUE) == ncol(.) ~ 0))

Upvotes: 3

maarvd
maarvd

Reputation: 1284

If you only have 0's and 1's in your dataset you could use this

df$New <- ifelse(rowSums(df) > 0, 1, 0)

If the rowsum > 0 it means that at least one '1' is present. Output

   A  B  C  D  E New
1 NA NA NA NA NA  NA
2  1  0  1  1  1   1
3  0  0  0  0  0   0
4  0  1  0  1  1   1
5  0  0  0  0  0   0
6  0  0  0  0  0   0
7  0  0  0  1  1   1

Upvotes: 1

Related Questions