2010-08-05 33 views
28

Estoy confundido por el uso de puntos suspensivos (...) en algunas funciones, es decir, cómo pasar un objeto que contiene los argumentos como un único argumento.Desempaquetar listas de argumentos para elipsis en R

En Python se denomina "listas de argumentos de desempaquetado", p.

>>> range(3, 6)    # normal call with separate arguments 
[3, 4, 5] 
>>> args = [3, 6] 
>>> range(*args)   # call with arguments unpacked from a list 
[3, 4, 5] 

En R, por ejemplo, que tienen la función file.path(...) que utiliza una elipsis. Me gustaría tener este comportamiento:

> args <- c('baz', 'foob') 
> file.path('/foo/bar/', args) 
[1] 'foo/bar/baz/foob' 

En cambio, me sale

[1] 'foo/bar/baz' 'foo/bar/foob' 

donde los elementos de args no son "desempaquetado" y evaluado al mismo tiempo. ¿Hay un R equivalente a Pythons *arg?

Respuesta

30

el sintaxis no es tan bonito, pero esto hace el truco:

do.call(file.path,as.list(c("/foo/bar",args))) 

do.call toma dos argumentos: una función y una lista de argumentos para llamar a esa función.

+0

Gracias, eso fue todo. – mhermans

+0

Una discusión extensa sobre esta técnica: https://www.r-bloggers.com/a-new-r-trick-for-me-at-least/ – Alex

17

Puede extraer información de las elipsis llamando al list(...) dentro de la función. En este caso, la información en la ellipsis se empaqueta como un objeto de lista. Por ejemplo:

> foo <- function(x,...){ 
+ print(list(...)) 
+ } 
> foo(1:10,bar = 'bar','foobar') 
$bar 
[1] "bar" 

[[2]] 
[1] "foobar" 

se puede lograr el comportamiento deseado de las funciones vectorizados como file.path con una llamada a do.call, que a veces es más fácil de usar con la envoltura splat (en el paquete plyr)

> args <- c('baz', 'foob') 
> library(plyr) 
> splat(file.path)(c('/foo/bar', args)) 
[1] "/foo/bar/baz/foob" 
+0

Gracias (aún no se puede votar). – mhermans

Cuestiones relacionadas