31

I have a df as follows:

a <- data_frame(keep=c("hello", "world"),drop = c("nice", "work"))
a
Source: local data frame [2 x 2]
   keep  drop
  (chr) (chr)
1 hello  nice
2 world  work

I can use a %>% select(-drop) to drop the column without problem. however, if I want to pass a variable to present drop column, then it returns error.

name <- "drop"
a  %>% select(-(name))

Error in -(name) : invalid argument to unary operator

UseR10085
  • 7,120
  • 3
  • 24
  • 54
HappyCoding
  • 5,029
  • 7
  • 31
  • 51

6 Answers6

46

You can use one_of to find the column positions and then use - to drop it, select(-one_of(name)), if you check ?select, the usage is documented in the Drop variable section in the Examples:

name <- "drop"
a %>% select(-one_of(name))

# A tibble: 2 × 1
#   keep
#  <chr>
#1 hello
#2 world

Or with select_, you need to paste - with the column names to drop them and pass the pasted column names to the .dots parameter if there are more than one column to be dropped:

name <- "drop"
a %>% select_(.dots = paste("-", name))

# A tibble: 2 × 1
#   keep
#  <chr>
#1 hello
#2 world
Psidom
  • 209,562
  • 33
  • 339
  • 356
11

You can simple use

a <- data_frame(keep=c("hello", "world"),drop = c("nice", "work"))
select(a, -starts_with('drop'))
#   Source: local data frame [2 x 1]
#
#   keep
#   (chr)
# 1 hello
# 2 world

you have to search for some previously written solutions too. Please read the document here Select/rename variables by name.DPLYR

I hope that does the job for you :) @Psidom thanx for updating your answer.. but I will request upvoters for vote for me too as I recently became an active user and still am to get basic privileges on stackoverflow.

Richard
  • 1,224
  • 3
  • 16
  • 32
Mandar
  • 1,659
  • 1
  • 10
  • 14
4

We can use select_ with setdiff

a %>%
    select_(setdiff(names(.), name))
# A tibble: 2 × 1
#   keep
#   <chr>
#1 hello
#2 world
robertspierre
  • 3,218
  • 2
  • 31
  • 46
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Notice that `select_` is not available anymore with modern versions of dplyr (as of August 2023). See [James Hirschorn's answer](https://stackoverflow.com/a/70359311/1719931) for how to do it with modern versions of dplyr. – robertspierre Aug 27 '23 at 18:10
4

A few more possibilities:

name <- "drop"
a %>% `[<-`(name, value=NULL)
a %>% magrittr::inset(name,value=NULL)
a %>% purrr::modify_at(name,~NULL)
moodymudskipper
  • 46,417
  • 11
  • 121
  • 167
1

I could only get these solutions to work by first ungrouping the data using ungroup:

df <- df  %>%  ungroup  %>%  select(-hello)

Notice no quotation marks on the column name you want to drop (hello). Also, to remove multiple columns, just place a , after hello and add the second column.

Marty999
  • 213
  • 1
  • 4
  • 12
1

From the ?select_ help:

dplyr used to offer twin versions of each verb suffixed with an underscore [...] However, dplyr now uses tidy evaluation semantics. [...] Thus, the underscored versions are now superfluous.

The example given in vignette("programming"), similar to @Psidom's answer, is:

name <- "drop"
a %>% select(!all_of(name))

Alternatively, this one could create a function to drop columns, so that drop does not need quoting:

drop_columns <- function(data, cols) {
  data %>% select(!{{cols}})
}

drop_columns(a, drop)
robertspierre
  • 3,218
  • 2
  • 31
  • 46
James Hirschorn
  • 7,032
  • 5
  • 45
  • 53