2016-12-21 4 views
6

Ich kann ein Duplikat ab sofort nicht finden.multiplizieren Sie zwei data.tables, behalten Sie alle Möglichkeiten

Mein Problem ist folgendes:

Ich habe zwei data.tables. Eins mit zwei Spalten (featurea, count), ein weiteres mit drei Spalten (featureb, featurec, count). Ich möchte multiplizieren (?), Damit ich ein neues data.table mit allen Möglichkeiten habe. Der Trick ist, dass diese Funktionen nicht übereinstimmen, so dass merge Lösungen nicht den Trick machen können.

MRE wie folgt:

# two columns 
DT1 <- data.table(featurea =c("type1","type2"), count = c(2,3)) 

#  featurea count 
#1: type1  2 
#2: type2  3 

#three columns 
DT2 <- data.table(origin =c("house","park","park"), color =c("red","blue","red"),count =c(2,1,2)) 

# origin color count 
#1: house red  2 
#2: park blue  1 
#3: park red  2 

Mein erwartetes Ergebnis, in diesem Fall ist ein data.table wie folgt:

> DT3 
    origin color featurea total 
1: house red type1  4 
2: house red type2  6 
3: park blue type1  2 
4: park blue type2  3 
5: park red type1  4 
6: park red type2  6 
+1

Würde 'DT2 [(featurea = DT1 [[ "featurea"]], count = zählen * DT1 [[“ Graf "]]), durch =. (Herkunft, Farbe)]' ausreichend effizient sein? – Roland

+1

@Roland scheint so, und das klingt die beste Antwort, also sollten Sie es als solche posten – Tensibai

Antwort

6

Dieser Weg sei. Zuerst erweiterte ich die Zeilen in DT2 mit expandRows() im splitstackshape Paket. Jede Zeile wird zweimal wiederholt, seit ich count = 2, count.is.col = FALSE angegeben habe. Dann kümmerte ich mich um die Multiplikation und erstellte eine neue Spalte namens total. Zur gleichen Zeit habe ich eine neue Spalte für featurea erstellt. Schließlich ließ ich count fallen.

library(data.table) 
library(splitstackshape) 

expandRows(DT2, count = nrow(DT1), count.is.col = FALSE)[, 
    `:=` (total = count * DT1[, count], featurea = DT1[, featurea])][, count := NULL] 

EDIT

Wenn Sie ein anderes Paket nicht hinzufügen möchten, können Sie Davids Idee in seinem Kommentar versuchen.

DT2[rep(1:.N, nrow(DT1))][, 
    `:=`(total = count * DT1$count, featurea = DT1$featurea, count = NULL)][] 



# origin color total featurea 
#1: house red  4 type1 
#2: house red  6 type2 
#3: park blue  2 type1 
#4: park blue  3 type2 
#5: park red  4 type1 
#6: park red  6 type2 
+0

@DavidArenburg Ja, ich stimme Ihnen zu. Wenn das OP ein detaillierteres Beispiel liefert, muss diese Idee überarbeitet werden. 'nrow (DT1)' ist eine gute Idee. – jazzurro

+0

@jazzurro Was wäre für ein gründlicheres Beispiel erforderlich? Mein Datensatz ist viel größer als dieser und hat nicht die gleichen Spaltennamen. Ich habe immer noch geupdated, obwohl – erasmortg

+0

@erasmortg Ich meinte nicht, dass ich den ganzen Datensatz benötigen würde. Entschuldigung für die Verwirrung. – jazzurro

0

Mit dplyr Lösung

library(dplyr) 
library(data.table) 

DT1 <- data.table(featurea =c("type1","type2"), count = c(2,3)) 
DT2 <- data.table(origin =c("house","park","park"), color =c("red","blue","red"),count =c(2,1,2)) 

eine Dummy-Spalte erstellen, um innere Verknüpfung auf (für mich seine key):

inner_join(DT1 %>% mutate(key=1), 
      DT2 %>% mutate(key=1), by="key") %>% 
mutate(total=count.x*count.y) %>% 
select(origin, color, featurea, total) %>% 
arrange(origin, color) 
8

Bitte größere Daten testen auf, ich bin nicht sicher wie optimiert das ist:

DT2[, .(featurea = DT1[["featurea"]], 
     count = count * DT1[["count"]]), by = .(origin, color)] 
# origin color featurea count 
#1: house red type1  4 
#2: house red type2  6 
#3: park blue type1  2 
#4: park blue type2  3 
#5: park red type1  4 
#6: park red type2  6 

Es könnte effizienter sein, es um zu wechseln, wenn DT1 weniger Gruppen hat.

DT1[, c(DT2[, .(origin, color)], 
     .(count = count * DT2[["count"]])), by = featurea] 
# featurea origin color count 
#1: type1 house red  4 
#2: type1 park blue  2 
#3: type1 park red  4 
#4: type2 house red  6 
#5: type2 park blue  3 
#6: type2 park red  6 
Verwandte Themen