我正在构建一个函数,我将基于一个字符串操纵数据框架。在函数,我将建立一个列名作为从字符串并用它来操纵数据帧,这样的事情:为什么在group_by()而不是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")
我的理解是什么问题:unquoting的quosure作为参数传递给filter()
在破碎的版本中没有引用实际的列anyA。
我不明白的是为什么它在summarize()
中有效,但在filter()
中没有 - 为什么有区别?
啊,我明白了! 'quo()'把一个符号变成一个平静,'enquo()'把一个函数参数的值变成一个平静,'sym()'把一个字符串变成一个平静。所以我传递一个字符串,但把它当作符号来对待。它只出现在'summarize_my_df_works()'中,因为你可以基于函数进行总结,而不是因为它实际上正在做我所期望的。 – crazybilly