2016-04-19 13 views
1

I 4 Datenrahmen in einer Liste L haben, wie unten:Union von Datenrahmen in R

L[[1]]: 

V1 V2 
B C 
A B 
Z B 

L[[2]]: 

V1 V2 
B D 
A B 
Z B 

L[[3]]: 

V1 V2 
Z Y 
X Z 
N Z 

L[[4]]: 

V1 V2 
Z J 
X Z 
N Z 

Dieser Graph von kommen mit dem Kopf C, D, Y und J. Offensichtlich, C und D aus dem gleichen Graphen, so ist Y und J. Wie kann ich C mit D und Y mit J verschmelzen gegeben diese Datenframes ist in einer Liste L?

Was ich denke ist, die Liste und den paarweisen Vergleich zu iterieren. Wenn sich dfx mit dfy überschneidet. Kann jemand mit dem R-Code helfen?

Edit: Was ich denke, ist wie folgt: Erhalten erstes Element, zu vergleichen, an zweiter Stelle zu, wenn in Ordnung, verschmolzen und auf das erste Element speichern, um das zweite Element zu entfernen, bis zuletzt zum nächsten Elemente bewegen. Wiederholen Sie den Vorgang, bis das verbleibende Element nicht entfernt wurde. Damit besteht die Liste aus verbleibenden Elementen, die zusammengeführt wurden. Wer weiß, wie man das im Code implementiert? Ausgang erwartet:

L[[1]]: 

V1 V2 
B C 
B D 
A B 
Z B 

L[[2]]: 

V1 V2 
Z Y 
Z J 
X Z 
N Z 
+0

Was ist die erwartete Ausgabe? – akrun

+0

Ich erwarte Liste der zusammengeführten. Bei dem Beispiel, das ich angegeben habe, wird es eine Liste mit 2 Elementen geben, die von C und D zusammengeführt werden und die andere wird von D und Y zusammengeführt. – Bharata

+0

Vielleicht 'Reduce (function (...) merge (...), by = "V1"), Liste (mget (paste0 ("df", 1: 4)))) – akrun

Antwort

0

Könnte dies für Sie zu einer Lösung ein Ansatz sein?

# create list of data.frames 
ld <- list(
    data.frame(V1 = c("B","A","Z"), V2 = c("C","B","B")), 
    data.frame(V1 = c("B","A","Z"), V2 = c("D","B","B")), 
    data.frame(V1 = c("Z","X","N"), V2 = c("Y","Z","Z")), 
    data.frame(V1 = c("Z","X","N"), V2 = c("J","Z","Z")) 
) 
# suggested solution 
union_ld <- data.table::rbindlist(ld) 
unique(union_ld) 

Ergebnisse:

V1 V2 
1: B C 
2: A B 
3: Z B 
4: B D 
5: Z Y 
6: X Z 
7: N Z 
8: Z J 

Update 1

Schnell Hack: zwei Datenrahmen in einer Liste, wie durch die OP angefordert. Gemäß dem Kommentar von OP spielt die Reihenfolge der Zeilen innerhalb jedes Ergebnisdatenrahmens keine Rolle.

list(
    unique(data.table::rbindlist(ld[1:2])), 
    unique(data.table::rbindlist(ld[3:4])) 
) 

ergibt:

[[1]] 
    V1 V2 
1: B C 
2: A B 
3: Z B 
4: B D 

[[2]] 
    V1 V2 
1: Z Y 
2: X Z 
3: N Z 
4: Z J 

Die vorgeschlagene Lösung, die die ersten beiden Datenrahmen in der Liste in einen Datenrahmen kombiniert, entfernt die doppelten Zeilen. Dies wird für die letzten zwei Datenrahmen in der Liste wiederholt. Dann werden die resultierenden Datenrahmen erneut zu einer Liste kombiniert.

Update 2

Diese Lösung verwendet rbindlist von Paket data.table. Wenn Sie dies nicht mögen, kann das Ergebnis wie diese

library(data.table) 
list(
    setDF(unique(rbindlist(ld[1:2]))), 
    setDF(unique(rbindlist(ld[3:4]))) 
) 

Update 3

als „reinen“ Datenrahmen zurückgegeben wird nach OP Kommentar mehr Datenrahmen, die in mehrere kombiniert werden müssen, Gruppen.

# set up a list of vectors of numbers of data.frames to combine 
dfs_to_combine <- list(c(1:2), c(3:4)) 
dfs_to_combine 

[[1]] 
[1] 1 2 

[[2]] 
[1] 3 4 

# now, combine data.frames as specified 
library(data.table) 
lapply(dfs_to_combine, function(x) setDF(unique(rbindlist(ld[x])))) 

[[1]] 
    V1 V2 
1 B C 
2 A B 
3 Z B 
4 B D 

[[2]] 
    V1 V2 
1 Z Y 
2 X Z 
3 N Z 
4 Z J 

Dies ist nur, um Ihr erstes Beispiel zu reproduzieren. Wenn Sie kombinieren möchten, ändern Sie die Zahlen, z. B.

dfs_to_combine <- list(c(1), c(2, 4), c(3)) 
+0

Das Ergebnis sollte eine Liste mit 2 Elementen haben, wie ich oben gepostet habe. – Bharata

+0

@Bharata Ist die Reihenfolge der Ergebnisse relevant? – Uwe

+0

Nein, die Reihenfolge ist unbedenklich. – Bharata