dplyr
の関数で文字列として変数名を使用したい。以下の例を参照してください。
df <- data.frame(
color = c("blue", "black", "blue", "blue", "black"),
value = 1:5)
filter(df, color == "blue")
完全に機能しますが、次のような文字列でcolor
を参照したいと思います。
var <- "color"
filter(df, this_probably_should_be_a_function(var) == "blue").
どうにかしてこれを実現できれば幸いであり、読みやすいdplyr
構文を使用できることを嬉しく思います。
dplyr
バージョン[0.3-0.7)(?-2017年6月)(最新のdplyr
バージョンについては、この質問に対する他の回答をご覧ください)
dplyr 0.3
現在、非標準評価(NSE、 リリース投稿 および ビネット を参照)を使用するすべてのdplyr
関数には、標準評価(SE)ツインがありますアンダースコアで終わる。これらは変数を渡すために使用できます。 filter
の場合、filter_
になります。 filter_
を使用すると、論理条件を文字列として渡すことができます。
filter_(df, "color=='blue'")
# color value
# 1 blue 1
# 2 blue 3
# 3 blue 4
論理条件を使用して文字列を構築することはもちろん簡単です
l <- paste(var, "==", "'blue'")
filter_(df, l)
新しいバージョンでは、変数を引用符で囲んで作成し、引用符を外す(UQ
または!!
)評価用
var <- quo(color)
filter(df, UQ(var) == "blue")
# color value
#1 blue 1
#2 blue 3
#3 blue 4
演算子の優先順位により、()
折り返す!!
filter(df, (!!var) == "blue")
# color value
#1 blue 1
#2 blue 3
#3 blue 4
新しいバージョンでは、||
は優先順位が高いため、
filter(df, !! var == "blue")
動作するはずです(@Moody_Mudskipperがコメントしたとおり)
以下も使用できます。
filter(df, get(var, envir=as.environment(df))=="blue")
#color value
#1 blue 1
#2 blue 3
#3 blue 4
編集:ソリューションの順序を並べ替えました
Dplyr 0.7の時点で、いくつかの点が再び変更されました。
library(dplyr)
df <- data.frame(
color = c("blue", "black", "blue", "blue", "black"),
value = 1:5)
filter(df, color == "blue")
# it was already possible to use a variable for the value
val <- 'blue'
filter(df, color == val)
# As of dplyr 0.7, new functions were introduced to simplify the situation
col_name <- quo(color) # captures the current environment
df %>% filter((!!col_name) == val)
# Remember to use enquo within a function
filter_col <- function(df, col_name, val){
col_name <- enquo(col_name) # captures the environment in which the function was called
df %>% filter((!!col_name) == val)
}
filter_col(df, color, 'blue')
より一般的なケースは dplyrプログラミングビネット で説明されています。
よく尋ねられますが、まだ簡単なサポートはありません。ただし、 この投稿 に関しては:
eval(substitute(filter(df, var == "blue"),
list(var = as.name(var))))
# color value
# 1 blue 1
# 2 blue 3
# 3 blue 4
rlang
パッケージのsym()
関数を使用してそれを行う1つの方法を次に示します。
library(dplyr)
df <- data.frame(
main_color = c("blue", "black", "blue", "blue", "black"),
secondary_color = c("red", "green", "black", "black", "red"),
value = 1:5,
stringsAsFactors=FALSE
)
filter_with_quoted_text <- function(column_string, value) {
col_name <- rlang::sym(column_string)
df1 <- df %>%
filter(UQ(col_name) == UQ(value))
df1
}
filter_with_quoted_text("main_color", "blue")
filter_with_quoted_text("secondary_color", "red")
rlang
version> = 0.4.0の新機能.data
は親データフレームを参照する方法として認識されるようになったため、文字列による参照は次のように機能します。
var <- "color"
filter(df, .data[[var]] == "blue")
変数が既にシンボルである場合、{{}}
は適切に逆参照します
例1:
var <- quo(color)
filter(df, {{var}} == "blue")
またはより現実的に
f <- function(v) {
filter(df, {{v}} == "blue")
}
f(color)