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

发布于 2024-09-13 04:14:54 字数 649 浏览 1 评论 0原文

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

在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

I am confused by the use of the ellipsis (...) in some functions, i.e. how to pass an object containing the arguments as a single argument.

In Python it is called "unpacking argument lists", e.g.

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

In R for instance you have the function file.path(...) that uses an ellipsis. I would like to have this behaviour:

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

Instead, I get

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

where the elements of args are not "unpacked" and evaluated at the same time. Is there a R equivalent to Pythons *arg?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

叫思念不要吵 2024-09-20 04:14:54

语法并不那么漂亮,但这确实有效:

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

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

The syntax is not as beautiful, but this does the trick:

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

do.call takes two arguments: a function and a list of arguments to call that function with.

情泪▽动烟 2024-09-20 04:14:54

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

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

[[2]]
[1] "foobar"

您可以通过调用 do.call 从矢量化函数(如 file.path)实现所需的行为,有时与包装器 一起使用会更简单splat(在 plyr 包中)

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

You can extract information from the ellipsis by calling list(...) inside the function. In this case, the info in the ellipsis is packaged as a list object. For example:

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

[[2]]
[1] "foobar"

You can achieve the desired behaviour from vectorised functions like file.path with a call to do.call, which is sometimes simpler to use with the wrapper splat (in the plyr package)

> args <- c('baz', 'foob')
> library(plyr)
> splat(file.path)(c('/foo/bar', args))
[1] "/foo/bar/baz/foob"
撑一把青伞 2024-09-20 04:14:54

我花了一段时间才找到它,但是 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 通过 !!! 运算符启用拼接

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

It took me a while to find it, but the purrr package has an equivalent to plyr::splat: it's called lift_dl.

The "dl" in the name stands for "dots to list", as it's part of a series of lift_xy functions that can be used to "lift" the domain of a function from one kind of input to another kind, these "kinds" being lists, vectors and "dots".

Since lift_dl is probably the most useful of those, there is a simple lift alias provided for it.

To reuse the above example:

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

Update

As of purrr 1.0.0, the lift_* family of functions is deprecated.

Moving forward, one should instead use rlang::inject to enable splicing via the !!! operator:

library(rlang)
args <- c("baz", "foob")
inject(file.path("/foo/bar", !!!args))
#> [1] "/foo/bar/baz/foob"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文