11

这可能是一个愚蠢的问题,但我已经阅读了 Crawley 关于数据帧的章节并搜索了互联网,但还没有能够使任何工作。

这是一个类似于我的示例数据集:

> data<-data.frame(site=c("A","A","A","A","B","B"), plant=c("buttercup","buttercup",
"buttercup","rose","buttercup","rose"), treatment=c(1,1,2,1,1,1), 
plant_numb=c(1,1,2,1,1,2), fruits=c(1,2,1,4,3,2),seeds=c(45,67,32,43,13,25))
> data
  site     plant treatment plant_numb fruits seeds
1    A buttercup         1          1      1    45
2    A buttercup         1          1      2    67
3    A buttercup         2          2      1    32
4    A      rose         1          1      4    43
5    B buttercup         1          1      3    13
6    B      rose         1          2      2    25  

我想做的是创建一个场景,只要存在独特的站点、植物和处理以及植物编号组合,就可以将“种子”和“果实”相加。理想情况下,这会导致行数减少,但会保留原始列(即我需要上面的示例看起来像这样:)

  site     plant treatment plant_numb fruits seeds
1    A buttercup         1          1      3   112
2    A buttercup         2          2      1    32
3    A      rose         1          1      4    43
4    B buttercup         1          1      3    13
5    B      rose         1          2      2    25

这个例子非常基础(我的数据集约为 5000 行),虽然在这里您只看到需要求和的两行,但需要求和的行数各不相同,范围从 1 到 ~45。

到目前为止,我已经尝试了 rowsum() 和 tapply() 的结果非常糟糕(错误告诉我这些函数对因子没有意义),所以如果你能指出我正确的方向,我将不胜感激!

非常感谢!

4

3 回答 3

11

希望下面的代码是不言自明的。它使用基本功能“聚合”,基本上这就是说对于站点、植物、处理和植物编号的每个独特组合,查看水果的总和和种子的总和。

# Load your data
data <- data.frame(site=c("A","A","A","A","B","B"), plant=c("buttercup","buttercup",
"buttercup","rose","buttercup","rose"), treatment=c(1,1,2,1,1,1), 
plant_numb=c(1,1,2,1,1,2), fruits=c(1,2,1,4,3,2),seeds=c(45,67,32,43,13,25)) 

# Summarize your data
aggregate(cbind(fruits, seeds) ~ 
      site + plant + treatment + plant_numb, 
      sum, 
      data = data)
#  site     plant treatment plant_numb fruits seeds
#1    A buttercup         1          1      3   112
#2    B buttercup         1          1      3    13
#3    A      rose         1          1      4    43
#4    B      rose         1          2      2    25
#5    A buttercup         2          2      1    32

行的顺序发生了变化(并按站点、植物等排序),但希望这不是太大的问题。

另一种方法是使用 plyr 包中的 ddply 。

library(plyr)
ddply(data, .(site, plant, treatment, plant_numb), 
      summarize, 
      fruits = sum(fruits), 
      seeds = sum(seeds))
#  site     plant treatment plant_numb fruits seeds
#1    A buttercup         1          1      3   112
#2    A buttercup         2          2      1    32
#3    A      rose         1          1      4    43
#4    B buttercup         1          1      3    13
#5    B      rose         1          2      2    25
于 2012-05-03T03:45:20.920 回答
4

为了完整起见,这是data.table@Chase建议的解决方案。对于较大的数据集,这可能是最快的方法:

library(data.table)
data.dt <- data.table(data)
setkey(data.dt, site)
data.dt[, lapply(.SD, sum), by = list(site, plant, treatment, plant_numb)]

     site     plant treatment plant_numb fruits seeds
[1,]    A buttercup         1          1      3   112
[2,]    A buttercup         2          2      1    32
[3,]    A      rose         1          1      4    43
[4,]    B buttercup         1          1      3    13
[5,]    B      rose         1          2      2    25

lapply(.SD, sum)部分总结了不属于分组集的所有列(即不在by函数中的列)

于 2012-05-03T04:33:39.350 回答
0

只是为了在很长一段时间后更新这个答案,dplyr/tidyverse解决方案将是

library(tidyverse)

data %>% 
  group_by(site, plant, treatment, plant_numb) %>% 
  summarise(fruits=sum(fruits), seeds=sum(seeds))
于 2018-12-11T23:24:45.530 回答