Подтвердить что ты не робот

Распаковка списков аргументов для многоточия в R

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

В Python он называется "распаковкой списков аргументов", например

>>> 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]

В R, например, у вас есть функция file.path(...), которая использует многоточие. Я хотел бы иметь такое поведение:

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

Вместо этого я получаю

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

где элементы args не распаковываются и не оцениваются одновременно. Существует ли R эквивалент Pythons *arg?

4b9b3361

Ответ 1

Синтаксис не такой красивый, но это делает трюк:

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

do.call принимает два аргумента: функцию и список аргументов для вызова этой функции с помощью.

Ответ 2

Вы можете извлекать информацию из эллипса, вызывая list(...) внутри функции. В этом случае информация в эллипсисе упаковывается как объект списка. Например:

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

[[2]]
[1] "foobar"

Вы можете добиться желаемого поведения от векторизованных функций, таких как file.path, с вызовом do.call, который иногда проще использовать с оберткой splat (в пакете plyr)

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