【问题标题】:How to do lazy-evaluation of "..." function arguments in R?如何在 R 中对“...”函数参数进行惰性求值?
【发布时间】:2020-08-04 22:46:32
【问题描述】:

我想将参数传递给在函数中使用之前不会被评估的函数。举个简单的例子,如果我想将... = foo, 'bar' 传递给以下函数,而foo 是在函数中定义的,我该怎么做:

  myfunc <- function(X, ...) {    
    for (foo in seq_along(X)) {
      cat(..., '\n')
    }
  }
  myfunc(X = 1:5, foo, 'bar')

我尝试使用cat(substitute(...), '\n'),它似乎只是省略了foo

谢谢!

【问题讨论】:

  • 是的,我最初希望在函数环境中评估所有参数。您将如何使用特殊规则来命名参数?

标签: r lazy-evaluation


【解决方案1】:

1) 使用eval(substitute(...))

myfunc <- function(X, ...) {    
  for (foo in seq_along(X)) {
    eval(substitute(cat(..., "\n")))
  }
}
myfunc(X = 1:5, foo, 'bar')

给予:

1 bar 
2 bar 
3 bar 
4 bar 
5 bar 

2) defmacro 另一种方法是在 gtools 中使用defmacro 创建一个宏:

library(gtools)

myfunc2 <- defmacro(X, DOTS, expr = {
  for (foo in seq_along(X)) {
    cat(..., "\n")
  }
})
myfunc2(X = 1:5, foo, 'bar')

【讨论】:

    【解决方案2】:

    这是一种方法

    myfunc <- function(X, ...) { 
      dots <- eval(substitute(alist(...)))
      for (foo in seq_along(X)) {
        do.call("cat", c(dots, '\n'))
      }
    }
    myfunc(X = 1:5, foo, 'bar')
    # 1 bar 
    # 2 bar 
    # 3 bar 
    # 4 bar 
    # 5 bar 
    

    我们在未评估的对列表中捕获传递给... 的所有参数。然后,我们使用“do.call”将这些值注入到对cat() 的调用中,并在本地环境中进行评估。

    只要您不需要做类似的事情,这将起作用

    test <- function() {
      bar <- "bar"
      myfunc(X = 1:5, foo, bar)
    }
    test()
    #  Error in cat(foo, bar, "\n") : object 'bar' not found 
    

    【讨论】:

      猜你喜欢
      • 2017-05-12
      • 2011-02-06
      • 2016-01-18
      • 1970-01-01
      • 2019-12-09
      • 1970-01-01
      • 2012-08-15
      • 2021-01-13
      • 2019-09-03
      相关资源
      最近更新 更多