bind_array

Dimensional Binding of Arrays with Broadcasting

Description

bind_array() binds (atomic/recursive) arrays and (atomic/recursive) matrices.
Returns an array.
Allows for broadcasting.

Usage

bind_array(
  input,
  along,
  rev = FALSE,
  ndim2bc = 1L,
  name_along = TRUE,
  comnames_from = 1L
)

Arguments

input a list of arrays; both atomic and recursive arrays are supported, and can be mixed.
If argument input has length 0, or it contains exclusively objects where one or more dimensions are 0, an error is returned.
If input has length 1, bind_array() simply returns input[[1L]].
input may not contain more than 2^16 objects.
along a single integer, indicating the dimension along which to bind the dimensions.
I.e. use along = 1 for row-binding, along = 2 for column-binding, etc.
Specifying along = 0 will bind the arrays on a new dimension before the first, making along the new first dimension.
Specifying along = N + 1, with N = max(lst.ndim(input)), will create an additional dimension (N + 1) and bind the arrays along that new dimension.
rev Boolean, indicating if along should be reversed, counting backwards.
If FALSE (default), along works like normally; if TRUE, along is reversed.
I.e. along = 0, rev = TRUE is equivalent to along = N+1, rev = FALSE;
and along = N+1, rev = TRUE is equivalent to along = 0, rev = FALSE;
with N = max(lst.ndim(input)).
ndim2bc a single non-negative integer;
specify here the maximum number of dimensions that are allowed to be broadcasted when binding arrays.
If ndim2bc = 0L, no broadcasting will be allowed at all.
name_along Boolean, indicating if dimension along should be named.
Please run the code in the examples section to get a demonstration of the naming behaviour.
comnames_from either an integer scalar or NULL.
Indicates which object in input should be used for naming the shared dimension.
If NULL, no communal names will be given.
For example:
When binding columns of matrices, the matrices will share the same rownames.
Using comnames_from = 10 will then result in bind_array() using rownames(input[[10]]) for the rownames of the output.

Value

An array.

Examples

library("broadcast")


# Simple example ====
x <- array(1:20, c(5, 4))
y <- array(-1:-15, c(5, 3))
z <- array(21:40, c(5, 4))
input <- list(x, y, z)
# column binding:
bind_array(input, 2L)
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
## [1,]    1    6   11   16   -1   -6  -11   21   26    31    36
## [2,]    2    7   12   17   -2   -7  -12   22   27    32    37
## [3,]    3    8   13   18   -3   -8  -13   23   28    33    38
## [4,]    4    9   14   19   -4   -9  -14   24   29    34    39
## [5,]    5   10   15   20   -5  -10  -15   25   30    35    40



# Mixing types ====
# here, atomic and recursive arrays are mixed,
# resulting in recursive arrays

# creating the arrays:
x <- c(
  lapply(1:3, \(x)sample(c(TRUE, FALSE, NA))),
  lapply(1:3, \(x)sample(1:10)),
  lapply(1:3, \(x)rnorm(10)),
  lapply(1:3, \(x)sample(letters))
) |> matrix(4, 3, byrow = TRUE)
dimnames(x) <- list(letters[1:4], LETTERS[1:3])
print(x)
##   A            B            C           
## a logical,3    logical,3    logical,3   
## b integer,10   integer,10   integer,10  
## c numeric,10   numeric,10   numeric,10  
## d character,26 character,26 character,26

y <- matrix(1:12, 4, 3)
print(y)
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
z <- matrix(letters[1:12], c(4, 3))

# column-binding:
input <- list(x = x, y = y, z = z)
bind_array(input, along = 2L)
##   A            B            C            y.1 y.2 y.3 z.1 z.2 z.3
## a logical,3    logical,3    logical,3    1   5   9   "a" "e" "i"
## b integer,10   integer,10   integer,10   2   6   10  "b" "f" "j"
## c numeric,10   numeric,10   numeric,10   3   7   11  "c" "g" "k"
## d character,26 character,26 character,26 4   8   12  "d" "h" "l"



# Illustrating `along` argument ====
# using recursive arrays for clearer visual distinction
input <- list(x = x, y = y)

bind_array(input, along = 0L) # binds on new dimension before first
## , , A
## 
##   a         b          c          d           
## x logical,3 integer,10 numeric,10 character,26
## y 1         2          3          4           
## 
## , , B
## 
##   a         b          c          d           
## x logical,3 integer,10 numeric,10 character,26
## y 5         6          7          8           
## 
## , , C
## 
##   a         b          c          d           
## x logical,3 integer,10 numeric,10 character,26
## y 9         10         11         12
bind_array(input, along = 1L) # binds on first dimension (i.e. rows)
##     A            B            C           
## a   logical,3    logical,3    logical,3   
## b   integer,10   integer,10   integer,10  
## c   numeric,10   numeric,10   numeric,10  
## d   character,26 character,26 character,26
## y.1 1            5            9           
## y.2 2            6            10          
## y.3 3            7            11          
## y.4 4            8            12
bind_array(input, along = 2L)
##   A            B            C            y.1 y.2 y.3
## a logical,3    logical,3    logical,3    1   5   9  
## b integer,10   integer,10   integer,10   2   6   10 
## c numeric,10   numeric,10   numeric,10   3   7   11 
## d character,26 character,26 character,26 4   8   12
bind_array(input, along = 3L) # bind on new dimension after last
## , , x
## 
##   A            B            C           
## a logical,3    logical,3    logical,3   
## b integer,10   integer,10   integer,10  
## c numeric,10   numeric,10   numeric,10  
## d character,26 character,26 character,26
## 
## , , y
## 
##   A B C 
## a 1 5 9 
## b 2 6 10
## c 3 7 11
## d 4 8 12

