【问题标题】:Moving from deprecated summarize_ to new summarize in dplyr在 dplyr 中从弃用的 summarise_ 迁移到新的 summarise
【发布时间】:2018-09-07 20:30:26
【问题描述】:

我有一个函数可以计算基于变量VarName 的内容选择的列的分组数据库的平均值。当前函数使用dplyr::summarize_,但现在我看到它已被弃用,我想在它完全删除之前替换它。

但是,我不确定如何使用新的取消引用来实现我想要做的事情。这是我当前的代码:

means<-summarize_(group_by(dat,Grade),.dots = setNames(paste0('mean(',VarName,',na.rm=TRUE)'),'means'))

我尝试用means=mean(!!VarName, na.rm=TRUE) 替换.dots 部分,但这只是返回了VarName 中的字符串。我需要将 VarName 中的字符串评估为dat 中的列名,这样我就可以得到一个列名“means”和每个组的平均值。如何使用新的summarize 实现这一目标?

可重复性的样本数据集:

VarName<-"Things"
dat<-data.frame(students=c("a","b","c","d","e"),Grade=c(2,2,2,3,3),varA=c(41:45),Things=c(90,100,80,75,80))

谢谢!

【问题讨论】:

    标签: r dplyr summarize nse quosure


    【解决方案1】:

    将其转化为函数并泛化为任意数据、分组变量和值变量:

    library(tidyverse)
    
    means <- function(data, group, value) {
    
      group = enquo(group)
      value = enquo(value)
      value_name = paste0("mean_", value)[2]
    
      data %>% group_by(!!group) %>% 
        summarise(!!value_name := mean(!!value, na.rm=TRUE))
    }
    
    means(dat, Grade, Things)
    
      Grade mean_Things
      <dbl>       <dbl>
    1  2.00        90.0
    2  3.00        77.5
    

    如果我理解你的评论,下面的函数怎么样,它接受一个字符串作为value 参数:

    means <- function(data, group, value) {
    
      group = enquo(group)
      value_name = paste0("mean_", value)
      value = sym(value)
    
      data %>% group_by(!!group) %>% 
        summarise(!!value_name := mean(!!value, na.rm=TRUE))
    }
    
    VarName = "Things"
    
    means(dat, Grade, VarName)
    
      Grade mean_Things
      <dbl>       <dbl>
    1  2.00        90.0
    2  3.00        77.5
    

    由于函数是泛化的,您可以对任何数据框执行此操作。例如:

    means(mtcars, cyl, "mpg")
    
        cyl mean_mpg
      <dbl>    <dbl>
    1  4.00     26.7
    2  6.00     19.7
    3  8.00     15.1
    

    您可以进一步概括该功能。例如,此版本采用任意数量的分组列:

    means <- function(data, value, ...) {
    
      group = quos(...)
      value_name = paste0("mean_", value)
      value = sym(value)
    
      data %>% group_by(!!!group) %>% 
        summarise(!!value_name := mean(!!value, na.rm=TRUE))
    }
    
    VarName = "Things"
    
    means(dat, VarName, students, Grade)
    
      students Grade mean_Things
      <fct>    <dbl>       <dbl>
    1 a         2.00        90.0
    2 b         2.00       100  
    3 c         2.00        80.0
    4 d         3.00        75.0
    5 e         3.00        80.0
    

    【讨论】:

    • 谢谢。但是,我不希望它在函数中。这一切都在 Shiny 应用程序中,并且 VarName 来自 UI 端。当我尝试在我的代码中执行您在此处所做的事情时,我得到了所有NAs。我的问题是,为了使 Things 起作用,必须不加引号,但我不确定当我通过 input 得到它时,我如何才能让它不加引号......
    • 我不打算进一步概括它。恰恰相反 - 我试图在不将所有内容都放入函数的情况下做到这一点......当我这样做时它似乎不起作用。
    • 好的,现在可以使用了!万分感谢!你能解释一下enquo()sym()之间的区别吗?
    • enquo 在函数中用于将名称(如 Grade)转换为 quosure。 sym 将字符串转换为名称。我实际上不确定为什么sym(value) 可以在以后不被!! 引用而不会变成一个quosure。我并没有真正了解 tidyeval/quosure 的东西,并且发现除了最简单的应用程序之外的所有应用程序都很难使用并且令人困惑。
    【解决方案2】:

    !!as.nameas.symbol 一起使用:

    dat %>% 
        group_by(Grade) %>% 
        summarize(means = mean(!!as.name(VarName), na.rm=T))
        # or summarize(means = mean(!!as.symbol(VarName), na.rm=T))
    
    # A tibble: 2 x 2
    #  Grade means
    #  <dbl> <dbl>
    #1  2.00  90.0
    #2  3.00  77.5
    

    【讨论】:

      猜你喜欢
      • 2018-01-20
      • 2016-01-17
      • 1970-01-01
      • 2021-06-21
      • 2016-08-07
      • 1970-01-01
      • 1970-01-01
      • 2020-01-21
      • 2018-04-30
      相关资源
      最近更新 更多