如何在编写自己的函数时使用R的省略功能?

如何在编写自己的函数时使用R的省略功能?

R语言有一个很好的特性来定义函数,这些函数可以使用可变数量的参数。例如,函数data.frame接受任意数量的参数,每个参数将成为结果数据表中某列的数据。示例用法:

> data.frame(letters=c("a", "b", "c"), numbers=c(1,2,3), notes=c("do", "re", "mi"))
  letters numbers notes1       a       1    do2       b       2    re3       c       3    mi

函数的签名包括省略号,如下所示:

function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, 
    stringsAsFactors = default.stringsAsFactors()) {
    [FUNCTION DEFINITION HERE]}

我想编写一个类似的函数,获取多个值并将它们合并为一个返回值(以及一些其他处理)。为了做到这一点,我需要弄清楚如何“解压”...函数中的参数。我不知道该怎么做。函数定义中的相关行data.frameobject <- as.list(substitute(list(...)))[-1L]我完全搞不懂。

那么,如何将省略号从函数的签名转换成列表呢?

更确切地说,我怎么写get_list_from_ellipsis在下面的代码里?

my_ellipsis_function(...) {
    input_list <- get_list_from_ellipsis(...)
    output_list <- lapply(X=input_list, FUN=do_something_interesting)
    return(output_list)}my_ellipsis_function(a=1:10,b=11:20,c=21:30)

编辑

似乎有两种可能的方法来做到这一点。他们是as.list(substitute(list(...)))[-1L]list(...)..然而,这两种做法并不完全相同。(关于差异,请参见答案中的示例。)谁能告诉我他们之间的实际区别是什么,以及我应该使用哪一个?


江户川乱折腾
浏览 1005回答 3
3回答

慕工程0101907

可以将省略号转换为list(),然后对其执行操作:>&nbsp;test.func&nbsp;<-&nbsp;function(...)&nbsp;{&nbsp;lapply(list(...),&nbsp;class)&nbsp;}>&nbsp;test.func(a="b",&nbsp;b=1)$a[1]&nbsp;"character"$b[1]&nbsp;"numeric"所以你的get_list_from_ellipsis函数只不过是list.这方面的有效用例是当您希望传递数目未知的要操作的对象时(如c()或data.frame())。使用...但是,当您预先知道每个参数时,因为它增加了参数字符串的一些模糊性和进一步的复杂性(并且使函数签名对任何其他用户都不明确)。参数列表是函数用户的重要文档。否则,当您希望将参数传递给子函数而不将它们全部暴露在您自己的函数参数中时,它也很有用。这可以在功能文档中看到。

LEATH

为了补充Shane和Dirk的回答:比较一下是很有趣的get_list_from_ellipsis1&nbsp;<-&nbsp;function(...){ &nbsp;&nbsp;list(...)}get_list_from_ellipsis1(a&nbsp;=&nbsp;1:10,&nbsp;b&nbsp;=&nbsp;2:20)&nbsp;#&nbsp;returns&nbsp;a&nbsp;list&nbsp;of&nbsp;integer&nbsp;vectors$a&nbsp;[1]&nbsp;&nbsp;1&nbsp;&nbsp;2&nbsp;&nbsp;3&nbsp;&nbsp;4&nbsp;&nbsp;5&nbsp;&nbsp;6&nbsp;&nbsp;7&nbsp;&nbsp;8&nbsp;&nbsp;9&nbsp;10$b&nbsp;[1]&nbsp;&nbsp;2&nbsp;&nbsp;3&nbsp;&nbsp;4&nbsp;&nbsp;5&nbsp;&nbsp;6&nbsp;&nbsp;7&nbsp;&nbsp;8&nbsp;&nbsp;9&nbsp;10&nbsp;11&nbsp;12&nbsp;13&nbsp;14&nbsp;15&nbsp;16&nbsp;17&nbsp;18&nbsp;19&nbsp;20带着get_list_from_ellipsis2&nbsp;<-&nbsp;function(...){ &nbsp;&nbsp;as.list(substitute(list(...)))[-1L]}get_list_from_ellipsis2(a&nbsp;=&nbsp;1:10,&nbsp;b&nbsp;=&nbsp;2:20)&nbsp;#&nbsp;returns&nbsp;a&nbsp;list&nbsp;of&nbsp;calls$a1:10$b2:20就目前情况而言,这两种版本似乎都适合您在my_ellipsis_function虽然第一条显然更简单
打开App,查看更多内容
随时随地看视频慕课网APP