10

I'm interested in simplifying the way that I can remove columns with dplyr (version >= 0.7). Let's say that I have a character vector of names.

drop <- c("disp", "drat", "gear", "am")

Selecting Columns

With the current version version of dplyr, you can perform a selection with:

dplyr::select(mtcars, !! rlang::quo(drop))

Or even easier with base R:

mtcars[, drop]

Removing Columns

Removing columns names is another matter. We could use each unquoted column name to remove them:

dplyr::select(mtcars, -disp, -drat, -gear, -am)

But, if you have a data.frame with several hundred columns, this isn't a great solution. The best solution I know of is to use:

dplyr::select(mtcars, -which(names(mtcars) %in% drop))

which is fairly simple and works for both dplyr and base R. However, I wonder if there's an approach which doesn't involve finding the integer positions for each column name in the data.frame.

detroyejr
  • 1,094
  • 1
  • 9
  • 14

2 Answers2

8

Use modify_atand set columns to NULL which will remove them:

mtcars %>% modify_at(drop,~NULL)
#                    mpg cyl  hp    wt  qsec vs carb
# Mazda RX4         21.0   6 110 2.620 16.46  0    4
# Mazda RX4 Wag     21.0   6 110 2.875 17.02  0    4
# Datsun 710        22.8   4  93 2.320 18.61  1    1
# Hornet 4 Drive    21.4   6 110 3.215 19.44  1    1
# Hornet Sportabout 18.7   8 175 3.440 17.02  0    2
# Valiant           18.1   6 105 3.460 20.22  1    1
# ...

Closer to what you were trying, you could have tried magrittr::extract instead of dplyr::select

extract(mtcars,!names(mtcars) %in% drop) # same output
moodymudskipper
  • 46,417
  • 11
  • 121
  • 167
6

You can use -one_of(drop) with select:

drop <- c("disp", "drat", "gear", "am")
select(mtcars, -one_of(drop)) %>% names()
# [1] "mpg"  "cyl"  "hp"   "wt"   "qsec" "vs"   "carb"

one_of evaluates the column names in character vector to integers, similar to which(... %in% ...) does:

one_of(drop, vars = names(mtcars))
# [1]  3  5 10  9

which(names(mtcars) %in% drop)
# [1]  3  5  9 10
Psidom
  • 209,562
  • 33
  • 339
  • 356