2015-06-17 7 views
8

Okay, das sollte einfach sein, aber ich suche nach einer Lösung, die so schnell wie möglich ist.Wie summiere ich die Werte von Spalten in mehreren Tabellen, wenn Tabellen unterschiedliche Längen haben?

Sagen wir, ich habe 3 Tabellen (die Anzahl der Tabellen wird viel größer sein):

tab1 <- table(c(1, 1, 1, 2, 2, 3, 3, 3)) 
tab2 <- table(c(1, 1, 4, 4, 4)) 
tab3 <- table(c(1, 1, 2, 3, 5)) 

Das ist, was wir bekommen:

> tab1 
1 2 3 
3 2 3 
> tab2 
1 4 
2 3 
> tab3 
1 2 3 5 
2 1 1 1 

Was ich auf eine schnelle Art und Weise haben wollen

1 2 3 4 5 
7 3 4 3 1 

alle also, im Grunde die Tabellen erhalten aggregiert über: so, dass es mit vielen großen Tabellen funktioniert dies. Gibt es eine elementare Funktion, die das tut, was mir fehlt? Danke für Ihre Hilfe!

+4

was ist mit Verkettung Ihrer Vektoren und Aufruf 'Tabelle' auf dem" Super "Vektor? – Cath

+0

Das würde funktionieren. Die Tabellen ('tab1',' tab2' ...) wurden jedoch bereits vorproduziert und ich möchte die Menge der Tabellen ändern, die in die Berechnung eingehen. Die ursprünglichen Vektoren, auf denen diese Tabellen basieren, sind nicht mehr verfügbar. – swolf

Antwort

12

Wir verketten (c) die tab Ausgang ‚v1‘ zu erstellen, verwenden Sie tapply die sum der Elemente durch die names dieses Objekts gruppiert zu erhalten.

v1 <- c(tab1, tab2, tab3) 
tapply(v1, names(v1), FUN=sum) 
#1 2 3 4 5 
#7 3 4 3 1 
+1

sehr schöne Lösung – Rentrop

+0

@ Floo0 Danke für die Rückmeldung – akrun

+1

Vielen Dank! 'tapply' scheint eine elegante Lösung zu sein. Und es scheint ziemlich schnell zu sein. Es übertrifft definitiv Mamoun Benghezals Lösung unten. 'rbenchmark' sagt mir, es ist ungefähr 5 mal schneller. – swolf

1

können Sie versuchen, diese

df <- rbind(as.matrix(tab1), as.matrix(tab2), as.matrix(tab3)) 
aggregate(df, by=list(row.names(df)), FUN=sum) 
    Group.1 V1 
1  1 7 
2  2 3 
3  3 4 
4  4 3 
5  5 1 
+0

Danke Mamoun, ich werde mit der 'tapply' Lösung gehen, die viel schneller zu sein scheint. – swolf

5

Sie könnten rowsum() verwenden. Die Ausgabe unterscheidet sich geringfügig von der angezeigten Ausgabe, Sie können sie jedoch nach den Berechnungen immer neu strukturieren. rowsum() ist bekannt als sehr effizient.

x <- c(tab1, tab2, tab3) 
rowsum(x, names(x)) 
# [,1] 
# 1 7 
# 2 3 
# 3 4 
# 4 3 
# 5 1 

Hier ist ein Benchmark mit dem akrun data.table Vorschlag in ebenfalls hinzugefügt.

library(microbenchmark) 
library(data.table) 

xx <- rep(x, 1e5) 

microbenchmark(
    tapply = tapply(xx, names(xx), FUN=sum), 
    rowsum = rowsum(xx, names(xx)), 
    data.table = data.table(xx, names(xx))[, sum(xx), by = V2] 
) 
# Unit: milliseconds 
#  expr  min  lq  mean median  uq  max neval 
#  tapply 150.47532 154.80200 176.22410 159.02577 204.22043 233.34346 100 
#  rowsum 41.28635 41.65162 51.85777 43.33885 45.43370 109.91777 100 
# data.table 21.39438 24.73580 35.53500 27.56778 31.93182 92.74386 100 
Verwandte Themen