"Reduce"会将未经请求的属性添加到结果中

Eva*_*Aad 4 functional-programming r

对比以下两个代码段:

1.

> a <- cbind(1,2)
> a
     [,1] [,2]
[1,]    1    2
> str(a)
 num [1, 1:2] 1 2
Run Code Online (Sandbox Code Playgroud)

2.

> b <- Reduce(cbind, list(1,2))
> b
     init  
[1,]    1 2
> str(b)
 num [1, 1:2] 1 2
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:2] "init" ""
Run Code Online (Sandbox Code Playgroud)

根据Reduce帮助页面,我希望a并且b是相同的,但他们显然不是很好.为什么?

Jos*_*ich 5

这是因为Reduce调用f以及如何cbind创建列名称.Reduce根据initrightargs 的值确定初始值,并将该值存储在一个名为的对象中init,它也会迭代地更新.

在您的示例中,以下代码Reduce是发生差异的位置:

init <- x[[1L]]
ind <- ind[-1L]
for (i in ind) init <- f(init, x[[i]])
Run Code Online (Sandbox Code Playgroud)

默认cbind参数,deparse.level = 1意味着它尝试dimnames通过去除传递给它的对象名称来创建(如果它们产生合理的名称).如果您希望Reduce输出与调用cbind单个数字相同,则设置deparse.level=0.

> str(Reduce(function(x,y) cbind(x,y,deparse.level=0), list(1,2)))
 num [1, 1:2] 1 2
Run Code Online (Sandbox Code Playgroud)

顺便说cbind一句,调用for循环是一个坏主意,因为它必须在每次迭代时重新分配内存,导致代码非常慢.分配您期望的完整输出对象(如果可以)然后填写元素要好得多.