which()
which(x, arr.ind = FALSE, useNames = TRUE) which() is a base R function that returns the indices of elements in a vector or array that are TRUE. It is essential for extracting positions of matching elements, making it a fundamental tool for data manipulation and conditional operations.
Syntax
which(x)
which(x, arr.ind = FALSE, useNames = TRUE)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
x | logical | required | A logical vector or array |
arr.ind | logical | FALSE | If TRUE, return array indices for matrices |
useNames | TRUE | logical | If TRUE, preserve names in the result |
Examples
Basic usage
x <- c(5, 12, 7, 8, 3)
# Find which elements are greater than 7
which(x > 7)
# [1] 2 4
Finding NA positions
which() paired with is.na() is the standard way to locate missing values in a vector. The is.na() function returns a logical vector where TRUE marks each NA position, and which() converts those boolean flags into explicit numeric indices. This pattern is common in data cleaning workflows where you need to inspect or replace specific missing entries before analysis.
y <- c(1, NA, 3, NA, 5)
# Find positions of NA values
which(is.na(y))
# [1] 2 4
Working with character vectors
Character matching with which() applies exact string comparison element by element. The expression words == "apple" produces a logical vector the same length as words, with TRUE at every position matching the target. which() then extracts those positions. For case-insensitive matching, wrap the comparison in tolower() or use grepl() with a regular expression inside which().
words <- c("apple", "banana", "cherry", "apple")
# Find positions of "apple"
which(words == "apple")
# [1] 1 4
Using with data frames
which() works naturally with data frame columns accessed via the $ operator, since column extraction yields a vector. The condition df$age > 28 returns a logical vector that which() converts into row indices. You can then pass those indices to df[idx, ] for subsetting, or use them directly for row-level operations such as labeling or filtering.
df <- data.frame(name = c("Alice", "Bob", "Charlie"), age = c(25, 30, 35))
# Find rows where age > 28
which(df$age > 28)
# [1] 2 3
Common patterns
Combining with subsetting
Using which() before subsetting with brackets is a two-step approach: first compute the indices, then extract the matching elements. This is marginally more verbose than direct logical indexing (values[values > 25]), but the intermediate index vector is useful when you need the positions for other purposes, such as labeling observations or updating multiple columns in a data frame simultaneously.
values <- c(10, 20, 30, 40, 50)
# Get indices first, then subset
idx <- which(values > 25)
values[idx]
# [1] 30 40 50
Finding first or last match
Extracting the first or last TRUE index from which() is a lightweight way to locate boundary matches without scanning the entire vector manually. which(z)[1] returns the index of the earliest TRUE, and which(z)[length(which(z))] returns the latest. For large vectors where only the first match matters, match(TRUE, z) is more efficient because it stops after finding the first TRUE, avoiding a full scan.
z <- c(FALSE, FALSE, TRUE, TRUE, FALSE)
# First TRUE position
which(z)[1]
# [1] 3
# Last TRUE position
which(z)[length(which(z))]
# [1] 4
Using with which.min and which.max
which.min() and which.max() are optimized convenience functions that find the position of the smallest or largest value in a numeric vector. They return only the first occurrence if there are ties. Internally, they loop through the input in C and update a running minimum or maximum, which is faster than constructing a full logical vector with x == min(x) and passing it to which().
numbers <- c(5, 2, 8, 1, 9)
# Find position of minimum
which.min(numbers)
# [1] 4
# Find position of maximum
which.max(numbers)
# [1] 5
which() in practice
which() converts a logical vector to the indices of its TRUE values. It is the inverse of logical indexing: x[which(condition)] and x[condition] produce the same subset, but which() explicitly materializes the index positions. Use which() when you need the positions themselves (e.g., to update specific elements, find adjacent elements, or report row numbers), and use logical indexing when you just need the subset.
which() ignores NA values in the input, NA positions are not included in the result, unlike logical indexing where NA positions produce NA in the output. This makes which() useful when the condition vector may contain NA and you want only the confirmed TRUE positions: df[which(df$x > 0), ] is safer than df[df$x > 0, ] when df$x may contain NA.
which.min(x) and which.max(x) return the index of the first minimum or maximum value, respectively. They are shorthand for which(x == min(x))[1] and which(x == max(x))[1], but faster because they stop searching after finding the first match.
which() with arr.ind = TRUE returns a matrix of multi-dimensional indices when the input is an array or matrix. which(m > 5, arr.ind = TRUE) gives the row and column positions of every element greater than 5, which is useful for sparse matrix operations or finding specific positions in a 2D grid.
which() returns the integer positions where the condition is TRUE. It ignores NA values, which(is.na(x)) finds the positions of NA elements. which.min() and which.max() return the position of the first minimum or maximum, respectively. Avoid using which() inside [ for subsetting when you only need a logical vector — x[x > 0] is simpler and equivalent to x[which(x > 0)].
See also
- which.max / which.min()
- match()Also,
which(is.na(x))is the idiomatic way to find the positions of NA values in a vector.which()returns integer positions, which can be used directly for subsetting:x[which(x > 0)]is equivalent tox[x > 0]but is marginally slower becausewhich()adds an extra step. The main use case forwhich()is when you need the positions themselves: to know which elements satisfy a condition, to find the first match withwhich(...)[1], or to get indices for modifying specific elements.which(arr.ind = TRUE)returns row/column indices for a matrix or higher-dimensional array.