在R中解压缩省略号的参数列表

mhe*_*ans 40 r list ellipsis iterable-unpacking

...对一些函数中使用省略号()感到困惑,即如何将包含参数的对象作为单个参数传递.

在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]
Run Code Online (Sandbox Code Playgroud)

例如,在R中你有一个file.path(...)使用省略号的函数.我想有这样的行为:

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

相反,我得到了

[1] 'foo/bar/baz' 'foo/bar/foob'
Run Code Online (Sandbox Code Playgroud)

其中的元素args不是"解包"并同时进行评估.是否有R等价于蟒蛇*arg

Jyo*_*rya 39

语法不是那么漂亮,但这样做有:

do.call(file.path,as.list(c("/foo/bar",args)))
Run Code Online (Sandbox Code Playgroud)

do.call 有两个参数:一个函数和一个用于调用该函数的参数列表.

  • 关于这种技术的扩展讨论:https://www.r-bloggers.com/a-new-r-trick-for-me-at-least/ (2认同)

nul*_*lob 21

您可以通过调用list(...)函数内部来从省略号中提取信息.在这种情况下,省略号中的信息将打包为列表对象.例如:

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

[[2]]
[1] "foobar"
Run Code Online (Sandbox Code Playgroud)

你可以从矢量化函数中实现所需的行为,比如file.path调用do.call,这有时候更容易与包装器一起使用splat(在plyr包中)

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


Nic*_*tte 5

我花了一段时间才找到它,但该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"
Run Code Online (Sandbox Code Playgroud)