代码之家  ›  专栏  ›  技术社区  ›  tjebo

函数列表:仅将附加参数应用于可以接受它的函数

r
  •  2
  • tjebo  · 技术社区  · 6 年前

    na.rm = TRUE ).

    我想添加一个不接受此参数的函数( length ). 是否可以将附加参数仅应用于可以接受它的函数?我想用 ...

    我在用 lapply ,但很高兴有任何选择,也超过了基本R。

    x <- c(1:10,NA)
    
    # working example only with functions that take the extra argument
    
    show_stats <- function(x) {
      funs <- list(mean = mean, sd = sd)
      lapply(funs, function(f) f(x, na.rm = TRUE))
    }
    show_stats(x) 
    #> $mean
    #> [1] 5.5
    #> 
    #> $sd
    #> [1] 3.02765
    
    # sadly not working, because length() only takes one argument
    show_stats <- function(x) {
      funs <- list(mean = mean, sd = sd, n = length)
      lapply(funs, function(f) f(x, na.rm = TRUE))
    }
    
    show_stats(x)
    #> Error in f(x, na.rm = TRUE): 2 arguments passed to 'length' which requires 1
    

    于2016年2月20日由 reprex package (第0.3.0版)

    3 回复  |  直到 6 年前
        1
  •  3
  •   Ronak Shah    6 年前

    我不确定这是否是最安全的方法,但你可以使用 tryCatch 其中,如果有错误,则返回 f(x) 没有任何额外的论据。

    show_stats <- function(x) {
      funs <- list(mean = mean, sd = sd, n = length)
      lapply(funs, function(f) tryCatch(f(x, na.rm = TRUE), error = function(e) f(x)))
    }
    show_stats(x) 
    
    #$mean
    #[1] 5.5
    
    #$sd
    #[1] 3.02765
    
    #$n
    #[1] 11
    
        2
  •  5
  •   G. Grothendieck    6 年前

    (一) 问题不清楚预期的产出是什么 length 但如果问题是如何删除NAs,而不管功能是否 na.rm

    show_stats2 <- function(x) {
      funs <- list(mean = mean, sd = sd, length = length)
      lapply(funs, function(f) f(na.omit(x)))
    }
    

    2个) 允许函数具有任意变化参数的另一种可能性如下。每一个函数都被定义为一个简单的公式,其中包含任何合适的参数。这使用 fn$ 从gsubfn将公式转换为函数`

    library(gsubfn)
    show_stats3 <- function(x) {
      funs <- list(mean = ~ mean(x, na.rm = TRUE), 
                   sd = ~ sd(x, na.rm = TRUE),
                   length = ~ length(x))
      fn$lapply(funs, function(f) fn$identity(f)(x))
    }
    

    三) function 但同样灵活:

    show_stats4 <- function(x) {
      funs <- list(mean = function(x) mean(x, na.rm = TRUE), 
                   sd = function(x) sd(x, na.rm = TRUE),
                   length = length)
      lapply(funs, function(f) f(x))
    }
    

    另一种变化是 Curry

    library(functional)
    show_stats5 <- function(x) {
      funs <- list(mean = Curry(mean, na.rm = TRUE), 
                   sd = Curry(sd, na.rm = TRUE),
                   length = length)
      lapply(funs, function(f) f(x))
    }
    
        3
  •  2
  •   PKumar    6 年前

    你可以试试 partial purrr

    func_factory <- function(x){
      partial(x, na.rm=T)
    }
    
    show_stats <- function(x) {
      funs <- list(mean = func_factory(mean), 
                   sd = func_factory(sd), n = length)
    
      lapply(funs, function(f) f(x))
    }
    
    show_stats(x)
    

    输出:

    > show_stats(x)
    $mean
    [1] 5.5
    
    $sd
    [1] 3.02765
    
    $n
    [1] 11
    
    >