我可以删除...(点 - 点)中的元素并传递它吗?

SFu*_*n28 22 r ellipsis

是否可以从...中删除元素并将...传递给其他函数?我的前两次尝试失败了:

parent = function(...)
{

   a = list(...)
   str(a)
   a$toRemove = NULL  
   str(a)

   # attempt 1   
   child(a)   

   # attempt 2
   child( ... = a )
}


child = function(...)
{
  a = list( ... )
  str(a)
}

parent( a = 1 , toRemove = 2 )
Run Code Online (Sandbox Code Playgroud)

编辑
抱歉混乱.我修了孩子().目的是让孩子列出......的内容

Edit2
这里有一个更真实的例子(但仍然相当简单,所以我们可以就此进行有用的对话).父通过递归调用.父需要知道递归调用的深度.父母以外的来电者不应该知道"深度",也不应该在调用parent()时设置它.Parent调用其他函数,在本例中为child().孩子需要值...显然,孩子不需要"深度",因为父母为自己的使用生成了它.

parent = function( ... )
{

   depth = list(...)$depth      
   if ( is.null( depth ) )
   {
       depth = 1
   }  
   print( depth )

   # parent needs value of depth to perform various calculations (not shown here)

   if ( depth == 5 )
   {
       return()
   }
   else
   {
      # child doesn't need "depth" in ...
      child( ... ) 
   }

   # yikes!  now we've added a second, third, etc. depth value to ...
   parent( depth = depth + 1 , ... )

}


child = function(...) 
{       
    # does some magic    
}
Run Code Online (Sandbox Code Playgroud)

Rei*_*son 24

操纵这些事情的方法之一是包裹child函数内部parent,并用它把你不想传递任何参数来定义child ...说法.例如:

parent <- function(...) {
    localChild <- function(..., toRemove) child(...)
    localChild(...)
}
child <- function(a) {
    a + 10
}

> parent(a = 1, toRemove = 10)
[1] 11
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用do.call():

parent2 <- function(...) {
    a <- list(...)
    a$toRemove <- NULL
    do.call(child2, a)
}
child2 <- function(b) {
    b + 10
}
> parent2(b = 1, toRemove = 10)
[1] 11
Run Code Online (Sandbox Code Playgroud)

根据您的实际使用情况,do.call()可能与您对问题的预期最接近.

  • @SFun28 是的;假设“parent()”有参数“x”、“y”、“...”和“child(x, y, a)”,但没有“b”。如上所示去掉 `b` (`dots &lt;- list(...);dots$b &lt;- NULL`),然后执行 `do.call(child, c(dots, x = x, y = y) )` 例如。就像我说的,我显示的习惯用法将取决于您*真正*想要做什么。`localFoo()` 技巧在基本 R 中绘制代码时经常使用,以传递图形参数和相关参数到其他绘图代码。我有一篇关于此的[博客文章](http://ucfagls.wordpress.com/2011/07/23/passing-non-graphical-parameters-to-graphical-functions-using/)。 (2认同)
  • @ SFun28:看看我的答案.使用match.call时,请注意eval()工作的帧.lm()函数使用这个结构,但它可以给出相当奇怪的结果. (2认同)

Jor*_*eys 5

你的孩子功能是错误的.尝试

> child(a=1)
Error in str(a) : object 'a' not found
Run Code Online (Sandbox Code Playgroud)

编辑:不再适用.

...参数只应用于将参数传递给下一个函数.除非将它们转换为列表,否则无法从中轻松获取参数.所以你的孩子的功能可能是:

child <- function(...)
{
  mc <- match.call()  # or mc <- list(...)
  str(mc$a)
}
Run Code Online (Sandbox Code Playgroud)

这没有意义.您无法知道用户是否指定了a.正确的方法是a在函数中包含一个参数.的...是将参数传递给下一个:

child <- function(a, ...){
    str(a,...)
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

parent <- function(...){

   mc <- match.call()
   mc$toRemove <- NULL
   mc[[1L]] <- as.name("child")
   eval(mc)

}
Run Code Online (Sandbox Code Playgroud)

或使用list(...)do.call()构建@Gavin提议.好处match.call()是你也可以包含非点参数.这允许您的父函数指定子项的默认值:

parent <- function(a=3, ...){
    ... (see above)
}
Run Code Online (Sandbox Code Playgroud)