Skip to contents

The bind_implementations provide dimensional binding functionalities.
When possible, the bind_ functions return mutable classes.

The following implementations are available:

  • bind_mat() binds dimensionless (atomic/recursive) vectors and (atomic/recursive) matrices row- or column-wise.
    If the result is atomic, returns a mutable_atomic matrix; otherwise returns a recursive matrix.

  • bind_array() binds (atomic/recursive) arrays and (atomic/recursive) matrices.
    If the result is atomic, returns a mutable_atomic array; otherwise returns a recursive array.

  • bind_dt() binds data.tables and other data.frame-like objects.
    Returns a data.table.
    Faster than do.call(cbind, ...) or do.call(rbind, ...) for regular data.frame objects.

Note that the naming convention of the binding implementations here is "bind_" followed by the resulting class (abbreviated).
I.e. bind_mat returns a matrix, but can bind both matrices and vectors.
And bind_array returns an array, but can bind both arrays and matrices.
And bind_dt returns a data.table, but can bind not only data.tables, but also most other data.frame-like objects.

Usage

bind_mat(arg.list, along, name_deparse = TRUE, comnames_from = 1L)

bind_array(
  arg.list,
  along,
  name_along = TRUE,
  comnames_from = 1L,
  name_flat = FALSE
)

bind_dt(arg.list, along, ...)

Arguments

arg.list

a list of only the appropriate objects.
If arg.list is named, its names will be used for the names of dimension along of the output, as far as possible.

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.
For arrays, additional flexibility is available:

  • 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 being the last available dimension, will create an additional dimension (n+1) and bind the arrays along that new dimension.

name_deparse

Boolean, for bind_mat().
Indicates if dimension along should be named.
Uses the naming method from rbind/cbind itself.

comnames_from

either integer scalar or NULL, for bind_mat() and bind_array().
Indicates which object in arg.list 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(arg.list[[10]]) for the rownames of the output.

name_along

Boolean, for bind_array().
Indicates if dimension along should be named.

name_flat

Boolean, for bind_array().
Indicates if flat indices should be named.
Note that setting this to TRUE will reduce performance considerably.
[for performance: set to FALSE]

...

arguments to be passed to rbindlist.

Value

The bound object.

Details

bind_array() is a modified version of the fantastic abind::abind function by Tony Plare & Richard Heiberger (2016), in the following ways:

  • bind_array() primarily differs from abind::abind in that it can handle recursive arrays properly
    (the original abind::abind function would unlist everything to atomic arrays, ruining the structure).

  • unlike abind::abind, bind_array() only binds (atomic/recursive) arrays and matrices.
    bind_array()does not attempt to convert things to arrays when they are not arrays, but will give an error instead.
    This saves computation time and prevents unexpected results.

  • if bind_array() results in an atomic array, it will be a mutable_atomic array.

  • bind_array() has more streamlined naming options.

bind_mat() is a modified version of rbind/cbind.
The primary differences is that bind_mat() gives an error when fractional recycling is attempted (like binding 1:3 with 1:10).

References

Plate T, Heiberger R (2016). abind: Combine Multidimensional Arrays. R package version 1.4-5, https://CRAN.R-project.org/package=abind.

Examples


# bind_array ====

# here, atomic and recursive matrices are mixed,
# resulting in a recursive matrix

# 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))
)
x <- matrix(x, 4, 3, byrow = TRUE)
dimnames(x) <- n(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

# binding the arrays
arg.list <- list(x = x, y = y)
bind_array(arg.list, 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(arg.list, along = 1L) # binds on first dimension
#>     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(arg.list, 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(arg.list, 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_mat ====

# here, atomic and recursive matrices are mixed,
# resulting in a recursive matrix

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))
)
x <- matrix(x, 4, 3, byrow = TRUE)
dimnames(x) <- n(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

bind_mat(n(x = x, y = y), 2L)
#>   A            B            C                  
#> 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_dt ====


x <- data.frame(a = 1:12, b = month.abb) # data.frame
y <- data.table::data.table(a = 1:12, b = month.abb) # data.table

bind_dt(n(x = x, y = y), 2L) # column bind
#>       x.a    x.b   y.a    y.b
#>     <int> <char> <int> <char>
#>  1:     1    Jan     1    Jan
#>  2:     2    Feb     2    Feb
#>  3:     3    Mar     3    Mar
#>  4:     4    Apr     4    Apr
#>  5:     5    May     5    May
#>  6:     6    Jun     6    Jun
#>  7:     7    Jul     7    Jul
#>  8:     8    Aug     8    Aug
#>  9:     9    Sep     9    Sep
#> 10:    10    Oct    10    Oct
#> 11:    11    Nov    11    Nov
#> 12:    12    Dec    12    Dec

bind_dt(n(x = x, y = y), 1L) # row bind
#>         a      b
#>     <int> <char>
#>  1:     1    Jan
#>  2:     2    Feb
#>  3:     3    Mar
#>  4:     4    Apr
#>  5:     5    May
#>  6:     6    Jun
#>  7:     7    Jul
#>  8:     8    Aug
#>  9:     9    Sep
#> 10:    10    Oct
#> 11:    11    Nov
#> 12:    12    Dec
#> 13:     1    Jan
#> 14:     2    Feb
#> 15:     3    Mar
#> 16:     4    Apr
#> 17:     5    May
#> 18:     6    Jun
#> 19:     7    Jul
#> 20:     8    Aug
#> 21:     9    Sep
#> 22:    10    Oct
#> 23:    11    Nov
#> 24:    12    Dec
#>         a      b