【问题标题】:call custom functions with {{}} in dplyr在 dplyr 中使用 {{}} 调用自定义函数
【发布时间】:2021-06-11 09:04:35
【问题描述】:

我知道我们可以在dplyr 中使用{{}} 进行非标准评估,但我遇到了一个特殊情况,我不知道如何解决这个问题。假设我有两个具有相同前缀的函数,例如:

custom_mean <- function(x) {
  mean(x, na.rm = TRUE)
}

custom_sum <- function(x) {
  sum(x, na.rm = TRUE)
}

我想让用户选择在mtcars 的列上应用哪个函数(用户也可以选择)。这就是我将如何使用两个单独的功能:

library(dplyr)

apply_mean_on_mtcars <- function(colname) {
  mtcars %>% 
    select({{colname}}) %>% 
    summarise(
      "custom_{{colname}}" := custom_mean({{colname}})
    )
}

apply_sum_on_mtcars <- function(colname) {
  mtcars %>% 
    select({{colname}}) %>% 
    summarise(
      "custom_{{colname}}" := custom_sum({{colname}})
    )
}

apply_mean_on_mtcars(drat)
> custom_drat
> 1    3.596563

apply_sum_on_mtcars(drat)
> custom_drat
> 1      115.09

但我想要一个函数apply_on_mtcars(),用户可以在其中选择要应用的列和函数(即custom_meancustom_sum)。我试过了,但没有成功:

apply_on_mtcars <- function(colname, func) {
  mtcars %>% 
    select({{colname}}) %>% 
    summarise(
      "custom_{{colname}}" := "custom_{{func}}"({{colname}})
    )
}

Error: Problem with `summarise()` input `custom_drat`.
x could not find function "custom_{{func}}"
ℹ Input `custom_drat` is ``custom_{{func}}`(drat)`.

有人有解决方案吗?最后,用户调用函数时应该提供的函数是meansum,而不是custom_meancustom_sum

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我们也可以使用match.fun

    library(stringr)
    library(dplyr)
    apply_on_mtcars <- function(colname, func) {
      mtcars %>% 
        select({{colname}}) %>% 
        summarise(
          "custom_{{colname}}" := 
             match.fun(str_c("custom_", func))({{colname}})
        )
    }
    
    
    apply_on_mtcars(drat, "mean")
    #    custom_drat
    #1    3.596563
    apply_on_mtcars(drat, "sum")
    #    custom_drat
    #1      115.09
    

    【讨论】:

      【解决方案2】:

      这样怎么样:

      apply_on_mtcars <- function(colname, func=c("mean", "sum")) {
        f <- match.arg(func)
        fun <- eval(parse(text=paste0("custom_", f)))
        mtcars %>% 
          select({{colname}}) %>% 
          summarise(
            "custom_{{colname}}" := fun({{colname}})
          )
      }
      
      apply_on_mtcars(drat, "mean")
      # custom_drat
      # 1    3.596563
       
      apply_on_mtcars(drat, "sum")
      # custom_drat
      # 1      115.09
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-10
        • 2014-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多