uso language functions family data r ellipsis replicate sapply

functions - r language apply data frame



Usando "..." y "replicar" (4)

En realidad, hay una manera de hacer esto:

# 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

En la documentación de sapply y replicate hay una advertencia sobre el uso de ...

Ahora, puedo aceptarlo como tal, pero me gustaría entender qué hay detrás de esto. Así que he creado este pequeño ejemplo artificial:

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)

Tal vez haya hecho algo obvio, horriblemente mal, pero encuentro el resultado bastante molesto. Entonces, ¿alguien puede explicarme por qué, en todas las llamadas anteriores a la función outerfunction , obtengo esta salida:

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

Como dije: los doctores parecen advertir sobre esto, pero no veo por qué esto es así.


Si miras el código para replicate :

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

Verá que la función se evalúa en el marco principal, donde ya no existe ... desde su función de llamada.


Una forma alternativa de hacerlo:

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)


?replicate , en la sección de Ejemplos, nos dice explícitamente que lo que está tratando de hacer no funciona y no funcionará. En la sección de Note de ?replicate tenemos:

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

Y si nos fijamos en los ejemplos, vemos:

## 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)

Mi lectura de los documentos es que hacen mucho más que advertirle sobre el uso de ... en replicate() llamadas replicate() ; documentan explícitamente que no funciona. Gran parte de la discusión en ese archivo de ayuda se relaciona con ... argumento de las otras funciones, no necesariamente para replicate() .