Contrast the following two code snippets:
1.
> a <- cbind(1,2)
> a
[,1] [,2]
[1,] 1 2
> str(a)
num [1, 1:2] 1 2
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" ""
According to the Reduce
help page, i would expect a
and b
to be the same, but they're obviously not quite. Why is it?
It's because of how Reduce
calls f
and how cbind
creates column names. Reduce
determines the initial value based on the values of the init
and right
args and stores that value in an object named init
, which it also happens to update iteratively.
In your example, the following code in Reduce
is where the difference occurs:
init <- x[[1L]]
ind <- ind[-1L]
for (i in ind) init <- f(init, x[[i]])
The default cbind
argument, deparse.level = 1
means that it tries to create dimnames
via deparsing the object names passed to it (if they make sensible names). If you want the Reduce
output to be identical to calling cbind
on single numbers, then set deparse.level=0
.
> str(Reduce(function(x,y) cbind(x,y,deparse.level=0), list(1,2)))
num [1, 1:2] 1 2
As an aside, calling cbind
in a for loop is a bad idea because it must re-allocate memory on each iteration, leading to very slow code. It's much better to allocate the full output object you expect (if you can) and then fill in the elements.
The answer of Joshua explains why you have a difference. I just show how to get the same output. Indeed you should initialize the init parameter to NULL:
identical(Reduce(cbind, list(1,2),init=NULL),
cbind(1,2))
TRUE
And as aside is more efficient here to call :
do.call(cbind,list(1,2))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With