2014-10-21 11 views
18

Ich möchte übergeben arrange() {dplyr} ein Vektor von Variablennamen zu sortieren. Normalerweise gebe ich einfach die Variablen ein, die ich will, aber ich versuche eine Funktion zu machen, bei der die Sortiervariablen als Funktionsparameter eingegeben werden können.Übergeben Sie einen Vektor von Variablennamen zu ordnen() in dplyr

df <- structure(list(var1 = c(1L, 2L, 2L, 3L, 1L, 1L, 3L, 2L, 4L, 4L 
), var2 = structure(c(10L, 1L, 8L, 3L, 5L, 4L, 7L, 9L, 2L, 6L 
), .Label = c("b", "c", "f", "h", "i", "o", "s", "t", "w", "x" 
), class = "factor"), var3 = c(7L, 5L, 5L, 8L, 5L, 8L, 6L, 7L, 
    5L, 8L), var4 = structure(c(8L, 5L, 1L, 4L, 7L, 4L, 3L, 6L, 9L, 
    2L), .Label = c("b", "c", "d", "e", "f", "h", "i", "w", "y"), 
    class = "factor")), .Names = c("var1", "var2", "var3", "var4"), 
    row.names = c(NA, -10L), class = "data.frame") 

# this is the normal way to arrange df with dplyr 
df %>% arrange(var3, var4) 

# but none of these (below) work for passing a vector of variables 
vector_of_vars <- c("var3", "var4") 
df %>% arrange(vector_of_vars) 
df %>% arrange(get(vector_of_vars)) 
df %>% arrange(eval(parse(text = paste(vector_of_vars, collapse = ", ")))) 
+3

Imo, die Verwendung von%>% sollte für die Verkettung gespeichert werden, da es ziemlich hässlich ... (für einzelne Aktionen <- oder = funktioniert ganz gut ... – Kevin

Antwort

21

Hadley hat dies nicht offensichtlich in der Hilfedatei gemacht - nur in seiner NSE-Vignette. Die Versionen der Funktionen, auf die die Unterstriche folgen, verwenden die Standardauswertung, also übergeben Sie ihnen Vektoren von Strings und ähnlichem. Wenn ich Ihr Problem richtig verstehe, können Sie arrange() durch arrange_() ersetzen und es wird funktionieren.

==== === bearbeiten

Übergeben Sie den Vektor der Zeichenfolge als .dots Argument, wenn Sie es tun.

> df %>% arrange_(.dots=c("var1","var3")) 
    var1 var2 var3 var4 
1  1 i 5 i 
2  1 x 7 w 
3  1 h 8 e 
4  2 b 5 f 
5  2 t 5 b 
6  2 w 7 h 
7  3 s 6 d 
8  3 f 8 e 
9  4 c 5 y 
10 4 o 8 c 
+2

Ich dachte das auch, aber wenn Sie 'df%>% array_ (vector_of_vars)', scheint es das zweite Element zu ignorieren und sortiert nur auf das erste Element. Allerdings, wenn Sie Do 'df%>% array_ (vector_of_vars [1], vector_of_vars [2])', dann sortiert es nach beiden Werten. Ich nehme an, dass es einen eleganteren Ansatz als die zweite Methode gibt, aber ich bin nicht sicher, was es ist. – eipi10

+0

'' 'arrangieren _()' '' scheint die zweite Spalte zu ignorieren. @eipi10 Ihre Lösung würde funktionieren, aber das Problem ist, dass es eine beliebige Anzahl von Elementen geben kann s in '' 'vector_of_vars'''. – rsoren

+0

Ich behauptete nicht, dass meine zweite Methode eine gute war. Ich habe nur versucht, das Problem herauszufinden, warum der scheinbar "natürliche" Ansatz nicht funktioniert und auch eine vorübergehende, wenn auch unelegante Lösung bietet. Hoffentlich springt @Hadley ein und baut uns auf. – eipi10

3

Try this:

df %>% do(do.call(arrange_, . %>% list(.dots = vector_of_vars))) 

und tatsächlich kann dies geschrieben werden einfach als:

df %>% arrange_(.dots = vector_of_vars) 

obwohl an diesem Punkt denke ich, ist es das gleiche wie farnsy der implizierten Lösung.

+0

Dies funktionierte nicht für mich, siehe [mein Beitrag] (http://stackoverflow.com/questions/38052325). – zx8754

4

In der neuen Version (bald 0.6.0 von dplyr freigegeben werden) wir die Verwendung der

library(dplyr) 
vector_of_vars <- quos(var1, var3) 
df %>% 
    arrange(!!! vector_of_vars) 
# var1 var2 var3 var4 
#1  1 i 5 i 
#2  1 x 7 w 
#3  1 h 8 e 
#4  2 b 5 f 
#5  2 t 5 b 
#6  2 w 7 h 
#7  3 s 6 d 
#8  3 f 8 e 
#9  4 c 5 y 
#10 4 o 8 c 

quosures machen können, wenn es mehr als eine Variable ist, verwenden wir quos und für eine einzelne Variable ist es quo . Die quos ein list quotierter Variablen zurückkehren und innerhalb arrange, unquote wir die list mit !!! zur Auswertung