2014-12-01 26 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爲複雜的公式。