使用非标准评估的gather运算符

4

我想编写一个函数,它以quosure作为参数,将-添加到quosure,并将其传递给gather函数,如下所示:

library(tidyverse)
my_gather <- function(d, not.columns) {
  dg <- tidyr::gather(d, key = k, value = v, .dots = -!!!not.columns)
  dg
}

de <- my_gather(mtcars, not.columns = quos(mpg, cyl, disp))

> Error in `-`(~mpg, ~cyl, ~disp) : operator needs one or two arguments

这显然是因为我需要将每个quosure的元素都用-连接起来,而不是将整个quosure与-连接起来。但在我的工作中,很难以 quos(-mpg, -cyl, -disp) 的形式创建该quosure - 那么我该如何修改quos(mpg, cyl, disp)以添加-呢?

我想看到的结果应该和 gather(mtcars, key = k, value = v, -mpg, -cyl, -disp) 相同,其中的前3行是:

   mpg cyl disp  k   v
1 21.0   6  160 hp 110
2 21.0   6  160 hp 110
3 22.8   4  108 hp  93

这里有一个类似的问题但它没有得到解答,并且似乎没有涉及quos()而是quo()的问题。


你能详细描述一下你希望看到的结果吗? - IRTFM
@42-:请查看编辑。 - Drew Steen
2个回答

3
我们可以做到。
my_gather <- function(d, not.columns) {
  tidyr::gather(d, key = k, value = v, .dots =  -c(UQS(not.columns)))
  #or use !!! instead of UQS
  #tidyr::gather(d, key = k, value = v, .dots =  -c(!!!(not.columns)))

}
de <- my_gather(mtcars, not.columns = quos(mpg, cyl, disp))
head(de, 3)
#   mpg cyl disp  k   v
#1 21.0   6  160 hp 110
#2 21.0   6  160 hp 110
#3 22.8   4  108 hp  93

没有使用函数的输出检查

de1 <- gather(mtcars, key = k, value = v, -mpg, -cyl, -disp)
identical(de, de1)
#[1] TRUE

这与 OP 的尝试有何不同?UQS = !!!;这里的 c 不应该有任何影响。 - Konrad Rudolph
2
@KonradRudolph 是的,c是不同之处,但我喜欢把它放在大括号里面。 - akrun
好的。能解释一下吗?这非常不明显。 - Konrad Rudolph
3
@KonradRudolph 我认为这个差异可以通过比较两个命令来解释:'-'(1, 2, 3)(因为函数“-”需要一个参数来改变符号而导致错误),和'-'(c(1, 2, 3))(得到了预期的结果)。 因此,c将列名包装成一个参数。 - echasnovski

2
我可以提供“解决问题而不是回答问题”的答案。您需要一种指定已收集列的方式,其中包含有关未使用列的信息。以下是我的方法:
library(tidyverse)

negate_columns <- function(.tbl, not.columns) {
  not_columns <- colnames(select(.tbl, !!!not.columns))

  setdiff(colnames(.tbl), not_columns)
}

my_gather <- function(d, not.columns) {
  columns <- negate_columns(d, not.columns)

  tidyr::gather(d, key = k, value = v, !!!syms(columns))
}

这样做可以按预期工作:

my_gather(mtcars, not.columns = quos(mpg, cyl, disp)) %>%
    head(3)
#>    mpg cyl disp  k   v
#> 1 21.0   6  160 hp 110
#> 2 21.0   6  160 hp 110
#> 3 22.8   4  108 hp  93

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接