Je travaille sur la construction d'une fonction que je vais manipuler une trame de données basée sur une chaîne. Au sein de la fonction, je vais construire un nom de colonne à partir de la chaîne et l'utiliser pour manipuler la trame de données, quelque chose comme ceci:Pourquoi les quosures fonctionnent dans group_by() mais pas filter()?
library(dplyr)
orig_df <- data_frame(
id = 1:3
, amt = c(100, 200, 300)
, anyA = c(T,F,T)
, othercol = c(F,F,T)
)
summarize_my_df_broken <- function(df, my_string) {
my_column <- quo(paste0("any", my_string))
df %>%
filter(!!my_column) %>%
group_by(othercol) %>%
summarize(
n = n()
, total = sum(amt)
) %>%
# I need the original string as new column which is why I can't
# pass in just the column name
mutate(stringid = my_string)
}
summarize_my_df_works <- function(df, my_string) {
my_column <- quo(paste0("any", my_string))
df %>%
group_by(!!my_column, othercol) %>%
summarize(
n = n()
, total = sum(amt)
) %>%
mutate(stringid = my_string)
}
# throws an error:
# Argument 2 filter condition does not evaluate to a logical vector
summarize_my_df_broken(orig_df, "A")
# works just fine
summarize_my_df_works(orig_df, "A")
Je comprends ce que le problème est: unquoting le quosure comme argument pour filter()
dans la version brisée ne fait pas référence à la colonne réelle anyA. Qu'est-ce que je ne comprends pas pourquoi cela fonctionne dans summarize()
, mais pas dans filter()
- pourquoi y a-t-il une différence?
Ah, je vois! 'quo()' transforme un symbole en quosure, 'enquo()' transforme la valeur d'un argument de fonction en quosure, et 'sym()' transforme une chaîne en une quosure. Donc je passais dans une ficelle mais en la traitant comme un symbole. Il semblerait que cela fonctionne dans 'summarize_my_df_works()' parce que vous pouvez résumer en fonction d'une fonction, et non pas parce qu'elle faisait ce que j'attendais. – crazybilly