Как выполнить ленивую оценку аргументов функции "..." в R? - PullRequest
0 голосов
/ 05 августа 2020

Я хочу передать аргументы функции, которые не подлежат оценке, пока они не будут использованы в функции. В качестве тривиального примера, как бы я мог go сказать, если бы я хотел передать ... = foo, 'bar' следующей функции, в то время как foo определяется внутри функции:

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

Я пробовал использовать cat(substitute(...), '\n') , который, кажется, просто опускает foo.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 05 августа 2020

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 Другой подход - создать макрос с использованием defmacro в gtools:

library(gtools)

myfunc2 <- defmacro(X, DOTS, expr = {
  for (foo in seq_along(X)) {
    cat(..., "\n")
  }
})
myfunc2(X = 1:5, foo, 'bar')
1 голос
/ 05 августа 2020

Вот один из способов:

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 
...