2017-03-22 6 views
0

Ich habe einige große Datensätze und probiere data.table, um sie zu kombinieren, während die gemeinsame Spalte über übereinstimmende Zeilen summiert. Ich weiß, wie [ passende Zeilen in der LHS data.table mit fusionieren, wie unten dargestellt mit Tabellen a2: LHS und a: RHSkombinieren data.tables und summieren die gemeinsame Spalte

a2 <- data.table(b= c(letters[1:5],letters[11:15]), c = as.integer(rep(100,10))) 
a <- data.table(b = letters[1:10], c = as.integer(1:10)) 
setkey(a2 ,"b") 
setkey(a , "b") 

a2 
    b c 
1: a 100 
2: b 100 
3: c 100 
4: d 100 
5: e 100 
6: k 100 
7: l 100 
8: m 100 
9: n 100 
10: o 100 

a 
    b c 
1: a 1 
2: b 2 
3: c 3 
4: d 4 
5: e 5 
6: f 6 
7: g 7 
8: h 8 
9: i 9 
10: j 10 

von den zweiten Antwort hier Merge data frames whilst summing common columns in R ich sah, wie Spalten über passende Zeilen zusammengefasst werden könnten , als solche:

setkey(a , "b") 
setkey(a2, "b") 
a2[a, `:=`(c = c + i.c)] 
a2 
    b c 
1: a 101 
2: b 102 
3: c 103 
4: d 104 
5: e 105 
6: k 100 
7: l 100 
8: m 100 
9: n 100 
10: o 100 

Allerdings versuche ich, die Zeilen zu behalten, die nicht übereinstimmen.

Alternativ könnte ich merge wie unten gezeigt verwenden, aber ich möchte eine Lücke machen eine neue Tabelle mit 4 Zeilen, bevor Sie es auf 2 Zeilen reduzieren.

c <- merge(a, a2, by = "b", all=T) 
c <- transform(c, value = rowSums(c[,2:3], na.rm=T)) 
c <- c[,c(1,4)] 

c 
    b value 
1: a 102 
2: b 104 
3: c 106 
4: d 108 
5: e 110 
6: f  6 
7: g  7 
8: h  8 
9: i  9 
10: j 10 
11: k 100 
12: l 100 
13: m 100 
14: n 100 
15: o 100 

Diese letzte Tabelle ist, was ich erreichen möchte, Vielen Dank im Voraus.

+1

Oder 'rbindlist (Liste (a, a2)) [, Summe (c), b]'? – A5C1D2H2I1M1N2O1R2T1

+0

Danke ich sehe sie beide arbeiten. Ich versuche die '[, sum ..] Syntax zu verstehen und schaue wieviel Speicher sie benutzen. – Bhail

Antwort

2

merge ist wahrscheinlich nicht sehr effizient für das Endergebnis, das Sie suchen. Da beide Ihrer data.table s die gleiche Struktur haben, würde ich rbind vorschlagen, sie zusammen zu bilden und die Summe durch ihren Schlüssel zu nehmen. Mit anderen Worten:

rbindlist(list(a, a2))[, sum(c), b] 

ich rbindlist verwendet habe, weil es in der Regel effizienter bei rbind ing data.table s (obwohl zu können, müssen setzen Sie Ihre data.table s in einem list) ist.


einige Timings auf größere Datensätze vergleichen:

library(data.table) 
library(stringi) 
set.seed(1) 
n <- 1e7; n2 <- 1e6 
x <- stri_rand_strings(n, 4) 
a2 <- data.table(b = sample(x, n2), c = sample(100, n2, TRUE)) 
a <- data.table(b = sample(x, n2), c = sample(10, n2, TRUE)) 

system.time(rbindlist(list(a, a2))[, sum(c), b]) 
# user system elapsed 
# 0.83 0.05 0.87 

system.time(merge(a2, a, by = "b", all = TRUE)[, rowSums(.SD, na.rm = TRUE), b]) # Get some coffee 
# user system elapsed 
# 159.58 0.48 162.95 

## Do we have all the rows we expect to have? 
length(unique(c(a$b, a2$b))) 
# [1] 1782166 

nrow(rbindlist(list(a, a2))[, sum(c), b]) 
# [1] 1782166 
+0

'rbind (a, a2)' wird an 'rbind.data.table' gesendet, denke ich, also keine Notwendigkeit, eine Liste zu erstellen/pass auf rbindlist, denke ich. – Frank

+0

'rbindlist (Liste (a, a2)) [, Summe (c), b]' – Bhail

+0

In 'rbindlist (Liste (a, a2)) [, Summe (c), b]' Ich rate hier '[, sum (c), b] 'ist eine data.table-Eigenschaft und ihre Weitergabe' sum() 'durch Spalten, die als ID oder Schlüssel zugewiesen sind, ein weiteres Merkmal von data.table. Aber ich bin immer noch etwas unsicher, dass ich in der Lage sein werde, '[' 'intuitiv zu verwenden, es sei denn, ich betrachte das Beispiel. Ich würde mich über die Hilfe der Sprache der data.table hier freuen. – Bhail

Verwandte Themen