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