43

我有一个数据框,其中一列是物种的名称,第二列是丰度值。由于抽样程序,一些物种出现了不止一次(即,有不止一行包含物种 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

提前感谢您提供的任何帮助!

4

6 回答 6

54

这有效:

library(plyr)
ddply(df,"x",numcolwise(sum))

df用文字来说:(1)按列拆分数据框"x";(2) 对于每个块,取每个数值列的总和;(3) 将结果粘贴回单个数据框中。(ddinddply代表“将数据帧作为输入,返回数据帧”)

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

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

请参阅快速/优雅的方式来构建相关(稍微复杂)问题的均值/方差汇总表。

于 2012-04-16T19:12:36.583 回答
29

简单如aggregate

aggregate(df['y'], by=df['x'], sum)
于 2012-04-16T19:15:39.883 回答
13

一个dplyr解决方案:

library(dplyr)
df %>% group_by(x) %>% summarise(y = sum(y))
于 2016-01-05T13:34:22.283 回答
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]
于 2012-09-13T04:13:38.903 回答
6
> tapply(df$y, df$x, sum)
sp1 sp2 sp3 sp4 
  2   9   7   3 

如果必须是data.frame本的答案,效果很好。或者你可以强制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
于 2012-04-16T19:16:27.070 回答
2

一个 MWE 来验证一个公式是否尊重第二个变量(即这里的“Z”和“X”之外的,实际上会起作用:

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)
于 2016-01-05T13:31:04.563 回答