Drop (or negation selection) multiple variables represented by a vector of strings in dplyr

Viewed 96

I have data frame as follows

df = data.frame(a=c(1:10), b=c(2:11), c=c(2:13))

The user specified a vector of variable names as characters

user_cols = c('a', 'b')

I want to take the vector and use select() to keep the variables being reference by the vector. The following code would work

df2 = df %>%
  select(!!!syms(user_cols))

However, if I want to drop these variable rather than keep these variables, adding a negation (-) directly to the syntax would NOT work:

df2 = df %>%
  select(-!!!syms(user_cols)) #Adding negation '-' hoping to de-select

Is there a good way of achieving this dropping operation in dplyr?

2 Answers

Simply use the object to select the columns

library(dplyr)
df %>%
      select(user_cols)

If we needed, in the new version of dplyr, we can wrap with all_of

df %>%
   select(all_of(user_cols))
#    a  b
#1   1  2
#2   2  3
#3   3  4
#4   4  5
#5   5  6
#6   6  7
#7   7  8
#8   8  9
#9   9 10
#10 10 11

Or to drop

df %>% 
   select(-all_of(user_cols))
#    c
#1   3
#2   4
#3   5
#4   6
#5   7
#6   8
#7   9
#8  10
#9  11
#10 12

NOTE: We can directly use this and doesn't need any other functions


If we want to use the OP's code, just wrap with c

df %>%
   select(-c(!!!syms(user_cols)))
#    c
#1   3
#2   4
#3   5
#4   6
#5   7
#6   8
#7   9
#8  10
#9  11
#10 12

You can use setdiff :

df[setdiff(names(df), user_cols)]

To use with dplyr, select :

library(dplyr)
df %>% select(setdiff(names(.), user_cols))

#    c
#1   2
#2   3
#3   4
#4   5
#5   6
#6   7
#7   8
#8   9
#9  10
#10 11
Related