<- array(1:20, c(4, 5))
x <- array(1:5*10, c(1, 5))
y print(x)
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 5 9 13 17
#> [2,] 2 6 10 14 18
#> [3,] 3 7 11 15 19
#> [4,] 4 8 12 16 20
print(y)
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 10 20 30 40 50
Binding Explained
This page explains some details on broadcasting that are specific to the bind_array() function.
The bind_array() function binds 2 or more arrays together along a dimension, and fully supports broadcasting. While it’s relatively easy to reason about broadcasting when it involves only 2 arrays, reasoning about broadcasting when it involves more than 2 arrays becomes a bit more difficult. Therefore, bind_array() comes with the ndim2bc
argument (an abbreviation of ” maximum number of dimensions to broadcast”), which allows users to specify the maximum number of dimensions that are allowed to be broadcasted while binding arrays. This way, users won’t get unpleasant surprises.
This should be fairly obvious, but the dimension specified in along
is never broadcasted.
By default, ndim2bc
is set to 1
. This means that, by default, bind_array() will broadcast no more than 1 dimension for each array in the input list, when necessary.
Consider the following arrays:
Binding them together with abind()
won’t work:
::abind(x, y, along = 2)
abindin abind::abind(x, y, along = 2) :
Error 'X2' has dims=1, 5; but need dims=4, X arg
To bind x
and y
together along columns, y
needs its single row to be recycled (broadcasted) 4 times.
This can be done in a highly efficient way using bind_array(), like so:
bind_array(list(x, y), 2L)
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#> [1,] 1 5 9 13 17 10 20 30 40 50
#> [2,] 2 6 10 14 18 10 20 30 40 50
#> [3,] 3 7 11 15 19 10 20 30 40 50
#> [4,] 4 8 12 16 20 10 20 30 40 50
But what if broadcasting is explicitly not desired? What if one actually wants this to produce an error, like abind()
? Fret not, for that’s what the ndim2bc
argument is for. Setting it to 0
will disable broadcasting altogether:
bind_array(list(x, y), 2L, ndim2bc = 0)
in bind_array(list(x, y), 2L, ndim2bc = 0) :
Error broadcasted (1) exceeds `ndim2bc` (0) maximum number of dimensions to be
Let’s replace x
with a 3 dimensional array:
<- array(1:20, c(4, 5, 3))
x print(x)
#> , , 1
#>
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 5 9 13 17
#> [2,] 2 6 10 14 18
#> [3,] 3 7 11 15 19
#> [4,] 4 8 12 16 20
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 5 9 13 17
#> [2,] 2 6 10 14 18
#> [3,] 3 7 11 15 19
#> [4,] 4 8 12 16 20
#>
#> , , 3
#>
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 5 9 13 17
#> [2,] 2 6 10 14 18
#> [3,] 3 7 11 15 19
#> [4,] 4 8 12 16 20
Trying to bind x
with y
now will produce an error even with bind_array(), to protect the user from unintended broadcasting:
bind_array(list(x, y), 2L)
in bind_array(list(x, y), 2L) :
Error broadcasted (2) exceeds `ndim2bc` (1) maximum number of dimensions to be
If you know you actually do want to broadcast multiple dimensions, simply increase ndim2bc
:
bind_array(list(x, y), 2L, ndim2bc = 3L)
#> , , 1
#>
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#> [1,] 1 5 9 13 17 10 20 30 40 50
#> [2,] 2 6 10 14 18 10 20 30 40 50
#> [3,] 3 7 11 15 19 10 20 30 40 50
#> [4,] 4 8 12 16 20 10 20 30 40 50
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#> [1,] 1 5 9 13 17 10 20 30 40 50
#> [2,] 2 6 10 14 18 10 20 30 40 50
#> [3,] 3 7 11 15 19 10 20 30 40 50
#> [4,] 4 8 12 16 20 10 20 30 40 50
#>
#> , , 3
#>
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#> [1,] 1 5 9 13 17 10 20 30 40 50
#> [2,] 2 6 10 14 18 10 20 30 40 50
#> [3,] 3 7 11 15 19 10 20 30 40 50
#> [4,] 4 8 12 16 20 10 20 30 40 50