bind_array(input, along = 0L, TRUE) # binds on new dimension after last
## , , x
## 
##   A            B            C           
## a logical,3    logical,3    logical,3   
## b integer,10   integer,10   integer,10  
## c numeric,10   numeric,10   numeric,10  
## d character,26 character,26 character,26
## 
## , , y
## 
##   A B C 
## a 1 5 9 
## b 2 6 10
## c 3 7 11
## d 4 8 12
bind_array(input, along = 1L, TRUE) # binds on last dimension (i.e. columns)
##   A            B            C            y.1 y.2 y.3
## a logical,3    logical,3    logical,3    1   5   9  
## b integer,10   integer,10   integer,10   2   6   10 
## c numeric,10   numeric,10   numeric,10   3   7   11 
## d character,26 character,26 character,26 4   8   12
bind_array(input, along = 2L, TRUE)
##     A            B            C           
## a   logical,3    logical,3    logical,3   
## b   integer,10   integer,10   integer,10  
## c   numeric,10   numeric,10   numeric,10  
## d   character,26 character,26 character,26
## y.1 1            5            9           
## y.2 2            6            10          
## y.3 3            7            11          
## y.4 4            8            12
bind_array(input, along = 3L, TRUE) # bind on new dimension before first
## , , A
## 
##   a         b          c          d           
## x logical,3 integer,10 numeric,10 character,26
## y 1         2          3          4           
## 
## , , B
## 
##   a         b          c          d           
## x logical,3 integer,10 numeric,10 character,26
## y 5         6          7          8           
## 
## , , C
## 
##   a         b          c          d           
## x logical,3 integer,10 numeric,10 character,26
## y 9         10         11         12



# binding, with empty arrays ====
emptyarray <- array(numeric(0L), c(0L, 3L))
dimnames(emptyarray) <- list(NULL, paste("empty", 1:3))
print(emptyarray)
##      empty 1 empty 2 empty 3
input <- list(x = x, y = emptyarray)
bind_array(input, along = 1L, comnames_from = 2L) # row-bind
##   A            B            C           
## a logical,3    logical,3    logical,3   
## b integer,10   integer,10   integer,10  
## c numeric,10   numeric,10   numeric,10  
## d character,26 character,26 character,26



# Illustrating `name_along` ====
x <- array(1:20, c(5, 3), list(NULL, LETTERS[1:3]))
y <- array(-1:-20, c(5, 3))
z <- array(-1:-20, c(5, 3))

bind_array(list(a = x, b = y, z), 2L)
##      A  B  C b.1 b.2 b.3           
## [1,] 1  6 11  -1  -6 -11 -1  -6 -11
## [2,] 2  7 12  -2  -7 -12 -2  -7 -12
## [3,] 3  8 13  -3  -8 -13 -3  -8 -13
## [4,] 4  9 14  -4  -9 -14 -4  -9 -14
## [5,] 5 10 15  -5 -10 -15 -5 -10 -15
bind_array(list(x, y, z), 2L)
##      A  B  C                      
## [1,] 1  6 11 -1  -6 -11 -1  -6 -11
## [2,] 2  7 12 -2  -7 -12 -2  -7 -12
## [3,] 3  8 13 -3  -8 -13 -3  -8 -13
## [4,] 4  9 14 -4  -9 -14 -4  -9 -14
## [5,] 5 10 15 -5 -10 -15 -5 -10 -15
bind_array(list(a = unname(x), b = y, c = z), 2L)
##      a.1 a.2 a.3 b.1 b.2 b.3 c.1 c.2 c.3
## [1,]   1   6  11  -1  -6 -11  -1  -6 -11
## [2,]   2   7  12  -2  -7 -12  -2  -7 -12
## [3,]   3   8  13  -3  -8 -13  -3  -8 -13
## [4,]   4   9  14  -4  -9 -14  -4  -9 -14
## [5,]   5  10  15  -5 -10 -15  -5 -10 -15
bind_array(list(x, a = y, b = z), 2L)
##      A  B  C a.1 a.2 a.3 b.1 b.2 b.3
## [1,] 1  6 11  -1  -6 -11  -1  -6 -11
## [2,] 2  7 12  -2  -7 -12  -2  -7 -12
## [3,] 3  8 13  -3  -8 -13  -3  -8 -13
## [4,] 4  9 14  -4  -9 -14  -4  -9 -14
## [5,] 5 10 15  -5 -10 -15  -5 -10 -15
input <- list(x, y, z)
names(input) <- c("", NA, "")
bind_array(input, 2L)
##      A  B  C                      
## [1,] 1  6 11 -1  -6 -11 -1  -6 -11
## [2,] 2  7 12 -2  -7 -12 -2  -7 -12
## [3,] 3  8 13 -3  -8 -13 -3  -8 -13
## [4,] 4  9 14 -4  -9 -14 -4  -9 -14
## [5,] 5 10 15 -5 -10 -15 -5 -10 -15