Je veux utiliser des noms de variables comme chaînes dans les fonctions de dplyr
. Voir l'exemple ci-dessous:
df <- data.frame(
color = c("blue", "black", "blue", "blue", "black"),
value = 1:5)
filter(df, color == "blue")
Cela fonctionne parfaitement, mais je voudrais faire référence à color
par chaîne, quelque chose comme ceci:
var <- "color"
filter(df, this_probably_should_be_a_function(var) == "blue").
Je serais heureux de le faire par tous les moyens et très heureux d'utiliser la syntaxe dplyr
facile à lire.
dplyr
[0,3 - 0,7) (? - juin 2017) (Pour les versions dplyr
plus récentes, veuillez voir les autres réponses à cette question)
À partir du dplyr 0.3
chaque dplyr
fonction utilisant une évaluation non standard (NSE, voir release post et vignette ) a un jumeau d'évaluation standard (SE) se terminant par un trait de soulignement. Ceux-ci peuvent être utilisés pour transmettre des variables. Pour filter
ce sera filter_
. En utilisant filter_
vous pouvez passer la condition logique sous forme de chaîne.
filter_(df, "color=='blue'")
# color value
# 1 blue 1
# 2 blue 3
# 3 blue 4
Construire la chaîne avec la condition logique est bien sûr simple
l <- paste(var, "==", "'blue'")
filter_(df, l)
Dans les versions plus récentes, nous pouvons utiliser, nous pouvons créer les variables telles que citées, puis annuler la citation (UQ
ou !!
) pour évaluation
var <- quo(color)
filter(df, UQ(var) == "blue")
# color value
#1 blue 1
#2 blue 3
#3 blue 4
En raison de la priorité de l'opérateur, nous pouvons avoir besoin de ()
pour boucler !!
filter(df, (!!var) == "blue")
# color value
#1 blue 1
#2 blue 3
#3 blue 4
Avec la nouvelle version, ||
ont une priorité plus élevée, donc
filter(df, !! var == "blue")
devrait fonctionner (comme l'a commenté @Moody_Mudskipper)
Nous pouvons également utiliser:
filter(df, get(var, envir=as.environment(df))=="blue")
#color value
#1 blue 1
#2 blue 3
#3 blue 4
EDIT: Réorganisé l'ordre des solutions
Depuis dplyr 0.7, certaines choses ont encore changé.
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')
Des cas plus généraux sont expliqués dans la vignette de programmation dplyr .
Souvent demandé, mais toujours pas de soutien facile afaik. Cependant, en ce qui concerne cette publication :
eval(substitute(filter(df, var == "blue"),
list(var = as.name(var))))
# color value
# 1 blue 1
# 2 blue 3
# 3 blue 4
Voici une façon de le faire en utilisant la fonction sym()
dans le package rlang
:
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
est maintenant reconnu comme un moyen de faire référence au bloc de données parent, donc la référence par chaîne fonctionne comme suit:
var <- "color"
filter(df, .data[[var]] == "blue")
Si la variable est déjà un symbole, alors {{}}
le déréférencera correctement
exemple 1:
var <- quo(color)
filter(df, {{var}} == "blue")
ou plus réaliste
f <- function(v) {
filter(df, {{v}} == "blue")
}
f(color)