2010-08-05 9 views
28

Je suis confus par l'utilisation de l'ellipse (...) dans certaines fonctions, c'est-à-dire comment passer un objet contenant les arguments en tant qu'argument unique.Décompresser les listes d'arguments pour les ellipses dans R

En Python, il est appelé "déballage des listes d'arguments", par ex.

>>> 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, par exemple, vous avez la fonction file.path(...) qui utilise des points de suspension. Je voudrais avoir ce comportement:

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

Au lieu de cela, je reçois

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

où les éléments de args ne sont pas « déballer » et évalués en même temps. Y at-il un R équivalent à Python *arg?

Répondre

30

la syntaxe est pas aussi beau, mais cela ne l'astuce:

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

do.call prend deux arguments: une fonction et une liste d'arguments pour appeler cette fonction.

+0

Merci, ça l'a fait. – mhermans

+0

Une discussion prolongée sur cette technique: https://www.r-bloggers.com/a-new-r-trick-for-me-at-least/ – Alex

17

Vous pouvez extraire des informations de l'ellipse en appelant list(...) dans la fonction. Dans ce cas, l'info de l'ellipse est empaquetée en tant qu'objet liste. Par exemple:

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

[[2]] 
[1] "foobar" 

Vous pouvez obtenir le comportement souhaité des fonctions vectorisées comme file.path avec un appel à do.call, ce qui est parfois plus simple à utiliser avec l'emballage splat (dans le paquet plyr)

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

Merci (ne peut pas encore upvote). – mhermans

Questions connexes