为什么quasure在group_by()中起作用但在filter()中不起作用? [英] Why do quosures work in group_by() but not filter()?

查看:107
本文介绍了为什么quasure在group_by()中起作用但在filter()中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个函数,该函数将基于字符串来操纵数据帧.在函数中,我将从字符串开始建立一个列名,并使用它来操纵数据框,如下所示:

I'm working on building a function that I will manipulate a data frame based on a string. Within the function, I'll build a column name as from the string and use it to manipulate the data frame, something like this:

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")

我理解问题出在哪里:在破损版本中将quosure引为filter()的参数时,没有引用实际的列anyA.

I understand what the problem is: unquoting the quosure as an argument to filter() in the broken version is not referencing the actual column anyA.

我不明白为什么它可以在summarize()中工作,而不能在filter()中工作-为什么会有区别?

What I don't understand is why it works in summarize(), but not in filter()--why is there a difference?

推荐答案

现在,您正在对字符串而不是符号名称进行定义.那不是应该被使用的方式. quo("hello")quo(hello)之间有很大的区别.如果要从字符串中输入正确的符号名称,则需要使用rlang::sym.因此,快速解决方案是

Right now you are are making quosures of strings, not symbol names. That's not how those are supposed to be used. There's a big difference between quo("hello") and quo(hello). If you want to make a proper symbol name from a string, you need to use rlang::sym. So a quick fix would be

summarize_my_df_broken <- function(df, my_string) {

  my_column <- rlang::sym(paste0("any", my_string))
  ...
}

如果您仔细观察,我想您会发现group_by/summarize实际上并没有按照您期望的方式工作(尽管您只是没有得到相同的错误消息).这两个结果不一样

If you look more closely I think you'll see the group_by/summarize isn't actually working the way you expect either (though you just don't get the same error message). These two do not produce the same results

summarize_my_df_works(orig_df, "A")
#  `paste0("any", my_string)` othercol     n total
#                        <chr>    <lgl> <int> <dbl>
# 1                       anyA    FALSE     2   300
# 2                       anyA     TRUE     1   300

orig_df  %>% 
  group_by(anyA, othercol) %>% 
  summarize(
    n = n()
    , total = sum(amt)
  )  %>%
  mutate(stringid = "A")
#    anyA othercol     n total stringid
#   <lgl>    <lgl> <int> <dbl>    <chr>
# 1 FALSE    FALSE     1   200        A
# 2  TRUE    FALSE     1   100        A
# 3  TRUE     TRUE     1   300        A

同样,问题是使用字符串而不是符号.

Again the problem is using a string instead of a symbol.

这篇关于为什么quasure在group_by()中起作用但在filter()中不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