Использование "..." и "копия" - PullRequest
19 голосов
/ 15 июля 2011

В документации sapply и replicate есть предупреждение относительно использования ...

Теперь я могу принять это как таковое, но хотел бы понять, что за этим стоит.Итак, я создал этот небольшой надуманный пример:

innerfunction<-function(x, extrapar1=0, extrapar2=extrapar1)
{
    cat("x:", x, ", xp1:", extrapar1, ", xp2:", extrapar2, "\n")
}

middlefunction<-function(x,...)
{
    innerfunction(x,...)
}

outerfunction<-function(x, ...)
{
    cat("Run middle function:\n")
    replicate(2, middlefunction(x,...))
    cat("Run inner function:\n")
    replicate(2, innerfunction(x,...))
}

outerfunction(1,2,3)
outerfunction(1,extrapar1=2,3)
outerfunction(1,extrapar1=2,extrapar2=3)

Возможно, я сделал что-то явно ужасное неправильно, но я нахожу результат этого довольно огорчительным.Может кто-нибудь объяснить мне, почему во всех вышеперечисленных вызовах outerfunction я получаю такой вывод:

Run middle function:
x: 1 , xp1: 0 , xp2: 0 
x: 1 , xp1: 0 , xp2: 0 
Run inner function:
x: 1 , xp1: 0 , xp2: 0 
x: 1 , xp1: 0 , xp2: 0

Как я уже сказал: документы, кажется, предупреждают об этом, но я не вижупочему это так.

Ответы [ 4 ]

12 голосов
/ 15 июля 2011

?replicate в разделе «Примеры» прямо говорит нам, что то, что вы пытаетесь сделать, не работает и не будет работать. В Note разделе ?replicate мы имеем:

     If ‘expr’ is a function call, be aware of assumptions about where
     it is evaluated, and in particular what ‘...’ might refer to.  You
     can pass additional named arguments to a function call as
     additional named arguments to ‘replicate’: see ‘Examples’.

И если мы посмотрим на Примеры, мы увидим:

 ## use of replicate() with parameters:
 foo <- function(x=1, y=2) c(x,y)
 # does not work: bar <- function(n, ...) replicate(n, foo(...))
 bar <- function(n, x) replicate(n, foo(x=x))
 bar(5, x=3)

Мое чтение документов заключается в том, что они гораздо больше, чем предупреждают вас об использовании ... в replicate() вызовах; они явно документируют, что это не работает. Большая часть обсуждения в этом файле справки относится к ... аргументу других функций, необязательно к replicate().

6 голосов
/ 15 июля 2011

Если вы посмотрите на код для replicate:

> replicate
function (n, expr, simplify = TRUE) 
sapply(integer(n), eval.parent(substitute(function(...) expr)), 
    simplify = simplify)
<environment: namespace:base>

Вы увидите, что функция оценивается в родительском кадре, где ... из вызывающей функции больше не существует.*

1 голос
/ 27 апреля 2015

Существует способ сделать это:

# Simple function:
ff <- function(a,b) print(a+b)

# This will NOT work:
testf <- function(...) {
  replicate(expr = ff(...), n = 5)
}
testf(45,56) # argument "b" is missing, with no default

# This will:
testf <- function(...) {
  args <- as.list(substitute(list(...)))[-1L]
  replicate(expr = do.call(ff, args), n = 5)
}
testf(45,56) # 101
0 голосов
/ 07 марта 2018

Альтернативный способ сделать это:

g <- function(x, y) x + y

f <- function(a = 1, ...) {
    arg_list <- list(...)
    replicate(n = 3, expr = do.call(g, args = arg_list))
}

f(x = 1, y = 2)
...