我有一个包含超过60列的大型数据表(来自包data.table)(前三个对应于因子,其余对应于响应变量,在这种情况下是不同的种类)和几个对应于不同的行治疗水平和物种丰富度。 一个非常小的版本看起来像这样:
library(data.table)
TEST <- data.table(Time=c("0","0","0","7","7","7","12"),
Zone=c("1","1","0","1","0","0","1"),
quadrat=c(1,2,3,1,2,3,1),
Sp1=c(0,4,29,9,1,2,10),
Sp2=c(20,17,11,15,32,15,10),
Sp3=c(1,0,1,1,1,1,0))
setkey(TEST,Time)
TEST
# Time Zone quadrat Sp1 Sp2 Sp3
# 1: 0 1 1 0 20 1
# 2: 0 1 2 4 17 0
# 3: 0 0 3 29 11 1
# 4: 12 1 1 10 10 0
# 5: 7 1 1 9 15 1
# 6: 7 0 2 1 32 1
# 7: 7 0 3 2 15 1
我首先想要计算每个区域x样方组合的每个物种的平均丰度,这很好:
Abundance = TEST[ , lapply(.SD, mean), by = "Zone,quadrat"]
Abundance
# Zone quadrat Time Sp1 Sp2 Sp3
# 1: Z1 1 NA 6.333333 15.0 0.6666667
# 2: Z1 2 NA 2.500000 24.5 0.5000000
# 3: Z0 1 NA 15.500000 13.0 1.0000000
然后我想计算'种类'列的行方向,在Sp1到Sp3的示例中。我尝试了以下代码但没有成功:
Abundance$SumAbundance <- rowSums(Abundance[ , c(4:6)])
我收到错误消息:
# Error in rowSums(Abundance[, c(4:6)]) :
# 'x' must be an array of at least two dimensions
如何计算data.table
的特定列的行总和?
答案 0 :(得分:19)
实际输入Abundance[, c(4:6)]
以查看结果是什么,并且您将清楚为什么不起作用。可以使用with = FALSE
进行更正,但更好的语法(复制更少)是:
Abundance[, SumAbundance := rowSums(.SD), .SDcols = 4:6]
另外,我没有检查,但我怀疑这会更快,因为它不会转换为matrix
rowSums
:
Abundance[, SumAbundance := Reduce(`+`, .SD), .SDcol = 4:6]
答案 1 :(得分:3)
替代方法(data.table
)将以长格式存储您的数据。 data.table
版本1.8.11具有快速melt
和dcast
方法
library(reshape2)
mt <- melt(test, id=1:3,variable.name='Species')
abundance <- mt[,list(abundance = mean(value)),by=list(Zone,quadrat,Species)][,
sumAbundance := sum(abundance), by = list(Zone,quadrat)]
以长格式工作会稍微改变一下思路,但最终可能会更有效地记忆(因为内部复制将会更少,并且您在每个“by”组中引用一个而不是多个元素。 )