对特定列的data.table行进行求和

Cla*_*e G 11 r data.table

我有一个大数据表(来自包data.table)有超过60列(前三个对应于因子,剩下的响应变量,在这种情况下是不同的物种)和几行对应于不同的处理水平和物种丰富.一个非常小的版本看起来像这样:

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
Run Code Online (Sandbox Code Playgroud)

我首先想要计算每个Zone x quadrat组合的每个物种的平均丰度,这很好:

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  
Run Code Online (Sandbox Code Playgroud)

然后我想计算'种类'列的行方向和,在Sp1到Sp3的示例中.我尝试了以下代码但没有成功:

Abundance$SumAbundance <- rowSums(Abundance[ , c(4:6)])  
Run Code Online (Sandbox Code Playgroud)

我收到错误消息:

# Error in rowSums(Abundance[, c(4:6)]) : 
# 'x' must be an array of at least two dimensions
Run Code Online (Sandbox Code Playgroud)

如何计算特定列的行总和data.table

edd*_*ddi 23

实际上键入Abundance[, c(4:6)]以查看结果是什么,并且您将清楚为什么这不起作用.它可以通过使用来纠正with = FALSE,但更好的语法(复制更少)是:

Abundance[, SumAbundance := rowSums(.SD), .SDcols = 4:6]
Run Code Online (Sandbox Code Playgroud)

另外,我没有检查,但我怀疑这会更快,因为它不会转换matrixrowSums:

Abundance[, SumAbundance := Reduce(`+`, .SD), .SDcol = 4:6]
Run Code Online (Sandbox Code Playgroud)

  • @GauravSinghal 只需执行`rowSums(..., na.rm = T)`。我认为当有 NA 时,“Reduce”解决方案不会提供任何优势。如果没有 NA,它可以比 `rowSums` 更快,并且大致一样紧凑。 (2认同)

mne*_*nel 7

另一种 ( data.table) 方法是以长格式存储数据。版本 1.8.11data.table有快速meltdcast方法

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)]
Run Code Online (Sandbox Code Playgroud)

以长格式工作将需要稍微改变思维,但最终可能会更有效地记忆(因为将涉及较少的内部复制,并且您在每个“by”组中引用单个而不是多个元素。)