解包R中省略号的参数列表

z9ju0rcb  于 2023-04-18  发布在  其他
关注(0)|答案(3)|浏览(135)

我对某些函数中使用省略号(...)感到困惑,即如何将包含参数的对象作为单个参数传递。
在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等价于Python *arg

svujldwt

svujldwt1#

语法不是那么漂亮,但这确实是个窍门:

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

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

rbpvctlc

rbpvctlc2#

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

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

[[2]]
[1] "foobar"

您可以通过调用do.call来实现像file.path这样的向量化函数的所需行为,这有时与 Package 器splat(在plyr包中)一起使用更简单。

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

8iwquhpp3#

我花了一段时间才找到它,但是purrr包有一个等价于plyr::splat的包:叫做lift_dl
名称中的“dl”代表“dots to list”,因为它是一系列lift_xy函数的一部分,可用于将函数的域从一种输入“提升”到另一种输入,这些“种类”是列表,向量和“点”。
由于lift_dl可能是其中最有用的,因此为它提供了一个简单的lift别名。
要重复使用上面的示例:

library(purrr)
args <- c("baz", "foob")
lift(file.path)(c("/foo/bar", args))
# [1] "/foo/bar/baz/foob"

更新

从purrr 1.0.0开始,lift_*系列函数被弃用。
接下来,应该使用rlang::inject来通过!!! operator实现拼接:

library(rlang)
args <- c("baz", "foob")
inject(file.path("/foo/bar", !!!args))
#> [1] "/foo/bar/baz/foob"

相关问题