Распаковка списков аргументов для многоточия в 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?

3 ответа

Решение

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

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

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

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

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

[[2]]
[1] "foobar"

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

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

Мне понадобилось время, чтобы найти его, но purrr пакет имеет эквивалент plyr::splat: это называется lift_dl,

"Dl" в названии означает "точки в списке", так как это часть серии lift_xy функции, которые можно использовать для "поднятия" области функции от одного вида ввода к другому, эти "виды" представляют собой списки, векторы и "точки".

поскольку lift_dl вероятно, самый полезный из них, есть простой lift псевдоним для этого.

Чтобы повторно использовать приведенный выше пример:

> library(purrr)
> args <- c('baz', 'foob')
> lift(file.path)(c('/foo/bar', args))
[1] "/foo/bar/baz/foob"
Другие вопросы по тегам