【问题标题】:Error when using dplyr {{ }} with aggregate inside a function将 dplyr {{ }} 与函数内的聚合一起使用时出错
【发布时间】:2021-12-28 02:12:23
【问题描述】:

我正在尝试通过使用 dplyrs {{ }} 表示法在函数内使用聚合来选择要聚合的列。

filter <- function(df, level) {
 df <- aggregate(.~ {{level}}, data=df, FUN=sum) 
 return(df)
}

但是我得到了错误

Error in model.frame.default(formula = cbind(phylum, '12K1B.txt', '12K2B.txt',  :  
variable lengths differ (found for '{{ level }}')

我已经仔细检查了我的数据,没有丢失或 NA 值,当我在函数之外运行它时,一切都按预期工作,所以我不确定是什么导致了错误。

【问题讨论】:

  • 不是我的强项,但如果 rlang 的 {{}}aggregate 的公式界面中工作,我会感到惊讶。如果您使用的是 tidyverse,请使用 tidyverse 并使用 dplyr::group_by 逻辑而不是 aggregate

标签: r function dplyr


【解决方案1】:

{{ }}tidyverse 语法,只能在 tidyverse 动词中使用。

如果我们想实现这样的目标

aggregate(. ~ Species, data = iris, sum)
     Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa        250.3       171.4         73.1        12.3
2 versicolor        296.8       138.5        213.0        66.3
3  virginica        329.4       148.7        277.6       101.3

我们可以动态创建公式,像这样操作文本

aggregate_var <- function(df, level) {
  level <- deparse(substitute(level))
  aggregate(formula(paste(". ~", level)), data=df, FUN=sum) 
}

aggregate_var(iris, Species)
     Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa        250.3       171.4         73.1        12.3
2 versicolor        296.8       138.5        213.0        66.3
3  virginica        329.4       148.7        277.6       101.3

顺便说一句-filter 是一个流行的函数名称,也许更详细的描述会很有用。另请注意,此处不需要显式的return 语句和对df 的赋值。

【讨论】:

    【解决方案2】:

    您可以使用get 来实现此目的。

    funn <- function(df, level){
      df <- aggregate(.~ get(level), data=df, FUN=sum) 
      return(df)
    }
    funn(iris, "Species")
    
      get(level) Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    1     setosa        250.3       171.4         73.1        12.3      50
    2 versicolor        296.8       138.5        213.0        66.3     100
    3  virginica        329.4       148.7        277.6       101.3     150
    

    【讨论】:

      【解决方案3】:

      为了补充已经提供的其他答案,如果您想使用{{,dplyr 方式是:

      my_fun <- function(df, level) {
        df |>
          group_by({{ level }}) |>
          summarize(across(everything(), sum))
      }
      
      my_fun(iris, Species)
      # A tibble: 3 x 5
        Species    Sepal.Length Sepal.Width Petal.Length Petal.Width
        <fct>             <dbl>       <dbl>        <dbl>       <dbl>
      1 setosa             250.        171.         73.1        12.3
      2 versicolor         297.        138.        213          66.3
      3 virginica          329.        149.        278.        101. 
      

      【讨论】:

        猜你喜欢
        • 2012-09-18
        • 2017-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多