【问题标题】:Expand function with arbitrary number of arguments使用任意数量的参数展开函数
【发布时间】:2019-11-10 09:39:34
【问题描述】:

假设我有如下函数foobar

bar <- function(a, b) {
    # Some operations with a and b ...
} 

foo <- function(...) {
    test <- baz(bar(...))
    return (test)
}   

是否有函数bazbar 调用作为字符串返回,并扩展了... 中指定的参数?所以,当我这样做时

> foo(a = 1, b = 2)

我希望得到类似的东西

[1] "bar(a = 1, b = 2)"

这可以通过在... 中粘贴参数来完成,但我更喜欢一些更干净、更漂亮的内置解决方案。


所以,不如说bar 是一些预构建的函数,在我的例子中是knitr::kable。我将如何获得相同的结果?为此,knitr::kable 与 bar 具有相同的输入,即ab。函数 foo 现在看起来像这样

foo <- function(...) {
    test <- baz(knitr::kable(...))
    return (test)
}  

所以我想打电话

> foo(a = 1, b = 2)

返回类似的东西

[1] "kable(a = 1, b = 2)"

【问题讨论】:

    标签: r


    【解决方案1】:

    如果foo 在问题中给出,并且它和bar 都不会被修改,而是你想定义一个函数baz,当从foo 调用时,如图所示返回语言对象bar(a = 1, b = 1) 然后:

    baz <- function(...) {
      mc <- substitute(list(...), parent.frame())
      mc[[1]] <- match.call()[-1][[1]][[1]]
      mc
    }
    
    # foo is copied from question without change
    foo <- function(...) {
        test <- baz(bar(...))
        return (test)
    }   
    
    foo(a = 1, b = 2)
    ## bar(a = 1, b = 2)
    

    第二个例子,上面的baz 没有改变

    # foo copied from question without change -- this is 2nd foo definition there
    foo <- function(...) {
        test <- baz(knitr::kable(...))
        return (test)
    }
    
    foo(a = 1, b = 2)
    ## knitr::kable(a = 1, b = 2)
    

    【讨论】:

      【解决方案2】:

      您可以将match.calldeparse 一起使用

      bar <- function(a, b) {
         deparse(match.call())
      } 
      
      foo <- function(...) {
          test <- bar(...)
          return (test)
      }   
      
      foo(a = 1, b = 2)
      #[1] "bar(a = 1, b = 2)"
      

      【讨论】:

      • 不错!对于一些预先构建的bar,这将如何完成? (见我更新的问题)
      • @itslwg 我明白了......如果被调用的函数使用match.call 与其他函数包装在一起我猜是不够的。
      猜你喜欢
      • 1970-01-01
      • 2013-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-26
      • 2017-12-18
      • 1970-01-01
      相关资源
      最近更新 更多