2014-02-18 13 views
8

Ich habe eine große Datentabelle (aus dem Paket data.table) mit über 60 Spalten (die ersten drei entsprechen den Faktoren und die restlichen Antwortvariablen, in diesem Fall verschiedene Arten) und mehrere Reihen, die den verschiedenen Ebenen der Behandlungen und den Artenhäufigkeiten entsprechen. Eine sehr kleine Version sieht wie folgt aus:Summierung über Zeilen einer data.table für spezifische Spalten

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 

ich zuerst die mittlere Häufigkeit der einzelnen Arten über die Zeit berechnet werden soll für jede Zone Quadrates Kombination x und das ist in Ordnung:

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 

Dann möchte ich Berechnen Sie die Zeilensumme für die Spalten "Spezies", im Beispiel von Sp1 bis Sp3. Ich habe den folgenden Code ohne Erfolg versucht:

Abundance$SumAbundance <- rowSums(Abundance[ , c(4:6)]) 

erhalte ich die Fehlermeldung:

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

Wie kann ich Zeilensummen für bestimmte Spalten eines data.table berechnen?

Antwort

13

Eigentlich geben Sie Abundance[, c(4:6)], um zu sehen, was das Ergebnis ist, und es wird Ihnen klar sein, warum das nicht funktioniert hat. Es kann durch die Verwendung with = FALSE, aber die bessere Syntax (mit weniger Kopieren) ist korrigiert werden:

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

Auch ich habe nicht überprüfen, aber ich habe den Verdacht, dies wird schneller sein, da es nicht konvertieren zu matrix wie rowSums tut:

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

Hallo @eddi, das ist toll, es funktioniert. Können Sie erklären, warum die ursprüngliche Version (Abundance [, c (4: 6)]) das getan hat? –

+1

@ClaireG siehe Punkt '1.1' in der [FAQ] (http://datatable.r-forge.r-project.org/datatable-faq.pdf) – eddi

+0

@eddi, wie man umgeht, wenn einige der Werte sind NA und du willst sie in der reduzierten Version loswerden –

3

Eine Alternative (data.table) Ansatz wäre Ihre Daten in der langen Form zu speichern. Version 1.8.11 von data.table hat schnell melt und dcast Methoden

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)] 

im Langformat Arbeiten wird eine geringfügige Änderung im Denken nehmen, aber es kann klug sein effizienter Speicher am Ende (wie weniger interne Kopier werden einbezogen, und Sie beziehen sich auf ein einzelnes, nicht mehrere Elemente in jeder "by" -Gruppe.)

+0

Ich fürchte, das funktioniert nicht und ich bin mir nicht sicher, ob es sowieso der beste Weg ist, da ich 63 Arten (Variablen) in meinem tatsächlichen Datensatz habe ... –

+0

ok, nachdem ich versucht habe, auf Version 1.8.11 von data.table zu aktualisieren (sorry ...), funktionieren die Befehle, aber es ist nicht das, was ich tun möchte: Ich möchte die Art zusammenfassen, also die oben vorgeschlagenen Befehle @eddi sind der Weg für mich. –

+0

@ClaireG --Ich habe mein Beispiel geändert. Arbeiten in "langer" Form wird etwas gewöhnungsbedürftig sein. – mnel

Verwandte Themen