我有一个大约有40列的数据框(df),我希望使用4列的总和来聚合。在我想要求和的4之外,第1列中的每个唯一值对应于其余列中的相同值,并且我希望将所有列保留在聚合数据框中。有没有什么办法可以指定by = list()部分中的列而不必显式地键入它们?例如,如果我知道我想要对列"字段"第1-36列。我试过了
aggregate(df$field, by = list(df[,1:36]), FUN = sum)
但它会抛出一个错误,因为它不是一个名字列表。我也试过了
aggregate(df$field, by = list(names(df)[1:36]), FUN = sum)
虽然这并没有给出错误,但它给了我一个聚合,我的df名称作为独特的观察结果。
或者我错过了一种简单的说法"使用数据框的其余部分聚合这四列?"
由于
这是一个示例数据框:
A B C D Sum
1 A B C D 1
2 A B C D 2
3 A B C D 3
4 E F 1 R 4
5 E F 1 R 5
在我聚合后,我希望它看起来像:
A B C D Sum
1 A B C D 6
2 E F 1 R 9
我知道我可以这样做,如果我在" by"中明确说明x $ A,x $ B,x $ C,x $ D.汇总语句的一部分,但在我的实际数据框中,这将需要明确键入大约40个字段名称。
答案 0 :(得分:4)
您正在询问如何汇总多个变量的总和,并按剩余变量分组。我会先将多个变量组合起来,然后使用(在我看来)aggregate
函数更方便的公式接口进行聚合。例如,考虑根据剩余变量(Petal.Width和Species)在虹膜数据集中聚合Sepal.Length,Sepal.Width和Petal.Length的总和:
agg <- iris
cols <- c("Sepal.Length", "Sepal.Width", "Petal.Length")
agg$sum <- rowSums(agg[,cols])
agg <- agg[,!names(agg) %in% cols]
aggregate(sum~., data=agg, FUN=sum)
# Petal.Width Species sum
# 1 0.1 setosa 47.8
# 2 0.2 setosa 284.1
# 3 0.3 setosa 68.1
# 4 0.4 setosa 74.6
# 5 0.5 setosa 10.1
# 6 0.6 setosa 10.1
# 7 1.0 versicolor 79.9
# 8 1.1 versicolor 34.3
# 9 1.2 versicolor 63.8
# 10 1.3 versicolor 166.5
# 11 1.4 versicolor 96.7
# 12 1.5 versicolor 136.5
# 13 1.6 versicolor 42.0
# 14 1.7 versicolor 14.7
# 15 1.8 versicolor 13.9
# 16 1.4 virginica 14.3
# 17 1.5 virginica 27.4
# 18 1.6 virginica 16.0
# 19 1.7 virginica 11.9
# 20 1.8 virginica 162.2
# 21 1.9 virginica 71.7
# 22 2.0 virginica 91.3
# 23 2.1 virginica 94.4
# 24 2.2 virginica 48.3
# 25 2.3 virginica 125.6
# 26 2.4 virginica 44.4
# 27 2.5 virginica 48.2
答案 1 :(得分:3)
使用@josilber提到的示例数据,这将是使用dplyr()
实现所需输出的另一种选择,这对于大型数据集更有效
library('dplyr')
out = agg %>%
regroup(lapply(names(select(agg, -sum)), as.symbol)) %>%
summarise_each(funs(sum))
Source: local data frame [27 x 3]
Groups: Species
# Species Petal.Width sum
#1 setosa 0.1 47.8
#2 setosa 0.2 284.1
#3 setosa 0.3 68.1
#4 setosa 0.4 74.6
#5 setosa 0.5 10.1
#6 setosa 0.6 10.1
#7 versicolor 1.0 79.9
#8 versicolor 1.1 34.3
#9 versicolor 1.2 63.8
#10 versicolor 1.3 166.5
#.. ... ... ...
使用data.table
library('data.table')
out = setDT(agg)[, list(sum = sum(sum)), by= names(agg[,!"sum", with=FALSE])]
# Species Petal.Width sum
#1: setosa 0.2 284.1
#2: setosa 0.4 74.6
#3: setosa 0.3 68.1
#4: setosa 0.1 47.8
#5: setosa 0.5 10.1
#6: setosa 0.6 10.1
#7: versicolor 1.4 96.7
#8: versicolor 1.5 136.5
#9: versicolor 1.3 166.5
#10:versicolor 1.6 42.0
# ...
答案 2 :(得分:2)
使用data.frame方法(aggregate.data.frame
),如下所示:
aggregate(df["field"], by = df[1:36], FUN = sum)
或使用公式方法(aggregate.formula
),如下所示:
nms <- c("field", names(df)[1:36])
aggregate(field ~., df, sum)
就问题末尾的示例数据而言:
Lines <- " A B C D Sum
1 A B C D 1
2 A B C D 2
3 A B C D 3
4 E F 1 R 4
5 E F 1 R 5"
df <- read.table(text = Lines, header = TRUE)
# data.frame method
aggregate(df["Sum"], df[1:4], sum)
# data.frame method - alternative
aggregate(df[5], df[-5], sum)
# formula method
aggregate(Sum ~., df, sum)
答案 3 :(得分:0)
这将是dplyr的当前答案:
library('dplyr')
mytb<-read.table(text="
A B C D Sum
1 A B C D 1
2 A B C D 2
3 A B C D 3
4 E F 1 R 4
5 E F 1 R 5", header=T, stringsAsFactors=F)
mytb %>%
group_by_at(names(select(mytb, -"Sum") ) ) %>%
summarise_all(.funs=sum)