Dplyr beitreten auf durch=(a = b), wo a und b sind Variablen mit strings?
Ich versuche, führen Sie eine inner join zwei Tabellen mit dplyr, und ich glaube, ich bin immer ausgelöst durch nicht-standard-Bewertung Regeln. Bei der Verwendung der durch=("a" = "b") - argument, funktioniert alles wie erwartet, wenn "a" und "b" sind die tatsächlichen Zeichenfolgen. Hier ist ein Spielzeug-Beispiel, das funktioniert:
library(dplyr)
data(iris)
inner_join(iris, iris, by=c("Sepal.Length" = "Sepal.Width"))
Aber sagen wir, ich war putting inner_join in einer Funktion:
library(dplyr)
data(iris)
myfn <- function(xname, yname) {
data(iris)
inner_join(iris, iris, by=c(xname = yname))
}
myfn("Sepal.Length", "Sepal.Width")
Dieser gibt die folgende Fehlermeldung zurück:
Error: cannot join on columns 'xname' x 'Sepal.Width': index out of bounds
Ich vermute, es wird einige Phantasie-Ausdruck, deparsing, zitieren, oder unquoting, dass ich tun konnte, um diese Arbeit zu machen, aber ich bin ein bisschen trübe auf diese details.
- Hadley nennt dies "nicht-standard-Auswertung" (NSE)
- Scheint nicht so viel NSE wie die Bereitstellung der "durch.x" und "durch.y" - Spalte mit den Namen in einer anderen Art und Weise. Die
by
-argument wirdc("Sepal.Length" = "Sepal.Width")
und was wäre also dieby.x
argumentmerge
zu einem echten R-Namen. In der Tat, es ist fast das Gegenteil von NSE als ich es sehen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie
Den vorgeschlagenen syntax in der
?inner_join
Dokumentation vonist etwas irreführend, da beide diese Werte sind nicht das richtige Zeichen Werte. Sie sind tatsächlich erstellt eine benannte Zeichen-Vektor. Dynamisch setzen Sie die Werte auf der linken Seite der Gleichheitszeichen ist Verschieden von denen auf der rechten Seite. Sie können
setNames()
um die Namen der vector dynamisch.setNames
die Reihenfolge der Argumente ist Umgekehrt mit Bezug auf die ursprüngliche Verwendung ininner_join
. Die gleiche Reihenfolge der Argumente, D. H. zuerstxname
dannyname
könnten Sieby=setNames(nm=xname, yname)
.Ich weiß, ich bin spät zur party, aber wie wäre es mit:
Diese Weise können Sie machen, was du willst:
myfn(c("a" = "b", "c" = "d"))
alsmyfn(c("a", "c"), c("b", "d"))
, aber es ist eine Frage des Geschmacks, denke ich.myfn(c(a = "b", c = "d"))
, und in meinen Augen wäre das sogar noch deutlicher, da es das übliche Eintragung der Namen, nicht zu erwähnen, weniger Zeichen, die eine shift-Taste.Stand ich vor einer fast identischen Herausforderung, da @Peter, aber musste passieren mehrere verschiedene Sätze von
by =
join-Parameter gleichzeitig. Ich entschied mich für die Verwendung dermap()
Funktion aus der tidyverse Paketpurrr
.Dies ist die Teilmenge der tidyverse, die ich verwendet.
Erste, die ich angepasst
myfn
zu verwendenmap()
für den Fall gepostet von Peter. 42 Kommentar und Felipe Gerard die Antwort klar gemacht, dass dieby
argument nehmen kann, eine benannte Vektor.map()
benötigt eine Liste, über die iteriert werden.Fand ich, dass ich nicht brauchen
quo_name()
/!!
im Gebäude die Funktion.Dann, ich angepasst, die Funktion zu nutzen, die eine Liste von
by
Parameter. Für jedeby_i
imby_grps
wir erweitern konntex
undy
zum hinzufügen benannter Werte, auf denen beitreten.Ich mag MrFlick Antwort und fber den Nachtrag, aber ich bevorzuge
structure
. Für michsetNames
fühlt sich wie etwas am Ende eines Rohres, nicht als on-the-fly-Konstruktor. Auf einer anderen Anmerkung, beidesetNames
undstructure
ermöglichen die Verwendung von Variablen in den Funktionsaufruf.Eine benannte Vektor-argument würde Probleme hier:
Könnte man lösen, dass, obwohl, indem Sie mit
setNames
oderstructure
im Funktionsaufruf.