2014-10-21 22 views
18

Chcę przekazać arrange() {dplyr} wektor nazw zmiennych do sortowania. Zazwyczaj po prostu wpisuję zmienne, które chcę, ale próbuję utworzyć funkcję, w której zmienne sortujące mogą być wprowadzane jako parametr funkcji.Przekaż wektor nazw zmiennych do rozmieszczenia() w 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, użycie%>% powinno zostać zapisane łańcuchowym, gdyż jest to dość brzydki ... (dla pojedynczych działań <- lub = działa dobrze ... – Kevin

Odpowiedz

21

Hadley nie dał tego oczywiste w pliku pomocy - tylko w jego winiety NSE. Wersje funkcji, po których następują podkreślenia, używają standardowej oceny, więc przekazujesz im wektory ciągów i tym podobne.

Jeśli dobrze rozumiem Twój problem, możesz po prostu zamienić arrange() na arrange_() i będzie działać.

==== edit ===

Przepuścić wektor ciąg jako .dots argumentu kiedy to zrobić.

> 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

Też tak myślałem, ale jeśli zrobisz 'df%>% aranżacja_ (wektor_z_vars)', to zignoruje drugi element i sortuje tylko na pierwszym elemencie. wykonaj "df%>% aranżacja_ (wektor_z_vars [1], wektor_z_vars [2])", a następnie sortuje obie wartości.Myślę, że istnieje bardziej eleganckie podejście niż druga metoda, ale nie jestem pewien co to jest. – eipi10

+0

'' 'arrange _() '' 'zdaje się ignorować drugą kolumnę. @ eipi10 twoje rozwiązanie by działało, ale problemem jest to, że może istnieć dowolna liczba elementów s w '' 'vector_of_vv''''. – rsoren

+0

Nie twierdziłem, że moja druga metoda była dobra. Próbowałem tylko ograniczyć problem ustalenia, dlaczego pozornie "naturalne" podejście nie działa, a także zapewnia tymczasowe, jeśli nieeleganckie, rozwiązanie. Mam nadzieję, że @Hadley wskoczy i podbuduje nas. – eipi10

3

Spróbuj tego:

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

i faktycznie może to być napisane po prostu jako:

df %>% arrange_(.dots = vector_of_vars) 

choć w tym momencie myślę, że jest taka sama jak sugeruje rozwiązania farnsy użytkownika.

+0

To nie działa dla mnie, zobacz [mój post] (http://stackoverflow.com/questions/38052325). – zx8754

4

W nowej wersji (wkrótce ma zostać wydany 0.6.0 z dplyr) możemy skorzystać z quosures

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 

Gdy istnieje więcej niż jedna zmienna, używamy quos i dla pojedynczej zmiennej jest quo . quos zwróci list cytowanej zmiennych i wewnątrz arrange, mamy cytatu z list korzystając !!! dla oceny

Powiązane problemy