【问题标题】:Using "..." and "replicate"使用“...”和“复制”
【发布时间】:2011-10-05 23:32:21
【问题描述】:

sapplyreplicate 的文档中有关于使用... 的警告

现在,我可以接受它,但想了解它背后的原因。所以我创建了这个人为的小例子:

innerfunction<-function(x, extrapar1=0, extrapar2=extrapar1)
{
    cat("x:", x, ", xp1:", extrapar1, ", xp2:", extrapar2, "\n")
}

middlefunction<-function(x,...)
{
    innerfunction(x,...)
}

outerfunction<-function(x, ...)
{
    cat("Run middle function:\n")
    replicate(2, middlefunction(x,...))
    cat("Run inner function:\n")
    replicate(2, innerfunction(x,...))
}

outerfunction(1,2,3)
outerfunction(1,extrapar1=2,3)
outerfunction(1,extrapar1=2,extrapar2=3)

也许我做了一些明显非常糟糕的事情,但我发现这样做的结果相当令人沮丧。那么任何人都可以向我解释为什么在上述所有对outerfunction 的调用中,我得到了这个输出:

Run middle function:
x: 1 , xp1: 0 , xp2: 0 
x: 1 , xp1: 0 , xp2: 0 
Run inner function:
x: 1 , xp1: 0 , xp2: 0 
x: 1 , xp1: 0 , xp2: 0

就像我说的:文档似乎对此发出警告,但我不明白为什么会这样。

【问题讨论】:

    标签: r ellipsis replicate sapply


    【解决方案1】:

    ?replicate 在示例部分中明确告诉我们,您尝试做的事情不会也不会奏效。在?replicateNote 部分,我们有:

         If ‘expr’ is a function call, be aware of assumptions about where
         it is evaluated, and in particular what ‘...’ might refer to.  You
         can pass additional named arguments to a function call as
         additional named arguments to ‘replicate’: see ‘Examples’.
    

    如果我们查看示例,我们会看到:

     ## use of replicate() with parameters:
     foo <- function(x=1, y=2) c(x,y)
     # does not work: bar <- function(n, ...) replicate(n, foo(...))
     bar <- function(n, x) replicate(n, foo(x=x))
     bar(5, x=3)
    

    我对文档的阅读是,它们不仅仅警告您在 replicate() 调用中使用 ...;他们明确记录它不起作用。该帮助文件中的大部分讨论与其他函数的... 参数 相关,不一定与replicate() 相关。

    【讨论】:

    • 请注意,在示例中,“正确”方式无法正常工作 - 它被复制 x 次 (3) 而不是 n 次 (5)。
    • @James - 不在我的系统上。我得到 bar(5, x = 3) 的 2*5 矩阵
    • 糟糕,我的错误。转录示例时有错字。
    • @Gavin:?replicate 的引用是我在问题中提到的警告。我想知道这个警告是什么意思? “评估的地方”和“......可能指的是什么”对我来说有点神秘。所以,再说一遍:我承认它不起作用,但是 为什么 它不起作用?这可能会极大地帮助我/其他人理解 R 中的参数传递/解析。
    • @Nick 抱歉回复晚了;在我看来,这不起作用的原因是您没有调用expr 中的函数,您只是在评估expr。因为你没有调用它,所以没有从外部调用...expr 的参数传递。这是一个微妙的区别,但非常重要;就好像你在全局环境中调用 middlefunction(...) 完全一样(你不能,因为 R 不允许你像那样交互地使用 ...),而 ... 没有引用任何东西。跨度>
    【解决方案2】:

    如果您查看replicate 的代码:

    > replicate
    function (n, expr, simplify = TRUE) 
    sapply(integer(n), eval.parent(substitute(function(...) expr)), 
        simplify = simplify)
    <environment: namespace:base>
    

    您会看到该函数在父框架中进行评估,其中您调用函数的... 不再存在。

    【讨论】:

      【解决方案3】:

      实际上有一种方法可以做到这一点:

      # Simple function:
      ff <- function(a,b) print(a+b)
      
      # This will NOT work:
      testf <- function(...) {
        replicate(expr = ff(...), n = 5)
      }
      testf(45,56) # argument "b" is missing, with no default
      
      # This will:
      testf <- function(...) {
        args <- as.list(substitute(list(...)))[-1L]
        replicate(expr = do.call(ff, args), n = 5)
      }
      testf(45,56) # 101
      

      【讨论】:

        【解决方案4】:

        另一种方法:

        g <- function(x, y) x + y
        
        f <- function(a = 1, ...) {
            arg_list <- list(...)
            replicate(n = 3, expr = do.call(g, args = arg_list))
        }
        
        f(x = 1, y = 2)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-17
          • 2015-01-06
          • 2014-04-18
          • 2018-01-05
          • 2016-12-15
          相关资源
          最近更新 更多