rguides

length()

length(x)

The length() function returns the number of elements in a vector, the number of components in a list, or the length of a string. It is one of the most frequently used functions in R for determining the size of objects. You can also use length<- to assign a new length to an object, which is useful for truncating or extending vectors.

Syntax

length(x)
length(x) <- value

Parameters

ParameterTypeDefaultDescription
xany R objectN/AA vector, list, matrix, data frame, or other R object
valuenon-negative integerN/ANew length to assign (only when using length<-)

Examples

Basic usage with vectors

# Numeric vector
x <- c(1, 2, 3, 4, 5)
length(x)
# [1] 5

# Character vector
words <- c("apple", "banana", "cherry")
length(words)
# [1] 3

# Empty vector
empty <- character(0)
length(empty)
# [1] 0

length() treats each vector element independently regardless of type. For character vectors, each string counts as one element no matter how many characters it contains. An empty vector created with character(0) or numeric(0) always has length zero, making length(x) == 0 a clean test for emptiness that works uniformly across all atomic types.

Working with lists

my_list <- list(a = 1, b = 2, c = 3)
length(my_list)
# [1] 3

# Nested list
nested <- list(list(1, 2), list(3, 4, 5))
length(nested)
# [1] 2

When working with lists, length() counts only the top-level components. A list containing two inner lists has length 2, regardless of how many elements those inner lists contain. To find the length of each list element individually, use lengths() (with an “s”) which returns a vector of per-element lengths — a useful companion function when inspecting nested data structures.

Setting length

x <- 1:10
length(x)
# [1] 10

# Truncate to 5 elements
length(x) <- 5
x
# [1] 1 2 3 4 5

# Extend to 10 elements (fills with NA)
length(x) <- 10
x
# [1]  1  2  3  4  5 NA NA NA NA NA

The length<- replacement form modifies the object in place, which is rare among base R functions. When extending a vector beyond its current size, the newly created positions are filled with NA values of the appropriate type — NA_real_ for numeric vectors, NA_character_ for character vectors, and NA for logical vectors. This makes length<- a fast way to pre-allocate a vector before filling it with computed results.

Common patterns

Looping over elements:

for (i in 1:length(x)) {
  print(x[i])
}

Using 1:length(x) as the loop index works reliably when x has at least one element, but it fails silently when x is empty: 1:0 produces c(1, 0) instead of an empty sequence, causing the loop body to execute twice with unexpected indices. A safer alternative is seq_along(x), which returns integer(0) for an empty vector and produces no loop iterations at all.

Checking if a vector is empty:

if (length(x) == 0) {
  message("Vector is empty")
}

Checking emptiness with length(x) == 0 is idiomatic in R and works correctly with NULL input — length(NULL) returns 0 rather than throwing an error. This makes the pattern safe in functions that accept optional arguments with NULL defaults. The identical(x, numeric(0)) alternative is stricter but less general since it checks the type as well.

Dynamic vector growth (inefficient - pre-allocate instead):

result <- numeric(0)
for (i in 1:100) {
  length(result) <- i
  result[i] <- i^2
}

length() in practice

length() returns the number of elements at the top level of an object. For atomic vectors (numeric, character, logical), this is the count of elements. For lists, it is the count of top-level list elements, a nested list’s inner elements are not counted. For data frames, length() returns the number of columns, not rows, because a data frame is internally a list of column vectors. Use nrow() for row counts.

length(NULL) returns 0, which makes NULL a natural “empty” value that can be tested with length(x) == 0. For atomic vectors, length(x) == 0 is equivalent to identical(x, integer(0)) (or the appropriate empty type), but length() is more general since it works regardless of type.

length<- (the replacement form) resizes a vector. length(x) <- 10 extends or truncates x to 10 elements. Extension fills with NA; truncation discards the excess. This in-place resizing is rarely used but appears in performance-sensitive code where pre-allocation is needed.

For named objects like lists, names(x) and length(x) are always consistent: names(x) has exactly length(x) elements (or is NULL if unnamed). Checking length(x) before subscripting is a pattern for defensive programming: if (length(x) > 0) x[[1]] avoids subscript-out-of-bounds errors.

length() returns the number of elements at the top level. For a list, it counts list elements, not all nested values. For a data frame, it counts columns. nrow() and ncol() are more explicit for data frames. When checking if an object is empty, use length(x) == 0, this works for vectors, lists, and NULL. NROW() and NCOL() treat vectors as single-column matrices, making them useful in generic functions.

length() returns the number of top-level elements. For a vector, this is the number of elements. For a list, it counts list elements at the top level only, nested elements are not counted. For a data frame, length() returns the number of columns (not rows). For NULL, it returns 0.

NROW() and NCOL() treat vectors as single-column matrices, returning length(x) and 1 respectively. These variants are useful in generic functions that must handle both vectors and matrices.

To count nested elements in a list, use lengths(x) (note the plural) which returns the length of each element: lengths(list(c(1,2), c(3,4,5))) returns c(2, 3).

length(x) == 0 checks whether x is empty — this works for empty vectors (integer(0)), empty lists, and NULL. Prefer this over nrow(x) == 0 for vectors, since nrow() returns NULL rather than 0 for non-matrix objects, making it unreliable in generic contexts.

Using length() with logical indexing

# Count elements that meet a condition
temps <- c(22.5, 19.8, 25.1, 21.3, 18.9, 27.4, 20.0, 23.6)
warm_days <- sum(temps > 22)
warm_days
# [1] 4

# Verify: count matches length of filtered subset
stopifnot(warm_days == length(temps[temps > 22]))

A common pattern pairs length() with logical indexing to count how many elements satisfy a condition without storing the intermediate subset. The expression temps[temps > 22] creates a new vector containing only the entries above 22, and length() returns its size — four in this example. The equivalent sum(temps > 22) is more memory-efficient because it counts TRUE values directly without allocating a new vector, but length() combined with subsetting makes the filtering step explicit for code review.

See also