Ich habe eine Liste mit vielen data.frames, die ich zusammenführen möchte. Das Problem hierbei ist, dass sich jeder data.frame in Bezug auf die Anzahl der Zeilen und Spalten unterscheidet, aber alle die Schlüsselvariablen gemeinsam haben (die ich aufgerufen habe "var1"
und "var2"
im folgenden Code). Wenn die data.frames in Bezug auf Spalten identisch wären , könnte ich nur rbind
, für welche plyrs rbind.fill die Arbeit erledigen würde, aber das ist bei diesen Daten nicht der Fall.
Da der merge
Befehl nur für 2 data.frames funktioniert, habe ich mich für Ideen an das Internet gewandt. Ich habe dieses von hier bekommen , das in R 2.7.2 perfekt funktioniert hat, was ich damals hatte:
merge.rec <- function(.list, ...){
if(length(.list)==1) return(.list[[1]])
Recall(c(list(merge(.list[[1]], .list[[2]], ...)), .list[-(1:2)]), ...)
}
Und ich würde die Funktion so nennen:
df <- merge.rec(my.list, by.x = c("var1", "var2"),
by.y = c("var1", "var2"), all = T, suffixes=c("", ""))
In jeder R-Version nach 2.7.2, einschließlich 2.11 und 2.12, schlägt dieser Code jedoch mit dem folgenden Fehler fehl:
Error in match.names(clabs, names(xi)) :
names do not match previous names
(Übrigens sehe ich andere Verweise auf diesen Fehler an anderer Stelle ohne Lösung).
Gibt es eine Möglichkeit, dies zu lösen?
map_dfr()
odermap_dfc()
dfs = [df1, df2, df3]
dannreduce(pandas.merge, dfs)
.Reduzieren macht das ziemlich einfach:
Hier ist ein vollständiges Beispiel mit einigen Scheindaten:
Und hier ist ein Beispiel, in dem diese Daten zum Replizieren verwendet werden
my.list
:Hinweis: Es sieht so aus, als wäre dies wohl ein Fehler
merge
. Das Problem ist, dass nicht überprüft wird, ob das Hinzufügen der Suffixe (um überlappende nicht übereinstimmende Namen zu behandeln) sie tatsächlich eindeutig macht. An einem bestimmten Punkt verwendet es[.data.frame
die tutmake.unique
, die Namen, so dass dierbind
zum Scheitern verurteilt.Die einfachste Möglichkeit zur Behebung besteht darin, das Umbenennen des Felds für doppelte Felder (von denen es hier viele gibt) nicht zu belassen
merge
. Z.B:Das
merge
/Reduce
wird dann gut funktionieren.quelle
empty <- data.frame(x=numeric(0),a=numeric(0); L3 <- c(empty,empty,list.of.data.frames,empty,empty,empty)
und es sind einige seltsame Dinge passiert, die ich noch nicht herausgefunden habe.Sie können dies mit
merge_all
imreshape
Paket tun . Sie können Parameter anmerge
das...
Argument übergebenHier finden Sie eine hervorragende Ressource zu verschiedenen Methoden zum Zusammenführen von Datenrahmen .
quelle
Sie können dazu die Rekursion verwenden. Ich habe Folgendes nicht überprüft, aber es sollte Ihnen die richtige Idee geben:
quelle
Ich werde das Datenbeispiel von @PaulRougieux wiederverwenden
Hier ist eine kurze und süße Lösung mit
purrr
undtidyr
quelle
Die Funktion
eat
meines Pakets safejoin hat eine solche Funktion. Wenn Sie ihm eine Liste von data.frames als zweite Eingabe geben, werden sie rekursiv mit der ersten Eingabe verknüpft.Ausleihen und Erweitern der Daten der akzeptierten Antwort:
Wir müssen nicht alle Spalten übernehmen, wir können ausgewählte Helfer von tidyselect verwenden und auswählen (da wir von
.x
allen.x
Spalten ausgehen, werden diese beibehalten):oder entfernen Sie bestimmte:
Wenn die Liste benannt ist, werden die Namen als Präfixe verwendet:
Wenn es Spaltenkonflikte gibt,
.conflict
können Sie diese mit dem Argument lösen, indem Sie beispielsweise den ersten / zweiten nehmen, hinzufügen, zusammenführen oder verschachteln.zuerst behalten:
zuletzt halten:
hinzufügen:
verschmelzen:
Nest:
NA
Werte können durch das.fill
Argument ersetzt werden.Standardmäßig ist es erweitert,
left_join
aber alle dplyr-Verknüpfungen werden durch das.mode
Argument unterstützt, Fuzzy- Verknüpfungen werden auch durch dasmatch_fun
Argument (es wird um das Paket gewickeltfuzzyjoin
) oder durch Angabe einer Formel wie z. B.~ X("var1") > Y("var2") & X("var3") < Y("var4")
desby
Arguments unterstützt.quelle
Ich hatte eine Liste von Datenrahmen ohne gemeinsame ID-Spalte.
Ich hatte fehlende Daten auf vielen dfs. Es gab Nullwerte. Die Datenrahmen wurden unter Verwendung der Tabellenfunktion erzeugt. Das Reduzieren, Zusammenführen, rbind, rbind.fill und dergleichen konnte mir nicht helfen, mein Ziel zu erreichen. Mein Ziel war es, einen verständlichen zusammengeführten Datenrahmen zu erstellen, der unabhängig von den fehlenden Daten und der gemeinsamen ID-Spalte ist.
Daher habe ich die folgende Funktion gemacht. Vielleicht kann diese Funktion jemandem helfen.
es folgt der Funktion
Beispiel ausführen
quelle
Wenn Sie eine Liste mit dfs haben und eine Spalte die "ID" enthält, in einigen Listen jedoch einige IDs fehlen, können Sie diese Version von Reduce / Merge verwenden, um mehrere Dfs mit fehlenden Zeilen-IDs oder Beschriftungen zu verknüpfen:
quelle
Hier ist ein generischer Wrapper, mit dem eine Binärfunktion in eine Funktion mit mehreren Parametern konvertiert werden kann. Der Vorteil dieser Lösung ist, dass sie sehr allgemein gehalten ist und auf alle Binärfunktionen angewendet werden kann. Sie müssen es nur einmal tun und können es dann überall anwenden.
Um die Idee zu demonstrieren, verwende ich eine einfache Rekursion, um sie zu implementieren. Es kann natürlich auf elegantere Weise implementiert werden, was von der guten Unterstützung von R für das funktionale Paradigma profitiert.
Dann können Sie einfach alle Binärfunktionen damit umschließen und mit Positionsparametern (normalerweise data.frames) in den ersten Klammern und benannten Parametern in den zweiten Klammern (wie
by =
odersuffix =
) aufrufen . Wenn keine benannten Parameter vorhanden sind, lassen Sie die zweiten Klammern leer.quelle