rguides

max()

max(..., na.rm = FALSE, na.last = TRUE, type = c("ordinary", "ordered"))

max() returns the maximum value of its arguments. It is among the most frequently used functions for exploratory data analysis and statistical summaries.

Syntax

max(..., na.rm = FALSE, na.last = TRUE, type = c("ordinary", "ordered"))

Parameters

ParameterTypeDefaultDescription
...numeric,One or more vectors, or atomic values. Multiple arguments are combined element-wise.
na.rmlogicalFALSEIf TRUE, NA values are removed before computing the result.
na.lastlogicalTRUEFor na.rm = FALSE, controls where NA is placed in the output.
typecharacter"ordinary"Either "ordinary" for standard comparison, or "ordered" for ordered factors.

Examples

Basic usage

x <- c(3, 1, 4, 1, 5, 9, 2, 6)
max(x)
# [1] 9

Calling max() on a single numeric vector returns the largest element, which is the most common use in exploratory analysis. The function scans the entire vector in one pass through compiled C code, so it is fast even on large inputs. A subtle point: if the vector contains NA values and na.rm is left at its default of FALSE, the result will be NA — this is R’s conservative default of not silently discarding missing data. Always check for NA values with anyNA(x) before relying on the maximum.

Multiple arguments

max(1, 2, 3, 4, 5)
# [1] 5

max(c(1, 2), c(3, 4), 5)
# [1] 5

When max() receives multiple arguments, it concatenates them internally before finding the maximum. max(1, 2, 3, 4, 5) is equivalent to max(c(1, 2, 3, 4, 5)) — both return 5. But the multi-argument form is more readable when comparing a handful of named scalars, such as max(mean_a, mean_b, mean_c) in a report script. For element-wise maximum across two vectors of equal length, use pmax(), not max(): pmax(c(1, 5), c(3, 2)) returns c(3, 5), comparing position by position.

Handling missing values

y <- c(1, 2, NA, 4, 5)

max(y)
# [1] NA

max(y, na.rm = TRUE)
# [1] 5

The na.rm = TRUE argument is the standard way to compute a summary statistic in the presence of missing data. Without it, max(c(1, 2, NA, 4, 5)) returns NA, following R’s principle that operations on unknown values produce unknown results. With na.rm = TRUE, the NA entries are stripped before the maximum is computed, returning 5. This pattern is consistent across min(), mean(), sum(), and most other summary functions in base R, making it easy to remember once you have used it a few times.

With different data types

# Character vectors (uses alphabetical order)
chars <- c("apple", "banana", "cherry")
max(chars)
# [1] "cherry"

# Logical vectors (TRUE = 1, FALSE = 0)
max(c(TRUE, FALSE, TRUE, FALSE))
# [1] 1

max() works on character vectors by comparing them in alphabetical order, so max(c("apple", "banana", "cherry")) returns "cherry". For logical vectors, TRUE is treated as 1 and FALSE as 0, making max(c(TRUE, FALSE)) return TRUE. This coercion behavior is convenient but can mask type errors — a vector that you thought was numeric but actually contains strings will silently produce alphabetical results. Consider adding a type assertion before calling max() on data from external sources.

Common patterns

Finding the range of a vector

data <- c(3, 1, 4, 1, 5, 9, 2, 6)
range_val <- range(data)
range_val
# [1] 1 9

max(data) - min(data)
# [1] 8

The range() function returns a two-element vector c(min, max), which is a convenient shortcut when you need both extremes. Subtracting min(data) from max(data) gives the total spread, equivalent to diff(range(data)). For data visualization, range() is often used to set axis limits: xlim = range(data) ensures the plot covers the full extent of the data. With na.rm = TRUE, range() handles missing values the same way max() and min() do individually.

Identifying which element is max

scores <- c(85, 92, 78, 91, 88)
which.max(scores)
# [1] 2

# Get the actual value
scores[which.max(scores)]
# [1] 92

