2015-02-08 21 views
20

Dplyr kullanarak bir iç birleştirme iki tabloyu gerçekleştirmeye çalışıyorum ve standart dışı değerlendirme kurallarına göre hızlandırıldığımı düşünüyorum. By = ("a" = "b") argümanını kullanırken, "a" ve "b" gerçek dizeler olduğunda her şey beklendiği gibi çalışır.Dplyr, = (a = b) 'ye katılıyor, burada a ve b dizeleri içeren değişkenler var mı?

library(dplyr) 
data(iris) 

inner_join(iris, iris, by=c("Sepal.Length" = "Sepal.Width")) 

Ama ben bir işlevi inner_join koyuyordum diyelim:

Error: cannot join on columns 'xname' x 'Sepal.Width': index out of bounds

Ben orada şüpheli:

library(dplyr) 
data(iris) 

myfn <- function(xname, yname) { 
    data(iris) 
    inner_join(iris, iris, by=c(xname = yname)) 
} 

myfn("Sepal.Length", "Sepal.Width") 

Bu, aşağıdaki hata döndürür Burada çalışan bir oyuncak örneği Bu işi yapmak için yapabileceğim süslü bir ifade, ötekileştirme, alıntılama ya da unquote, ama bu detaylarda birazcık karışıkım. Her iki bu değerler uygun karakter değerleri olmadıklarından

+0

Hadley bu [ "standart dışı değerlendirmeyi çağırır:

myfn <- function(byvar) { data(iris) inner_join(iris, iris, by=byvar) } 

Bu şekilde size ile istediğinizi yapabilirsiniz "] (http://adv-r.had.co.nz/Computing-on-the-language.html) (NSE) – smci

+0

" by.x "ve" by.y "yi teslim etmek için çok fazla NSE görünmüyor sütun adları farklı bir şekilde. 'By'-argümanı' c ("Sepal.Length" = "Sepal.Width") olur ve '' birleştirme '' by.x' argümanı gerçek bir R ismi olur. Aslında, onu gördüğümde NSE'nin neredeyse tam tersi. –

cevap

21

Sen

by = c("a"="b") # same as by = c(a="b") 

arasında ?inner_join belgelerinde sözdizimi önerdi

myfn <- function(xname, yname) { 
    data(iris) 
    inner_join(iris, iris, by=setNames(yname, xname)) 
} 

kullanabilirsiniz biraz yanıltıcı olduğunu. Aslında adlandırılmış bir karakter vektörü yarattınız. Değerleri, eşittir işaretinin soluna dinamik olarak ayarlamak için sağdakilerden farklıdır. Vektörlerin isimlerini dinamik olarak ayarlamak için setNames()'u kullanabilirsiniz.

+1

'setNames' kullanarak, argümanların sırasının' inner_join' içindeki orijinal kullanıma göre ters çevrildiğini unutmayın. Argümanların aynı düzenine sahip olmak için, yani ilk 'xname' sonra' yname', 'by = setNames (nm = xname, yname)' kullanabilirsiniz. – fber

2

Ben partiye geç kaldım biliyorum ama hakkında nasıl:

myfn(c("Sepal.Length"="Sepal.Width")) 
+0

Bu, BayFlick yanıtından önemli ölçüde farklı değil. –

+0

Çok benzerler. Tek fark, birden çok boyuta katıldığınız zamandır. Myfn (c ("a", "c" = "d")) 'myfn (c (" a "," c "), c (" b ", "d")), ama sanırım bir tat meselesi. –

+0

Evet. Senin noktanı görebilirim. Gerçi gereksiz tırnak kullanıyorsunuz. "Myfn (c (a =" b ", c =" d "))' ile sizinkileri arayabilir ve gözlerimin normal isimlerini kullandığı için daha net olacağını düşündüğüm daha az sayıda karakterden bahsetmezsiniz. bir vardiya anahtarına ihtiyacım var. –

İlgili konular