dplyr:取消选择的列

sna*_*aut 6 r dplyr tidyverse

如何取消选择...自写函数参数中给出的列.(我还需要在另一个点选择列,所以只使用-in 指定列...不能解决我的问题.)

任何解决方案都是apreciated,select-helpers,manipulating quosures或expression,......

# very simple example data
test <- data.frame(a=1:3, b=1:3, c=1:3)

# function skeleton
testfun <- function(x, ...){
  y <- select(x, ...)
  z <- select(x, -...) # does of course not work like this
  return(list(y, z))   # just as an example
}

# calling the function to select different columns
testfun(test, a)
testfun(test, a, b)
Run Code Online (Sandbox Code Playgroud)

TJ *_*ahr 6

这些最简单的解决方案是选择正列,然后比较名称以确定要删除的列,如本答案中所示.

直接处理点,

  1. 我们将在一系列quosures(quos)中捕获它们.
  2. 取消引用并拼接点以UQS进行正选择.
  3. 在内部做同样的事情,c()以便我们有一个选择的向量.
  4. 否定该向量进行否定选择.

这是(3)和(4)描述的变换.

library(dplyr)
dots <- quos(a, b)
quos(-c(UQS(dots)))
#> [[1]]
#> <quosure: frame>
#> ~-c(~a, ~b)
#> 
#> attr(,"class")
#> [1] "quosures"
Run Code Online (Sandbox Code Playgroud)

那么完整的解决方案就是

test <- data.frame(a = 1:3, b = 1:3, c = 1:3)

# function skeleton
testfun <- function(x, ...) {
  dots <- quos(...)
  y <- select(x, UQS(dots))
  z <- select(x, -c(UQS(dots)))
  return(list(y, z))   
}

testfun(test, a)
#> [[1]]
#>   a
#> 1 1
#> 2 2
#> 3 3
#> 
#> [[2]]
#>   b c
#> 1 1 1
#> 2 2 2
#> 3 3 3

testfun(test, a, b)
#> [[1]]
#>   a b
#> 1 1 1
#> 2 2 2
#> 3 3 3
#> 
#> [[2]]
#>   c
#> 1 1
#> 2 2
#> 3 3
Run Code Online (Sandbox Code Playgroud)

测试选择助手.

testfun(test, starts_with("b"), one_of("c"))
#> [[1]]
#>   b c
#> 1 1 1
#> 2 2 2
#> 3 3 3
#> 
#> [[2]]
#>   a
#> 1 1
#> 2 2
#> 3 3
Run Code Online (Sandbox Code Playgroud)