在dplyr的summarise中使用可变列名

4
我发现这个问题已经被问过,但没有得到正确的答案。R使用变量列名在dplyr中的summarise函数中 我想计算两列均值之间的差异,但列名应由变量提供...到目前为止,我只找到了as.name 函数将列名提供为文本,但这在这里不起作用...
对于固定的列名,它可以工作。
x <- c('a','b')
df <- group_by(data.frame(a=c(1,2,3,4), b=c(2,3,4,5), c=c(1,1,2,2)), c)
df %>% summarise(mean(a) - mean(b))

使用可变列,它不能工作。
df %>% summarise(mean(x[1]) - mean(x[2]))
df %>% summarise(mean(as.name(x[1])) - mean(as.name(x[2])))

由于这个问题已经在3年前提出,并且dplyr正在良好地发展,我想知道现在是否有答案。


x 是两个列名,因此是两个字符串。 - drmariod
4
你可以使用 getdf %>% summarise(mean(get(x[1])) - mean(get(x[2])))。(说明:这段代码是使用R语言中的dplyr包对数据进行汇总统计,其中get()函数用于获取对象名称所对应的值。该代码计算了数据框df中第一个变量列和第二个变量列的均值差。) - moodymudskipper
哇,这帮了大忙!随意将其发布为答案!为什么没有文档记录这个?我以为 as.name 可以工作的。 - drmariod
2个回答

9
您可以使用base :: get :
df %>% summarise(mean(get(x[1])) - mean(get(x[2])))

# # A tibble: 2 x 2
#        c `mean(a) - mean(b)`
#    <dbl>               <dbl>
# 1     1                  -1
# 2     2                  -1

get 默认会在当前环境中搜索。

正如错误信息所说,mean 期望一个逻辑或数值对象,而 as.name 返回一个名称:

class(as.name("a")) # [1] "name"

你也可以评估你的名称,这也是可行的:
df %>% summarise(mean(eval(as.name(x[1]))) - mean(eval(as.name(x[2]))))
# # A tibble: 2 x 2
#       c `mean(eval(as.name(x[1]))) - mean(eval(as.name(x[2])))`
#   <dbl>                                                   <dbl>
# 1     1                                                      -1
# 2     2                                                      -1

1
这不是对你问题的直接回答,但可能对阅读你帖子的其他人有用: 直接使用可变列可能更容易,例如:
df %>% summarise(someName = mean(.[[1]]) - mean(.[[2]]))
############ which is the same as ############
df %>% summarise(someName = mean(.[,1,drop=T]) - mean(.[,2,drop=T]))

请注意,使用drop=T是因为当仅使用单个方括号时,结果会保留类别(在这种情况下,class(.) = data.frame),而这不是我们想要的(列必须以向量形式提供给summarise函数)。

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