Arrays in Action

Multi-Dimensional Arrays in R: A Complete Guide

Author

Raju Rimal

Published

December 2, 2024

Modified

March 19, 2025

In R, multi-dimensional arrays are powerful data structures that extend matrices to higher dimensions, enabling more complex data representations and operations. This blog post explores everything about arrays, including their creation, manipulation, and common operations. We’ll also cover advanced tools like the abind package and purrr functions for converting lists to arrays.


What Is a Multi-Dimensional Array?

An array in R is a multi-dimensional data structure where all elements are of the same type. While matrices are limited to two dimensions (rows and columns), arrays can have three or more dimensions, making them ideal for storing higher-dimensional data like tensors or cubes.


Creating Arrays in R

1. Using the array() Function

The array() function creates multi-dimensional arrays by specifying dimensions.

# Create a 3D array
arr <- array(1:24, dim = c(3, 4, 2))  # 3 rows, 4 columns, 2 layers
print(arr)
, , 1

     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

, , 2

     [,1] [,2] [,3] [,4]
[1,]   13   16   19   22
[2,]   14   17   20   23
[3,]   15   18   21   24

2. Specifying Dimension Names

You can name the dimensions of an array for better readability.

dimnames <- list(
  Row = c("R1", "R2", "R3"),
  Column = c("C1", "C2", "C3", "C4"),
  Layer = c("L1", "L2")
)
arr_named <- array(1:24, dim = c(3, 4, 2), dimnames = dimnames)
print(arr_named)
, , Layer = L1

    Column
Row  C1 C2 C3 C4
  R1  1  4  7 10
  R2  2  5  8 11
  R3  3  6  9 12

, , Layer = L2

    Column
Row  C1 C2 C3 C4
  R1 13 16 19 22
  R2 14 17 20 23
  R3 15 18 21 24

3. Converting a Matrix to an Array

mat <- matrix(1:12, nrow = 3)
arr <- array(mat, dim = c(2, 3, 2))  # Add a third dimension
print(arr)
, , 1

     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

, , 2

     [,1] [,2] [,3]
[1,]    7    9   11
[2,]    8   10   12

Accessing and Modifying Array Elements

1. Access Specific Elements

Access elements using indices for all dimensions.

# Access element in row 2, column 3, layer 1
arr[2, 3, 1]
[1] 6

2. Access Entire Slices

Extract a specific row, column, or layer using empty indices (NULL).

# Extract the 1st layer
arr[, , 1]
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
# Extract the 2nd column from all layers
arr[, 2, ]
     [,1] [,2]
[1,]    3    9
[2,]    4   10
# Extract the 3rd row from the 2nd layer
arr[2, , 2]
[1]  8 10 12

3. Modify Elements

arr[1, 2, 1] <- 100  # Set element at [1, 2, 1] to 100
arr
, , 1

     [,1] [,2] [,3]
[1,]    1  100    5
[2,]    2    4    6

, , 2

     [,1] [,2] [,3]
[1,]    7    9   11
[2,]    8   10   12

Basic Array Operations

1. Arithmetic Operations

Perform element-wise operations on arrays.

arr2 <- array(1:12, dim = c(2, 3, 2))

# Addition
(result <- arr + arr2)
, , 1

     [,1] [,2] [,3]
[1,]    2  103   10
[2,]    4    8   12

, , 2

     [,1] [,2] [,3]
[1,]   14   18   22
[2,]   16   20   24
# Multiplication
(result <- arr * arr2)
, , 1

     [,1] [,2] [,3]
[1,]    1  300   25
[2,]    4   16   36

, , 2

     [,1] [,2] [,3]
[1,]   49   81  121
[2,]   64  100  144

2. Array Transposition

Use aperm() to reorder array dimensions.

# Swap the first and third dimensions
transposed <- aperm(arr, c(3, 2, 1))
transposed
, , 1

     [,1] [,2] [,3]
[1,]    1  100    5
[2,]    7    9   11

, , 2

     [,1] [,2] [,3]
[1,]    2    4    6
[2,]    8   10   12

3. Summarize Along Dimensions

Use apply() to compute summaries along specific dimensions.

# Sum across layers (dimension 3)
apply(arr, c(1, 2), sum)
     [,1] [,2] [,3]
[1,]    8  109   16
[2,]   10   14   18
# Mean across rows (dimension 1)
apply(arr, c(2, 3), mean)
     [,1] [,2]
[1,]  1.5  7.5
[2,] 52.0  9.5
[3,]  5.5 11.5

Combining Arrays with abind

The abind package allows you to combine arrays along specified dimensions.

1. Installing and Loading abind

# install.packages("abind")
library(abind)

