Correct usage of dplyr::select in dplyr 0.7.0+, selecting columns using character vector

耗尽温柔 提交于 2019-12-03 14:01:57

There is an example with dplyr::select in https://cran.r-project.org/web/packages/rlang/vignettes/tidy-evaluation.html that uses:

dplyr::select(df, !!cols_to_select)

Why? Let's explore the options you mention:

Option 1

dplyr::select(df, cols_to_select)

As you say this fails if cols_to_select happens to be the name of a column in df, so this is wrong.

Option 4

cols_to_select_syms <- rlang::syms(c("b", "d"))  
dplyr::select(df, !!!cols_to_select_syms)

This looks more convoluted than the other solutions.

Options 2 and 3

dplyr::select(df, !!cols_to_select)
dplyr::select(df, !!!cols_to_select)

These two solutions provide the same results in this case. You can see the output of !!cols_to_select and !!!cols_to_select by doing:

dput(rlang::`!!`(cols_to_select)) # c("b", "d")
dput(rlang::`!!!`(cols_to_select)) # pairlist("b", "d")

The !! or UQ() operator evaluates its argument immediately in its context, and that is what you want.

The !!! or UQS() operator are used to pass multiple arguments at once to a function.

For character column names like in your example it does not matter if you give them as a single vector of length 2 (using !!) or as a list with two vectors of length one (using !!!). For more complex use cases you will need to use multiple arguments as a list: (using !!!)

a <- quos(contains("c"), dplyr::starts_with("b"))
dplyr::select(df, !!a) # does not work
dplyr::select(df, !!!a) # does work
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!