web-dev-qa-db-ja.com

変数名のベクトルをdplyrの配列()に渡します

並べ替える変数名のベクトルをarrange() {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 = ", "))))
35
rsoren

ハドリーはこれをヘルプファイルで明らかにしていません。彼のNSEビネットでのみです。アンダースコアが後に続く関数のバージョンは標準の評価を使用するため、文字列のベクトルなどを渡します。

問題を正しく理解できれば、arrange()arrange_()に置き換えるだけで機能します。

具体的には、文字列のベクトルを_.dots_引数として渡します。

_> 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
_

========== 2018年3月更新==============

ここで示したように、dplyrで標準評価版を使用することは非推奨と見なされます。新しい方法については、 Hadleyのプログラミングビネット を参照してください。基本的に、_!!_を使用して1つの変数の引用符を外すか、_!!!_を使用して、arrange()内の変数のベクトルの引用符を外します。

それらの列を渡すときに、それらが裸の場合、1つの変数の場合はquo()を使用し、ベクトルの場合はquos()を使用してそれらを引用します。引用符は使用しないでください。 Akrunの回答をご覧ください。

列が既に文字列である場合は、単一の列の場合はrlang::sym()を、ベクトルの場合はrlang::syms()を使用して名前を付けます。クリストスの答えを見てください。単一の列に対してas.name()を使用することもできます。残念ながら、これを書いている時点では、rlang::sym()の使用方法に関する情報は、まだ上記のリンクにあるビネットには含まれていません(最終的には、ドラフトによると、「多様な準引用」のセクションにあります)。

33
farnsy

新しいバージョン(まもなくリリースされる0.6.0 of dplyr)では、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

複数の変数がある場合はquosを使用し、単一の変数の場合はquoです。 quosは、引用符で囲まれた変数のlistを返し、arrange内で、評価のために!!!を使用してlistの引用符を外します

17
akrun

クオシュア精神で:

df %>% arrange(!!! rlang::syms(c("var1", "var3")))

単一変数の場合、次のようになります。

df %>% arrange(!! rlang::sym(c("var1")))
15
Christos

今、あなたはdplyr::arrange_at()を使うことができると思います。

library(dplyr)

### original
head(iris)
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1         3.5          1.4         0.2  setosa
# 2          4.9         3.0          1.4         0.2  setosa
# 3          4.7         3.2          1.3         0.2  setosa
# 4          4.6         3.1          1.5         0.2  setosa
# 5          5.0         3.6          1.4         0.2  setosa
# 6          5.4         3.9          1.7         0.4  setosa

### arranged
iris %>% 
  arrange_at(c("Sepal.Length", "Sepal.Width")) %>% 
  head()
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          4.3         3.0          1.1         0.1  setosa
# 2          4.4         2.9          1.4         0.2  setosa
# 3          4.4         3.0          1.3         0.2  setosa
# 4          4.4         3.2          1.3         0.2  setosa
# 5          4.5         2.3          1.3         0.3  setosa
# 6          4.6         3.1          1.5         0.2  setosa
5
Cecilia Lee

これを試して:

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

そして実際には、これはより簡単に次のように書くことができます:

df %>% arrange_(.dots = vector_of_vars)

この時点では、ファーニーの暗黙の解決策と同じだと思います。

3
G. Grothendieck