Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用R';在编写自己的函数时,是否具有省略号功能?_R_Function_Parameters_Ellipsis_Variadic - Fatal编程技术网

如何使用R';在编写自己的函数时,是否具有省略号功能?

如何使用R';在编写自己的函数时,是否具有省略号功能?,r,function,parameters,ellipsis,variadic,R,Function,Parameters,Ellipsis,Variadic,R语言有一个很好的特性,用于定义可以接受可变数量参数的函数。例如,函数data.frame接受任意数量的参数,每个参数都成为结果数据表中一列的数据。用法示例: > data.frame(letters=c("a", "b", "c"), numbers=c(1,2,3), notes=c("do", "re", "mi")) letters numbers notes

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

> data.frame(letters=c("a", "b", "c"), numbers=c(1,2,3), notes=c("do", "re", "mi"))
  letters numbers notes
1       a       1    do
2       b       2    re
3       c       3    mi
函数的签名包含一个省略号,如下所示:

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

我想写一个函数,做一些类似的事情,获取多个值并将它们合并成一个返回值(以及做一些其他处理)。为了做到这一点,我需要弄清楚如何从函数内的函数参数中“解包”
。我不知道怎么做。
data.frame
函数定义中的相关行是
object您已经给出了一半的答案。考虑

R> my_ellipsis_function <- function(...) {
+   input_list <- as.list(substitute(list(...)))
+ }
R> print(my_ellipsis_function(a=1:10, b=2:20))
[[1]]
list

$a
1:10

$b
11:20

R> 
R>我的省略号函数

因此,这从调用中获取了两个参数
a
b
,并将其转换为一个列表。这不是您要求的吗?

您可以使用
list()
将省略号转换为列表,然后对其执行操作:

> test.func <- function(...) { lapply(list(...), class) }
> test.func(a="b", b=1)
$a
[1] "character"

$b
[1] "numeric"
test.func test.func(a=“b”,b=1) 一美元 [1] “角色” b美元 [1] “数字”
因此,您的
get\u list\u from\u省略号
函数只不过是
list

这方面的一个有效用例是希望传入未知数量的对象进行操作的情况(如
c()
data.frame()
的示例)。但是,当您事先知道每个参数时,使用
不是一个好主意,因为它会给参数字符串增加一些模糊性和进一步的复杂性(并使任何其他用户都不清楚函数签名)。参数列表是函数用户的重要文档


否则,对于希望将参数传递给子函数而不在自己的函数参数中公开它们的情况,它也很有用。这一点可以在函数文档中看到。

只是为了补充Shane和Dirk的回答:比较起来很有趣

get_list_from_ellipsis1 <- function(...)
{
  list(...)
}
get_list_from_ellipsis1(a = 1:10, b = 2:20) # returns a list of integer vectors

$a
 [1]  1  2  3  4  5  6  7  8  9 10

$b
 [1]  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

