【问题标题】:dplyr group_by and summarize with non-standard evaluationdplyr group_by 和非标准评估总结
【发布时间】:2020-09-17 11:26:07
【问题描述】:

假设我有这个代码:

> df<-data.frame(a=c(1,1,1,2,2,2), b=c(T,T,F,F,F,T))
> df %>% group_by(a) %>% summarize(trues=sum(b), falses=sum(!b))
# A tibble: 2 x 3
      a trues falses
  <dbl> <int>  <int>
1     1     2      1
2     2     1      2

我想使用一个字符串变量来给出b(例如在一个for循环中)。我想这和this question 完全一样,但我似乎无法让它工作。

一些失败的尝试:

var <- 'b'

df %>% group_by(a) %>% summarize_(trues=sum(var), falses=sum(!var))
df %>% group_by(a) %>% summarize(trues=sum({{var}}), falses=sum(!{{var}}))
df %>% group_by(a) %>% summarize_(trues=sum({{var}}), falses=sum(!{{var}}))
foo1 <- function(df, var) {
  df %>% group_by(a) %>% summarize(trues=sum({{var}}), falses=sum(!{{var}}))
}
foo1(df, 'b')
foo2 <- function(df, var) {
  var <- enquo(var)
  df %>% group_by(a) %>% summarize(trues=sum(!!var), falses=sum(! !!var))
}
foo2(df, 'b')

也许我可以在另一个问题中使用 lazyeval 包,但我更想知道如何只使用 tidyverse。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    在这种情况下,最好使用ensym,因为我们正在传递一个字符串。此外,ensym 也适用于不带引号的参数

    foo2 <- function(df, var) {
       var <- ensym(var)
       df %>% 
             group_by(a) %>%
             summarize(trues=sum(!!var), 
                       falses=sum(! (!!var)))
      }
    foo2(df, 'b')
    # A tibble: 2 x 3
    #      a trues falses
    #* <dbl> <int>  <int>
    #1     1     2      1
    #2     2     1      2
    
    
    foo2(df, b)
    # A tibble: 2 x 3
    #      a trues falses
    #* <dbl> <int>  <int>
    #1     1     2      1
    #2     2     1      2
    

    如果传递的参数是一个对象,则在传递给函数时评估 (!!) 以避免文字评估

    foo2(df, !!var)
    # A tibble: 2 x 3
    #      a trues falses
    #* <dbl> <int>  <int>
    #1     1     2      1
    #2     2     1      2
    

    【讨论】:

    • 有效!当stackoverflow允许我(7分钟)时,我会接受。你能说说为什么其他人没有工作吗?
    • 为什么它只在函数中起作用?还有(奖励)我如何在没有函数的情况下让它工作(因为我只是在 for 循环中使用它)?
    • @dfrankow 如果你检查?enquo The defusing operators expr() and enquo() prevent the evaluation of R code. Defusing is also known as quoting, and is done in base R by quote() and substitute(). When a function argument is defused, R doesn't return its value like it normally would but it returns the R expression describing how to make the value. These defused expressions are like blueprints for computing values.
    • @dfrankow 在函数之外你可以使用quo sym 没有en
    • @dfrankow 你的意思是enquo/ensym 为那些你需要quo/sym 的人。此外,还有整洁的选择助手,即df %&gt;% group_by(a) %&gt;% summarise(across(var, ~ sum(.)))
    猜你喜欢
    • 2017-10-27
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    • 2015-03-10
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多