合并重复行

49

我有一个数据框,其中一列是物种名称,第二列是它们的数量值。由于采样过程中,某些物种可能会出现在多行中(即有多行数据中均为物种X)。我想要将这些条目合并,并对它们的数量进行求和。

例如,在给定的数据框中:

set.seed(6)
df=data.frame(
  x=c("sp1","sp2","sp3","sp3","sp4","sp2","sp3"),
  y=rpois(7,2)); df

它生成:

    x y
1 sp1 2
2 sp2 4
3 sp3 1
4 sp3 1
5 sp4 3
6 sp2 5
7 sp3 5

我想要生成以下内容:

    x y
1 sp1 2    
2 sp2 9     (5+4)
3 sp3 7     (5+1+1)
5 sp4 3

非常感谢您能提供的任何帮助!

6个回答

56
这有效:
library(plyr)
ddply(df,"x",numcolwise(sum))

用语言表述:(1)按照"x"列将数据框df拆分;(2)对于每个块,取每个数值列的和;(3)将结果合并为一个数据框。(ddply中的dd表示"将一个data frame作为输入,返回一个data frame")

另一种可能更清晰的方法:

aggregate(y~x,data=df,FUN=sum)

请参见快速 / 简洁的方式构建均值 / 方差汇总表,这是一个相关但稍微复杂一些的问题。


哎呀!这个ddply的教科书应用怎么会从我手中溜走...谢谢Ben! - jslefche
+1 应用 numcolwise 和 sum。我曾经尝试使用 transform 和 mutate 来实现这个功能。 - Brandon Bertelsen
2
据我所知,“aggregate(y~x+z,data=df,FUN=sum)”可用于保留额外的一列(这里是“z”),如果需要的话(在我的情况下需要)。如果我有错,请纠正我。 - Shadow

31

aggregate一样简单:

aggregate(df['y'], by=df['x'], sum)

14

一个 dplyr 的解决方案:

library(dplyr)
df %>% group_by(x) %>% summarise(y = sum(y))

9

使用data.table可提高时间和内存效率的解决方案

library(data.table)
DT <- as.data.table(df)
# which columns are numeric 
numeric_cols <- which(sapply(DT, is.numeric))
DT[, lapply(.SD, sum), by = x, .SDcols = numeric_cols]

或者,就您的情况而言,考虑到您知道只有1列y需要求和

DT[, list(y=sum(y)),by=x]

6
> tapply(df$y, df$x, sum)
sp1 sp2 sp3 sp4 
  2   9   7   3 

如果必须使用 data.frame,Ben的答案非常适用。或者你可以强制转换 tapply 的输出。

out <- tapply(df$y, df$x, sum)
>     data.frame(x=names(out), y=out, row.names=NULL)
    x y
1 sp1 2
2 sp2 9
3 sp3 7
4 sp4 3

2

一个用于验证公式是否符合第二个变量(即此处为“Z”,除了“X”之外)的MWE,看看其是否实际可行:

example = data.frame(X=c("x"),Z=c("a"),Y=c(1), stringsAsFactors=F)
newrow = c("y","b",1)
example <- rbind(example, newrow)
newrow = c("z","a",0.5)
example <- rbind(example, newrow)
newrow = c("x","b",1)
example <- rbind(example, newrow)
newrow = c("x","b",2)
example <- rbind(example, newrow)
newrow = c("y","b",10)
example <- rbind(example, newrow)
example$X = as.factor(example$X)
example$Z = as.factor(example$Z)
example$Y = as.numeric(example$Y)
example_agg <- aggregate(Y~X+Z,data=example,FUN=sum)

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