2014-02-18 27 views
8

我有一個大的數據表(從包data.table)有超過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的特定列行總和?

回答

13

實際上輸入Abundance[, c(4:6)]來查看結果是什麼,它會清楚地告訴你爲什麼這樣做不起作用。它可以通過使用with = FALSE予以糾正,但更好的語法(以較少的複製)是:

Abundance[, SumAbundance := rowSums(.SD), .SDcols = 4:6] 

此外,我沒有檢查,但我懷疑這會更快,因爲它不會轉換爲matrixrowSums做:

Abundance[, SumAbundance := Reduce(`+`, .SD), .SDcol = 4:6] 
+0

嗨@eddi,這很好用。你能解釋爲什麼原始版本(Abundance [,c(4:6)])做到了嗎? –

+1

@ClaireG參見[FAQ](http://datatable.r-forge.r-project.org/datatable-faq.pdf)中的點'1.1' – eddi

+0

@eddi,如果某些值爲NA,你想擺脫他們在減少版本 –

3

的替代(data.table)的方式將存儲在長表數據。的data.table版本1.8.11具有快速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)] 

長格式的合作將採取的思維略有變化,但它可能最終會被更高效的內存明智的(因爲較少的內部複製將參與,並且您引用的是每個「by」組中的單個非多個元素。)

+0

恐怕這不起作用,我不知道這是最好的方式,因爲我在我的實際數據集中有63種(變量)... –

+0

好吧,在努力更新到data.table版本1.8.11後(對不起...),這些命令可以工作,但這不是我想要做的事情:我想總結物種的意思,所以上面提到的命令@eddi是我的方式。 –

+0

@ClaireG - 我改變了我的例子。以「長」形式工作將需要一些習慣。 – mnel