2012-05-03 5 views
11

Das ist wahrscheinlich eine dumme Frage, aber ich habe Crawleys Kapitel über Datenframes gelesen und das Internet durchforstet und konnte noch nichts machen.Zeilen auf Basis bestimmter Faktorkombinationen zusammenfassen

Hier ist ein Beispieldatensatz ähnlich wie ich:

> 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 

Was ich ein Szenario tun möchte, ist in den „Samen“ und „Früchte“ werden, wenn einzigartiger Ort & Pflanze & Behandlung & plant_numb Kombinationen summierten existieren. Ideal gelegen in einer Reduktion der Zeilen führt, würde dies aber eine Erhaltung der ursprünglichen Spalten (dh ich das obige Beispiel muß wie folgt aussehen :)

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 

Dieses Beispiel ist ziemlich einfach (mein Dataset ~ 5000 Zeilen), und obwohl hier nur zwei Zeilen angezeigt werden, die summiert werden müssen, variieren die Anzahl der Zeilen, die summiert werden müssen, und reichen von 1 bis ~ 45.

Ich habe rowsum() und tapply() mit ziemlich düsteren Ergebnissen bisher versucht (die Fehler sagen mir, dass diese Funktionen für Faktoren nicht sinnvoll sind), also wenn Sie mir sogar in die richtige Richtung zeigen könnten, ich Ich würde es sehr zu schätzen wissen!

Vielen Dank!

+0

Blick auf die 'plyr' und' data.table' Tag. Viele Fragen befassen sich hauptsächlich damit. Viel Glück! – Chase

+0

Siehe auch http://4dpiecharts.com/2011/12/16/a-quick-primer-on-split-apply-combine-problems/ –

Antwort

11

Hoffentlich ist der folgende Code ziemlich selbsterklärend. Es verwendet die Basisfunktion "Aggregat" und im Grunde genommen sagt dies für jede einzigartige Kombination von Standort, Pflanze, Behandlung und Pflanzenanzahl die Summe der Früchte und die Summe der Samen.

# 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 

Die Reihenfolge der Zeilen ändert (und es nach Standort sortiert, Pflanze, ...), aber hoffentlich ist, dass nicht zu viel von einer Besorgnis.

Eine alternative Möglichkeit wäre, ddply aus dem plyr-Paket zu verwenden.

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 
+0

Awesome - Ich habe gerade mit Aggregat gespielt, nachdem ich die Frage gestellt habe, aber Sie Hab mich mächtig mitgenommen. Danke für Ihre Hilfe. Noch eine Frage: Wenn ich den Code einfüge, wie Sie es gezeigt haben, bekomme ich den Fehler "Fehler in as.data.frame.default (x): kann Klasse" Formel "nicht in einen data.frame zwingen" . Irgendwelche Ideen, damit es funktioniert? – user1371443

+0

Beides leider. Ich erhalte dieselbe Fehlermeldung sowohl für das Beispiel als auch für meine tatsächlichen Datensätze (ohne Leerzeichen):> aggregate (cbind (früchte, samen) ~ website + anlage + treatment + anlagennummer, summe, daten = daten) Fehler in as .data.frame.default (x): kann Klasse "Formel" nicht in einen data.frame zwingen – user1371443

+0

Die Plyr-Lösung sollte immer noch funktionieren, würde ich raten. Aber es klingt, als hättest du keine Formelversion von Aggregat. Welche Version von R verwendest du? Ich denke Aggregat erlaubt Formeleingabe seit 2.11 – Dason

4

Für Vollständigkeit, hier ist die data.table Lösung, wie @Chase vorgeschlagen. Für größere Datenmengen wird dies wahrscheinlich die schnellste Methode sein:

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 

Der lapply(.SD, sum) Teil fasst alle Spalten, die nicht Teil der Gruppierungsmenge sind (. Dh Spalten nicht in der by Funktion)