Indexing Arrays in R

basics
r-programming
Learn how to access and manipulate elements in vectors, matrices, and arrays in R
Published

March 30, 2025

Indexing Arrays in R

R provides powerful and flexible ways to access and manipulate elements in data structures like vectors, matrices, and arrays.

Vector Indexing

Vectors are one-dimensional arrays and the most basic data structure in R:

# Create a vector
x <- c(10, 20, 30, 40, 50)

# Access by position (indexing starts at 1, not 0)
x[1]        # First element
[1] 10
x[3]        # Third element
[1] 30
x[length(x)] # Last element
[1] 50
# Access multiple elements
x[c(1, 3, 5)]  # First, third, and fifth elements
[1] 10 30 50
x[1:3]         # First three elements
[1] 10 20 30
# Negative indices exclude elements
x[-2]          # All elements except the second
[1] 10 30 40 50
x[-(3:5)]      # All elements except third through fifth
[1] 10 20

Logical Indexing

You can use logical vectors to filter elements:

# Create a vector
ages <- c(25, 18, 45, 32, 16, 50)

# Filter using logical conditions
ages[ages > 30]         # Elements greater than 30
[1] 45 32 50
ages[ages >= 18 & ages <= 40]  # Elements between 18 and 40
[1] 25 18 32
# Named logical operations
adults <- ages >= 18
ages[adults]            # Only adult ages
[1] 25 18 45 32 50

Matrix Indexing

Matrices are two-dimensional arrays:

# Create a matrix
mat <- matrix(1:12, nrow = 3, ncol = 4)
print(mat)
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
# Access by row and column indices
mat[1, 2]      # Element at first row, second column
[1] 4
mat[2, ]       # Entire second row
[1]  2  5  8 11
mat[, 3]       # Entire third column
[1] 7 8 9
mat[1:2, 3:4]  # Submatrix (rows 1-2, columns 3-4)
     [,1] [,2]
[1,]    7   10
[2,]    8   11
# Logical indexing in matrices
mat[mat > 6]   # All elements greater than 6
[1]  7  8  9 10 11 12

Array Indexing

Arrays can have more than two dimensions:

# Create a 3D array (2x3x2)
arr <- array(1:12, dim = c(2, 3, 2))
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
# Access elements
arr[1, 2, 1]   # Element at position [1,2,1]
[1] 3
arr[, , 1]     # First "layer" of the array
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
arr[1, , ]     # All elements in first row across all layers
     [,1] [,2]
[1,]    1    7
[2,]    3    9
[3,]    5   11

Data Frame Indexing

Data frames combine features of matrices and lists:

# Create a data frame
df <- data.frame(
  name = c("Alice", "Bob", "Charlie", "David"),
  age = c(25, 30, 35, 40),
  score = c(88, 92, 79, 94)
)
print(df)
     name age score
1   Alice  25    88
2     Bob  30    92
3 Charlie  35    79
4   David  40    94
# Access by row and column indices (like matrices)
df[1, 2]       # First row, second column
[1] 25
df[2:3, ]      # Second and third rows
     name age score
2     Bob  30    92
3 Charlie  35    79
# Access by column name
df$name        # Name column
[1] "Alice"   "Bob"     "Charlie" "David"  
df[, "age"]    # Age column
[1] 25 30 35 40
df[["score"]]  # Score column
[1] 88 92 79 94
# Filter rows by condition
df[df$age > 30, ]  # Rows where age is greater than 30
     name age score
3 Charlie  35    79
4   David  40    94

List Indexing

Lists can contain elements of different types:

# Create a list
my_list <- list(
  name = "John",
  numbers = c(1, 2, 3),
  matrix = matrix(1:4, nrow = 2)
)
print(my_list)
$name
[1] "John"

$numbers
[1] 1 2 3

$matrix
     [,1] [,2]
[1,]    1    3
[2,]    2    4
# Access list elements
my_list[[1]]       # First element (by position)
[1] "John"
my_list[["name"]]  # Element by name
[1] "John"
my_list$numbers    # Element by name using $ notation
[1] 1 2 3
# Access nested elements
my_list$numbers[2]  # Second element of the numbers vector
[1] 2
my_list$matrix[1,2] # Element at row 1, column 2 of the matrix
[1] 3

Advanced Indexing Techniques

# Using which() for positional indexing from logical conditions
x <- c(5, 10, 15, 20, 25)
which(x > 15)  # Returns positions where condition is TRUE
[1] 4 5
# Using %in% for membership tests
fruits <- c("apple", "banana", "cherry", "date")
fruits %in% c("banana", "date", "fig")  # Tests which elements are in the second vector
[1] FALSE  TRUE FALSE  TRUE
fruits[fruits %in% c("banana", "date", "fig")]  # Select matching elements
[1] "banana" "date"  

Remember that R indexing starts at 1, not 0 as in many other programming languages. This is a common source of confusion for beginners coming from languages like Python or JavaScript.