get_list_from_ellipsis1我阅读了答案和评论,发现有几件事没有提到:

  • data.frame
    使用
    列表(…)
    版本。代码片段:

    object <- as.list(substitute(list(...)))[-1L]
    mrn <- is.null(row.names)
    x <- list(...)
    
    第一个元素没有名称,这是Dirk answer中的
    [[1]]
    。我通过以下方式实现这一结果:

    my_ellipsis_function <- function(...) {
      input_list <- as.list(substitute(list(...)))
      str(input_list)
      NULL
    }
    my_ellipsis_function(a=1:10,b=11:20,c=21:30)
    
    没关系。请参见替换版本:

       my_ellipsis_function <- function(...) {
           input_list <- as.list(substitute(list(...)))
           output_list <- lapply(X=input_list, function(x) {str(x);summary(x)})
           return(output_list)
       }
       my_ellipsis_function(a=1:10,b=11:20,c=21:30)
        symbol list
        language 1:10
        language 11:20
        language 21:30
       [[1]]
       Length  Class   Mode 
            1   name   name 
       $a
       Length  Class   Mode 
            3   call   call 
       $b
       Length  Class   Mode 
            3   call   call 
       $c
       Length  Class   Mode 
            3   call   call 
    
    my_省略号函数此函数按预期工作。
    以下是一个交互式会话:

    > talk <- function(func, msg, ...){
    +     func(msg, ...);
    + }
    > talk(cat, c("this", "is", "a","message."), sep=":")
    this:is:a:message.
    > 
    
    谈话(cat,c(“这”、“是”、“a”、“消息”)、sep=“:”) 这是一条信息。 >
    相同,但使用默认参数除外:

    > talk <- function(func, msg=c("Hello","World!"), ...){
    +     func(msg, ...);
    + }
    > talk(cat,sep=":")
    Hello:World!
    > talk(cat,sep=",", fill=1)
    Hello,
    World!
    >
    
    谈话(cat,sep=“:”) 你好:世界! >通话(cat,sep=“,”,fill=1) 你好 世界! >

  • 如您所见,如果在特定情况下,默认值不是您想要的,则可以使用此函数将“额外”参数传递给函数中的函数。

    与我想要的不完全一样。它实际上似乎返回了一个列表列表。请注意
    [[1]]
    。另外,我想知道魔法咒语
    as.list(替换(list(…))
    是如何工作的。内部
    list(…)
    根据参数创建一个
    list
    对象。然后
    substitute()
    为未赋值表达式创建解析树;请参阅此函数的帮助。以及R(或S)上的良好高级文本。这不是小事。好吧,那
    [[-1L]]
    部分呢(我的问题)?不应该是
    [[1]]
    ?您需要仔细阅读索引。减号表示“排除”,即
    print(c(1:3)[-1])
    仅打印2和3。
    L
    是一种确保它最终成为整数的新方法,这在R源代码中做了很多。我不需要阅读索引,但我需要更加关注您显示的命令的输出。
    [[1]]
    $a
    索引之间的差异使我认为嵌套列表涉及其中。但是现在我看到你实际上得到的是我想要的列表,但是前面有一个额外的元素。因此,
    [-1L]
    是有意义的。那个额外的第一个元素是从哪里来的呢?有什么理由我应该使用它而不是简单的
    列表(…)
    ?我知道如何使用省略号作为子函数参数的传递,但在R原语中,以我描述的方式使用省略号也是常见的做法。事实上,
    list
    c
    函数都是这样工作的,但它们都是原语,因此我无法轻松检查它们的源代码以了解它们是如何工作的。
    rbind.data.frame
    使用这种方式。如果
    list(…)
    足够了,为什么像
    data.frame
    这样的内置函数会使用较长的
    as.list(替换(list(…))[-1L]
    相反?因为我没有创建
    data.frame
    ,所以我不知道这个问题的答案(也就是说,我确信这有一个很好的理由)。我在自己的包中使用
    list()
    来实现这个目的,但还没有遇到问题。
    my_ellipsis_function <- function(...) {
        input_list <- list(...)
        output_list <- lapply(X=input_list, function(x) {str(x);summary(x)})
        return(output_list)
    }
    my_ellipsis_function(a=1:10,b=11:20,c=21:30)
     int [1:10] 1 2 3 4 5 6 7 8 9 10
     int [1:10] 11 12 13 14 15 16 17 18 19 20
     int [1:10] 21 22 23 24 25 26 27 28 29 30
    $a
       Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
       1.00    3.25    5.50    5.50    7.75   10.00 
    $b
       Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
       11.0    13.2    15.5    15.5    17.8    20.0 
    $c
       Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
       21.0    23.2    25.5    25.5    27.8    30.0 
    
       my_ellipsis_function <- function(...) {
           input_list <- as.list(substitute(list(...)))
           output_list <- lapply(X=input_list, function(x) {str(x);summary(x)})
           return(output_list)
       }
       my_ellipsis_function(a=1:10,b=11:20,c=21:30)
        symbol list
        language 1:10
        language 11:20
        language 21:30
       [[1]]
       Length  Class   Mode 
            1   name   name 
       $a
       Length  Class   Mode 
            3   call   call 
       $b
       Length  Class   Mode 
            3   call   call 
       $c
       Length  Class   Mode 
            3   call   call 
    
    > talk <- function(func, msg, ...){
    +     func(msg, ...);
    + }
    > talk(cat, c("this", "is", "a","message."), sep=":")
    this:is:a:message.
    > 
    
    > talk <- function(func, msg=c("Hello","World!"), ...){
    +     func(msg, ...);
    + }
    > talk(cat,sep=":")
    Hello:World!
    > talk(cat,sep=",", fill=1)
    Hello,
    World!
    >