Ich habe die folgenden 2 Datenrahmen:
a1 <- data.frame(a = 1:5, b=letters[1:5])
a2 <- data.frame(a = 1:3, b=letters[1:3])
Ich möchte die Zeile a1 finden, die a2 nicht hat.
Gibt es eine eingebaute Funktion für diese Art von Operation?
(ps: Ich habe eine Lösung dafür geschrieben, ich bin einfach neugierig, ob jemand bereits einen besser gestalteten Code erstellt hat)
Hier ist meine Lösung:
a1 <- data.frame(a = 1:5, b=letters[1:5])
a2 <- data.frame(a = 1:3, b=letters[1:3])
rows.in.a1.that.are.not.in.a2 <- function(a1,a2)
{
a1.vec <- apply(a1, 1, paste, collapse = "")
a2.vec <- apply(a2, 1, paste, collapse = "")
a1.without.a2.rows <- a1[!a1.vec %in% a2.vec,]
return(a1.without.a2.rows)
}
rows.in.a1.that.are.not.in.a2(a1,a2)
a2 <- data.frame(a = c(1:3, 1), b = c(letters[1:3], "c"))
. Lassa1
das gleiche. Versuchen Sie nun den Vergleich. Es ist mir selbst beim Lesen der Optionen nicht klar, wie man nur gemeinsame Elemente auflistet.SQLDF
bietet eine schöne LösungUnd die Zeilen, die sich in beiden Datenrahmen befinden:
Die neue Version von
dplyr
hat eine Funktionanti_join
für genau diese Art von VergleichenUnd
semi_join
Zeilen darin zu filterna1
sind auch ina2
quelle
anti_join
undsemi_join
!In dplyr :
Grundsätzlich erhalten
setdiff(bigFrame, smallFrame)
Sie die zusätzlichen Datensätze in der ersten Tabelle.In der SQLverse wird dies als a bezeichnet
Für eine gute Beschreibung aller Join-Optionen und festgelegten Themen ist dies eine der besten Zusammenfassungen, die ich bisher zusammengestellt habe: http://www.vertabelo.com/blog/technical-articles/sql-joins
Aber zurück zu dieser Frage - hier sind die Ergebnisse für den
setdiff()
Code bei Verwendung der OP-Daten:Oder Sie erhalten sogar
anti_join(a1,a2)
die gleichen Ergebnisse.Für weitere Informationen: https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf
quelle
a1
, die nicht ina2
, wollen Sie nicht zu nutzen so etwas wiesemi_join(a1, a2, by = c('a','b'))
? In der Antwort von "Rickard" sehe ich, dass diessemi_join
vorgeschlagen wurde.setdiff()
für zwei Vektoren funktioniert: stat.ethz.ch/R-manual/R-devel/library/base/html/sets.html . Vielleicht haben Sie die Lubridate- Bibliothek nach dplyr geladen und es wird vorgeschlagen, sie als Quelle in der tabcomplete-Liste zu verwenden?Es ist sicherlich nicht effizient für diesen speziellen Zweck, aber was ich in diesen Situationen oft mache, ist, Indikatorvariablen in jeden data.frame einzufügen und dann zusammenzuführen:
Fehlende Werte in include_a1 notieren, welche Zeilen in a1 fehlen. ähnlich für a2.
Ein Problem bei Ihrer Lösung besteht darin, dass die Spaltenreihenfolgen übereinstimmen müssen. Ein weiteres Problem besteht darin, dass man sich leicht Situationen vorstellen kann, in denen die Zeilen gleich codiert sind, obwohl sie tatsächlich unterschiedlich sind. Der Vorteil der Zusammenführung besteht darin, dass Sie kostenlos alle Fehlerprüfungen erhalten, die für eine gute Lösung erforderlich sind.
quelle
included_a1
? : - /Ich habe ein Paket geschrieben ( https://github.com/alexsanjoseph/compareDF ), da ich das gleiche Problem hatte.
Ein komplizierteres Beispiel:
Das Paket verfügt außerdem über einen Befehl html_output zur schnellen Überprüfung
quelle
The two data frames have different columns!
Sie könnten das
daff
Paket verwenden (das diedaff.js
Bibliothek mit demV8
Paket umschließt ):erzeugt das folgende Differenzobjekt:
Das Diff-Format wird im Coopy-Textmarker-Diff-Format für Tabellen beschrieben und sollte ziemlich selbsterklärend sein. Die Zeilen mit
+++
in der ersten Spalte@@
sind diejenigen, die neu sinda1
und in nicht vorhanden sinda2
.Das Differenzobjekt kann verwendet werden
patch_data()
, um den Unterschied zu Dokumentationszwecken zu speichernwrite_diff()
oder um den Unterschiedrender_diff()
zu visualisieren, indem :generiert eine ordentliche HTML-Ausgabe:
quelle
Mit
diffobj
Paket:quelle
Ich habe das angepasst
merge
Funktion , um diese Funktionalität zu erhalten. Bei größeren Datenrahmen wird weniger Speicher benötigt als bei der vollständigen Zusammenführungslösung. Und ich kann mit den Namen der Schlüsselspalten spielen.Eine andere Lösung besteht darin, die Bibliothek zu verwenden
prob
.quelle
Ihre Beispieldaten enthalten keine Duplikate, aber Ihre Lösung verarbeitet sie automatisch. Dies bedeutet, dass möglicherweise einige der Antworten bei Duplikaten nicht mit den Ergebnissen Ihrer Funktion übereinstimmen.
Hier ist meine Lösung, deren Adresse genauso dupliziert wird wie Ihre. Es skaliert auch großartig!
Es benötigt data.table 1.9.8+
quelle
Vielleicht ist es zu einfach, aber ich habe diese Lösung verwendet und finde sie sehr nützlich, wenn ich einen Primärschlüssel habe, mit dem ich Datensätze vergleichen kann. Hoffe es kann helfen.
quelle
Noch eine andere Lösung basierend auf match_df in plyr. Hier ist plyrs match_df:
Wir können es ändern, um zu negieren:
Dann:
quelle
Verwenden von
subset
:quelle
Der folgende Code verwendet beide
data.table
undfastmatch
für eine höhere Geschwindigkeit.quelle