2017-09-26 24 views
2

Vielen Dank für Ihre Hilfe.Vergleichen Sie in R Vektoren unterschiedlicher Länge, um Werte zu vergleichen und zu ersetzen

Ich habe zwei Datenrahmen. Die Datenrahmen sind unterschiedlich lang. Einer ist ein Datensatz, der oft Fehler enthält. Ein anderer ist eine Reihe von Korrekturen. Ich versuche mit diesen beiden Datensätzen zwei Dinge gleichzeitig zu machen. Zuerst möchte ich drei Spalten von df1 mit drei Spalten in df2 vergleichen. Dies bedeutet, dass Sie die erste Datenzeile in df1 lesen und sehen, ob diese drei Variablen mit einer der Zeilen in df2 für diese drei Variablen übereinstimmen, und dann weiter zur Zeile 2 und so weiter. Wenn für alle drei Variablen eine Übereinstimmung in einer Zeile gefunden wird, ersetzen Sie den Wert in einer der Spalten in df1 durch eine Ersetzung in df2. Ich habe ein Beispiel unten eingefügt.

df1 <- data.frame("FIRM" = c("A", "A", "B", "B", "C", "C"), "LOCATION" = c("N", "S", "N", "S", "N", "S"), "NAME" = c("Apple", "Blooberry", "Cucumber", "Date", "Egplant", "Fig")) 
df2 <- data.frame("FIRM" = c("A", "C"), "LOCATION" = c("S", "N"), "NAME" = c("Blooberry", "Egplant"), "NEW_NAME" = c("Blueberry", "Eggplant")) 
df1[] <- lapply(df1, as.character) 
df2[] <- lapply(df2, as.character) 

Wenn es eine Zeile in df1 ist, die gegen die "Firma" entspricht, "Location" und "NAME" in df2, dann würde Ich mag die "NAME" in df1 mit "NEW_NAME" in df2 ersetzen, so dass "Blooberry" und "Egplant" zu "Blueberry" und "Aubergine" wechseln.

Ich kann die endgültige Ersatz tun * mit:

df1$NAME[match(df2$NAME, df1$NAME)] <- df2$NEW_NAME[match(df1$NAME[match(df2$NAME, df1$NAME)], df2$NAME)] 

Aber dies schließt nicht die Einschränkung der drei Spiele. Außerdem scheint mein Code mit den verschachtelten Match-Funktionen unnötig komplex zu sein. Ich denke, ich könnte diese Aufgabe erfüllen, indem ich df2 unterteilen und eine for Schleife verwenden, um Zeilen eins nach dem anderen anzupassen, aber ich würde denken, dass es eine bessere vektorisierte Methode gibt.

* Ich bin mir bewusst, dass innerhalb der Klammern von df2$NEW_NAME[] die Funktion beide Elemente in dieser Spalte aufruft, aber ich versuche zu verallgemeinern.

+0

By the way, ich habe nur durch Einfügen der drei Spalten zusammen in beiden Datenrahmen und Anpassung der einzelnen Spalte in der Vergangenheit um dies tatsächlich bekommen, aber ich würde wirklich eine Lösung für das Problem, das oben finden möchte. – trijamms

+1

Wenn der Kern Ihrer Frage ist, wie Sie in mehreren Spalten übereinstimmen, wurde dies auf dieser Website zuvor gefragt: https://stackoverflow.com/q/6880450/3093387. Sie könnten nur die Interaktion der relevanten Variablen anpassen. – josliber

+1

@Frank Danke. Normalerweise mache ich das, wenn ich Daten importiere, habe aber nicht gemerkt, dass man das im 'data.frame()' Befehl machen kann. – trijamms

Antwort

2

ein Betrachten all.xmerge (d.h. LEFT JOIN in SQL sprechen) mit einer ifelse bedingten Vergleich BEZEICHNUNG und NEW_NAME.

Unten, transform ermöglicht die gleiche Zeile Spaltenzuweisung und die Klammersequenz am Ende hält die ersten drei Spalten.

mdf <- transform(merge(df1,df2,all.x=TRUE),NAME=ifelse(is.na(NEW_NAME),NAME,NEW_NAME))[1:3] 
mdf 
# FIRM LOCATION  NAME 
# 1 A  N  Apple 
# 2 A  S Blueberry 
# 3 B  N Cucumber 
# 4 B  S  Date 
# 5 C  N Eggplant 
# 6 C  S  Fig 
+3

Anstelle von '1: 3' Ich würde 'Namen (df1)' am Ende machen. – Frank

+0

Danke, das ist besser lesbar als meine obige Zusammenführung. – trijamms

+0

Es hat mich ein bisschen mehr von der Untersuchung Ihrer Antwort benötigt, um zu sehen, dass es tatsächlich alles getan hat, was ich gefragt habe. Ich habe noch nie eine SQL-Datenbank benutzt, so dass ich mit den Feinheiten von Datenbank-Joins nicht vertraut bin und nicht erkannt habe, dass 'merge()' das tatsächlich tut.So scheint es, dass die Merge-Funktion selbst das Matching für alle gleichnamigen Spalten alleine durchführt! Das ist eine Offenbarung für mich. Vielen Dank! – trijamms

Verwandte Themen