substr()

substr(x, start, stop)
Returns: character · Updated March 13, 2026 · Base Functions
substr substring strings text base

substr() is a base R function that extracts or replaces substrings from a character vector using 1-indexed positions. Unlike substring(), which uses start and stop positions, substr() requires both boundaries to be explicitly specified.

Signature

substr(x, start, stop)
substr(x, start, stop) <- value

Parameters

ParameterTypeDefaultDescription
xcharacterA character vector
startintegerStarting position (1-indexed)
stopintegerEnding position (1-indexed)
valuecharacterReplacement string (for assignment)

Return Value

Returns a character vector of the same length as x with the extracted or replaced substring.

Key Differences: substr() vs substring()

  • 1-indexed: Both use 1-based indexing (first character is position 1)
  • Parameters: substr(x, start, stop) vs substring(x, first, last = Inf)
  • substring() default: When last is omitted, substring() goes to the end of the string
  • substr() requirement: Both start and stop must be provided

Examples

Example 1: Basic String Extraction

# Extract characters from position 2 to 4
x <- "abcdefg"
substr(x, 2, 4)
[1] "bcd"
# First character
substr(x, 1, 1)
[1] "a"
# Last three characters
substr(x, 5, 7)
[1] "efg"

Example 2: Out-of-Bounds Behavior

# Start beyond string length returns empty string
x <- "hello"
substr(x, 10, 15)
[1] ""
# Stop beyond string length is silently truncated to string end
substr(x, 2, 100)
[1] "ello"
# Start > Stop returns empty string
substr(x, 5, 2)
[1] ""
# Negative indices are treated as 1
substr(x, -1, 3)
[1] "abc"

Example 3: String Replacement with Assignment

# Replace substring on left-hand side of <-
x <- "abcdef"
substr(x, 2, 4) <- "XXX"
x
[1] "aXXXef"
# Works with vectors
words <- c("apple", "banana", "cherry")
substr(words, 1, 2) <- "XX"
words
[1] "XXple"   "XXnana"  "XXerry"
# Replacement longer than substring length (fills from start)
x <- "abcdef"
substr(x, 2, 3) <- "MMMMM"
x
[1] "aMMMMMdef"
# Replacement shorter than substring length
x <- "abcdef"
substr(x, 2, 4) <- "X"
x
[1] "aXef"

Example 4: Comparison with substring()

# substr() requires both start and stop
x <- "abcdef"
substr(x, 2, 6)
[1] "bcdef"
# substring() can use just start (goes to end)
substring(x, 2)
[1] "bcdef"
# Both handle vectors the same way
strings <- c("first", "second", "third")
substr(strings, 2, 4)
substring(strings, 2, 4)
[1] "irs" "eco" "hir"
[1] "irs" "eco" "hir"
# Key difference: substring with one arg goes to end
substring(x, 3)
substr(x, 3, nchar(x))  # equivalent
[1] "cdef"
[1] "cdef"

Common Patterns

Character-by-character processing:

# Replace first character of each string
names <- c("apple", "banana", "cherry")
substr(names, 1, 1) <- toupper(substr(names, 1, 1))
names
[1] "Apple"   "Banana"  "Cherry"

Masking sensitive data:

# Mask middle of credit card number
card <- "1234-5678-9012-3456"
substr(card, 9, 20) <- "XXXX-XXXX-XXXX"
card
[1] "1234-5678-XXXX-XXXX"

See Also