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
| Parameter | Type | Default | Description |
|---|---|---|---|
x | character | — | A character vector |
start | integer | — | Starting position (1-indexed) |
stop | integer | — | Ending position (1-indexed) |
value | character | — | Replacement 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)vssubstring(x, first, last = Inf) substring()default: Whenlastis omitted,substring()goes to the end of the stringsubstr()requirement: Bothstartandstopmust 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"