2. Combine Arrays Along a Dimension

arr1 <- array(1:12, dim = c(3, 4, 1))
arr2 <- array(13:24, dim = c(3, 4, 1))

# Combine along the 3rd dimension
combined <- abind(arr1, arr2, along = 3)
print(combined)
, , 1

     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

, , 2

     [,1] [,2] [,3] [,4]
[1,]   13   16   19   22
[2,]   14   17   20   23
[3,]   15   18   21   24

Converting a List to an Array with purrr

The purrr package provides a convenient way to convert lists into arrays.

1. Installing and Loading purrr

# install.packages("purrr")
library(purrr)

2. Using array_branch() and array_tree()

  • array_branch(): Split an array into a list.
  • array_tree(): Create an array from a nested list.
# Create an array
arr <- array(1:12, dim = c(2, 4, 3))

# Convert the list to a 3D array
purrr::array_tree(arr, margin = c(1)) %>% str()
List of 2
 $ : int [1:4, 1:3] 1 3 5 7 9 11 1 3 5 7 ...
 $ : int [1:4, 1:3] 2 4 6 8 10 12 2 4 6 8 ...
purrr::array_tree(arr, margin = c(2)) %>% str()
List of 4
 $ : int [1:2, 1:3] 1 2 9 10 5 6
 $ : int [1:2, 1:3] 3 4 11 12 7 8
 $ : int [1:2, 1:3] 5 6 1 2 9 10
 $ : int [1:2, 1:3] 7 8 3 4 11 12
purrr::array_tree(arr, margin = c(3)) %>% str()
List of 3
 $ : int [1:2, 1:4] 1 2 3 4 5 6 7 8
 $ : int [1:2, 1:4] 9 10 11 12 1 2 3 4
 $ : int [1:2, 1:4] 5 6 7 8 9 10 11 12
purrr::array_tree(arr, margin = c(1, 3)) %>% str()
List of 2
 $ :List of 3
  ..$ : int [1:4] 1 3 5 7
  ..$ : int [1:4] 9 11 1 3
  ..$ : int [1:4] 5 7 9 11
 $ :List of 3
  ..$ : int [1:4] 2 4 6 8
  ..$ : int [1:4] 10 12 2 4
  ..$ : int [1:4] 6 8 10 12
purrr::array_tree(arr, margin = 2:3) %>% str()
List of 4
 $ :List of 3
  ..$ : int [1:2] 1 2
  ..$ : int [1:2] 9 10
  ..$ : int [1:2] 5 6
 $ :List of 3
  ..$ : int [1:2] 3 4
  ..$ : int [1:2] 11 12
  ..$ : int [1:2] 7 8
 $ :List of 3
  ..$ : int [1:2] 5 6
  ..$ : int [1:2] 1 2
  ..$ : int [1:2] 9 10
 $ :List of 3
  ..$ : int [1:2] 7 8
  ..$ : int [1:2] 3 4
  ..$ : int [1:2] 11 12

Advanced Array Functions

1. Reshaping an Array

You can reshape arrays by modifying their dimensions.

arr2 <- arr

# Reshape a 2x3x4 array into a 4x6 array
dim(arr2) <- c(4, 6)
arr2
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    5    9    1    5    9
[2,]    2    6   10    2    6   10
[3,]    3    7   11    3    7   11
[4,]    4    8   12    4    8   12

2. Slicing Arrays

Extract subsets of an array using [ and logical indices.

# Extract elements greater than 10
subset <- arr[arr > 10]

3. Apply Custom Functions

Use lapply() or apply() for custom operations along dimensions.

# Apply a custom function along layers
apply(arr, c(1, 2), function(x) sum(x))
     [,1] [,2] [,3] [,4]
[1,]   15   21   15   21
[2,]   18   24   18   24

Practical Applications of Arrays

1. Storing Multi-Channel Images

Arrays are often used to represent images, where each layer corresponds to a color channel (e.g., RGB).

2. Statistical Models

Arrays can store results of statistical simulations across multiple dimensions.

3. Tensor Manipulation in Machine Learning

Arrays act as tensors in deep learning frameworks, holding data for multi-dimensional computations.


Best Practices for Arrays

  1. Use Meaningful Dimension Names: Always name dimensions for better interpretation.
  2. Check Dimensions Regularly: Use dim() to ensure compatibility during operations.
  3. Explore Libraries: Packages like abind and purrr simplify complex array tasks.

Conclusion

Multi-dimensional arrays in R are versatile tools for handling complex data structures. By mastering array creation, manipulation, and operations, you can effectively manage high-dimensional data. Explore advanced features like the abind package for combining arrays and purrr functions for list conversions to unlock their full potential.