並べ替える変数名のベクトルを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 = ", "))))
ハドリーはこれをヘルプファイルで明らかにしていません。彼の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()
の使用方法に関する情報は、まだ上記のリンクにあるビネットには含まれていません(最終的には、ドラフトによると、「多様な準引用」のセクションにあります)。
新しいバージョン(まもなくリリースされる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
の引用符を外します
クオシュア精神で:
df %>% arrange(!!! rlang::syms(c("var1", "var3")))
単一変数の場合、次のようになります。
df %>% arrange(!! rlang::sym(c("var1")))
今、あなたは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
これを試して:
df %>% do(do.call(arrange_, . %>% list(.dots = vector_of_vars)))
そして実際には、これはより簡単に次のように書くことができます:
df %>% arrange_(.dots = vector_of_vars)
この時点では、ファーニーの暗黙の解決策と同じだと思います。