which.max() returns the index of the first occurrence of the maximum value, which is useful when you need to look up the corresponding row in a data frame: df[which.max(df$score), ] returns the full row for the highest score. The value itself is then scores[which.max(scores)], though max(scores) is simpler when you only need the numeric answer. Once you have identified extreme values, a common next step is to rescale the data to a fixed range, as shown below.

Normalizing by scaling to 0-1

values <- c(10, 20, 30, 40, 50)

scaled <- (values - min(values)) / (max(values) - min(values))
scaled
# [1] 0.00 0.25 0.50 0.75 1.00

max() and min() in practice

max() returns the largest value across all of its arguments. It accepts multiple vectors or scalars: max(a, b, c) returns the single largest value across all three. For computing the element-wise maximum of two vectors (each position independently), use pmax(a, b) instead, pmax(c(1,5), c(3,2)) returns c(3,5).

max() returns -Inf when called on an empty vector, with a warning. This makes it safe to use in reductions where the input might be empty: max(integer(0)) returns -Inf rather than raising an error. The corresponding identity holds: max(c(-Inf, x)) always equals max(x), since -Inf is less than any finite value.

With na.rm = TRUE, max() ignores NA values. Without it, any NA in the input produces NA output. For computing per-group maxima, tapply(x, groups, max) or dplyr::summarise(group_by(df, group), m = max(col)) are the standard approaches.

which.max(x) returns the index of the first maximum value, not the maximum itself. This is useful when you need the position of the maximum (e.g., to look up the corresponding row in a data frame) rather than the value.

max() with na.rm = FALSE (default) returns NA if any element is NA. Called on an empty vector, it returns -Inf with a warning, the identity element for the max operation. pmax(x, y) computes element-wise maximum between two vectors, equivalent to ifelse(x > y, x, y) but faster and handles NA correctly with the na.rm argument. For the position of the maximum, use which.max().

max() with multiple arguments

max() accepts multiple arguments in addition to a vector. max(a, b, c) returns the maximum of all three, whether they are scalars or vectors. When called with multiple vector arguments, it returns the overall maximum across all elements of all vectors, equivalent to max(c(a, b, c)). For element-wise maximum (comparing position by position), use pmax(), which is the parallel maximum.

pmax(a, b) returns a vector where each element is the maximum of the corresponding elements of a and b. This is the vectorized version useful for clamping values at a minimum or maximum threshold: pmax(values, 0) replaces negative values with zero, keeping positive values unchanged.

Finding the row with extreme values in a data frame

# Using which.max() to extract the full row
scores <- data.frame(
  name = c("Alice", "Bob", "Charlie", "Diana", "Eve"),
  score = c(88, 92, 79, 95, 84)
)

# Get the full row for the highest score
scores[which.max(scores$score), ]
#    name score
# 4 Diana    95

# Top 3 scores: sort descending and take first rows
scores[order(scores$score, decreasing = TRUE), ][1:3, ]
#      name score
# 4   Diana    95
# 2     Bob    92
# 1   Alice    88

which.max() returns the position of the largest value, which makes it the natural choice for row extraction — pass the index directly to the data frame brackets and you get back the full record in one line. For selecting the top n records rather than just the maximum, order() with decreasing = TRUE sorts the entire data frame by the score column, after which you subset the first three rows. The dplyr equivalent, slice_max(scores, score, n = 3), handles ties explicitly via the with_ties argument.

See also

  • min()
  • mean()
  • range()
  • which.max / which.min()pmax(x, y) computes the element-wise maximum. pmax(x, 0) is the rectified linear unit (ReLU) operation used in neural networks — it replaces negative values with zero. For finding the row or column maximum of a matrix: apply(m, 1, max) gives row maxima; apply(m, 2, max) gives column maxima. matrixStats::rowMaxs() and colMaxs() are faster C implementations. The which.max() function returns the position of the maximum.