2014-12-01 25 views
3

,我有以下的数据帧:与列名的变量名中使用聚合

a <- c(1,1,4) 
b <- c(1,0,2) 
c <- data.frame(a=a,b=b) 
str(c) 
# a b 
#1 1 1 
#2 1 0 
#3 4 2 

我想聚集以下列方式将数据帧C:

aggregate(b~a,FUN=mean,data=c) 
# a b 
#1 1 0.5 
#2 4 2.0 

然而,我的主问题是,我将使用一个变量的列名

所以:

d <- 'a' 

如果我尝试使用这个变量d包含列名聚集,我显然会得到一个错误:

aggregate(b~d,FUN=mean,data=c) 
#Error in model.frame.default(formula = b ~ d, data = c) : variable lengths differ (found for 'd') 

这工作,但后来我得到愚蠢的列名。我想避免重命名列的额外步骤:

aggregate(c[,'b']~c[,d],FUN=mean,data=c) 
# c[, d] c[, "b"] 
#1 1  0.5 
#2 4  2.0 

如何聚合并获得正确的列名第一次尝试? (也许是没有办法做到这一点)

回答

3

你可以尝试

aggregate(c['b'], c[d], FUN=mean) 
# a b 
# 1 1 0.5 
# 2 4 2.0 

另一种选择,如果你使用的是formula方法是使用setNames

setNames(aggregate(b~get(d), FUN=mean, data=c), colnames(c)) 
# a b 
#1 1 0.5 
#2 4 2.0 
+0

我想知道为什么这会产生与我使用的不同的列名称。 – Michal 2014-12-01 19:12:52

+1

@Michal您在使用'aggregate.data.frame'时使用'formula'方法,即'aggregate.formula'您可以检查'stats ::: aggregate.formula'和'aggregate.data的源代码。框架' – akrun 2014-12-01 19:15:46

1

您可以使用cbindaggregate中设置名称。此方法还表明,您可以省略data参数。因此,如果我们使用原来的计划,你可以做

aggregate(cbind(b = c[, "b"]) ~ cbind(a = c[, "a"]), FUN = mean) 
# a b 
# 1 1 0.5 
# 2 4 2.0 
+0

这个不起作用,因为你有cbind(a = c [,“a”])。该声明中的第一个是固定的,不能被变量替代。 – Michal 2014-12-01 19:52:47

+1

好的,你可以用'get(“d”)'代替'“a”'。但可能比这更安全的替代(x,list(x = d))' – 2014-12-01 19:54:56

3

如果你没有在基础R拘泥于aggregate(...),这里是一个data.table解决方案。

library(data.table) 
setDT(c)[,list(b=mean(b)),by=d,with=TRUE] 
# a b 
# 1: 1 0.5 
# 2: 4 2.0 
0

我解决这个问题的方法是构建公式参数贴:

aggregate(formula(paste0("b ~ ", d)), data = c, FUN = mean) 

这样,您可以根据需要轻松地传递尽可能多的变量colnames为复杂的公式。