我有一个数据框,其中一列是物种的名称,第二列是丰度值。由于采样程序,一些物种出现不止一次(即,其中有多个物种,其中有物种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
提前感谢您提供的任何帮助!
答案 0 :(得分:42)
这有效:
library(plyr)
ddply(df,"x",numcolwise(sum))
单词:(1)将数据框df
拆分为"x"
列; (2)对于每个块,取每个数值列的总和; (3)将结果粘贴回单个数据框。 (dd
中的ddply
代表“将 d ata帧作为输入,返回 d ata frame”)
另一种可能更清晰的方法:
aggregate(y~x,data=df,FUN=sum)
请参阅quick/elegant way to construct mean/variance summary table了解相关(稍微复杂一点)的问题。
答案 1 :(得分:22)
简单为aggregate
:
aggregate(df['y'], by=df['x'], sum)
答案 2 :(得分:8)
时间和内存效率的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]
答案 3 :(得分:8)
dplyr
解决方案:
library(dplyr)
df %>% group_by(x) %>% summarise(y = sum(y))
答案 4 :(得分: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
答案 5 :(得分:1)
一个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)