stringr str_pad() in R: Pad Strings to a Fixed Width
stringr str_pad() adds characters to each element of a character vector until it reaches a fixed width. It is vectorised, NA aware, and lets you pad on the left, right, or both sides, which makes it the standard tool for zero-padding IDs and aligning text into clean fixed-width columns.
str_pad("7", 3, pad = "0") # "007" pad left (default)
str_pad("R", 6) # " R" pad with spaces
str_pad("R", 6, side = "right") # "R " left-justify
str_pad("ab", 6, side = "both") # " ab " centre the text
str_pad(c("1", "22"), 4, pad = "0") # "0001" "0022" vectorised
str_pad("toolong", 3) # "toolong" never truncates
str_pad(NA, 5) # NA stays NA (NA-safe)
str_pad(id, 6, pad = "0") # zero-pad an ID columnNeed explanation? Read on for examples and pitfalls.
What str_pad() does in one sentence
str_pad(string, width, side, pad) returns a copy of the input grown to at least width characters by adding the pad character to one or both ends. It works element-wise on a character vector, propagates NA inputs as NA outputs, and never removes characters, so a string already wider than width comes back untouched.
Use str_pad() whenever values need a uniform length: zero-padded order numbers, right-aligned console output, or fixed-width export files. It is the natural counterpart to str_trim(), which strips whitespace rather than adding it.
Every element grows to five characters, the shorter values gain more zeros, and the NA input stays NA.
Syntax
str_pad(string, width, side = c("left", "right", "both"), pad = " ") takes four arguments. The first is the character vector to pad and the second is the target width. The side argument chooses where the padding goes, and pad sets the fill character. The default pads on the left with spaces.
Because str_pad() is vectorised, you can pad thousands of strings in one call, and width itself may be a vector to give each element a different target length.
Each label is padded on the right, so the text starts flush at the left edge and trailing spaces fill the rest.
Five common str_pad() scenarios
Five scenarios cover almost every real use of str_pad(). Each block stands alone so you can paste it into the live console.
Zero-pad numeric IDs to a fixed width
The most common use of str_pad() is giving IDs a uniform length. Pad with "0" so short numbers line up with long ones.
Every value becomes six characters wide, which keeps file names, keys, and report columns consistent.
Right-align text for a clean console table
Padding on the left right-aligns variable-length labels. This is the quickest way to line up a column of text in printed output.
Each string ends at the same column, so the values form a tidy right-aligned block.
Pad a column inside a data frame
Most padding happens inside a tidyverse pipeline. Combine str_pad() with mutate() to rewrite a column in place.
The new order_id column is fixed-width, which makes it safe to use as a join key or a sortable label.
Build fixed-width codes by combining with str_c
str_pad() pairs naturally with str_c() to assemble structured codes. Pad the numeric part first, then prefix it.
Each SKU has the same shape, which keeps catalogues and lookups predictable.
Centre text with a custom pad character
The "both" side and a custom pad character produce centred banners. Padding splits as evenly as possible across the two ends.
The seven-character input gains seven stars on each side to reach the requested width of 21.
c("2", "10", "1") as text gives "1" "10" "2" because "1" precedes "2" character by character. Pad to a common width first and the lexical order finally agrees with the numeric order, which is why padded IDs sort and join cleanly.str_pad() vs formatC() vs sprintf()
Three functions can zero-pad a value, but they target different jobs. Picking the wrong one usually shows up as a type error or an awkward format string.
| Function | Source | Any pad char | Best for |
|---|---|---|---|
str_pad(x, 4, pad = "0") |
stringr | yes | padding character vectors in pipelines |
formatC(x, width = 4, flag = "0") |
base R | no | numeric formatting with alignment flags |
sprintf("%04d", x) |
base R | no | precise numeric format strings |
Reach for str_pad() when the input is already character data or sits inside a dplyr pipeline, and use formatC() or sprintf() when you are formatting raw numbers and want number-specific control.
Common pitfalls
Three pitfalls cause most str_pad() surprises. Each has a one-line fix.
Expecting str_pad() to shorten long strings
str_pad() only ever adds characters; it never removes them. A string already wider than width passes through unchanged.
To cap a string at a maximum length instead, use str_trunc(), which shortens long values and adds an ellipsis.
Passing a multi-character pad value
The pad argument must be exactly one character. A longer string raises an error rather than repeating it.
Pick a single fill character such as "0", " ", or "*". To build a repeated multi-character prefix, use str_dup() and str_c() instead.
Misreading width as the number of pad characters
width is the total target length, not the count of characters to add. str_pad("hi", 3) adds only one space, because "hi" is already two characters wide.
Set width to the final length you want each element to reach, and str_pad() works out how much padding each value needs.
as.character() before padding, or wrap the result with as.factor() when you need to keep factor levels.Try it yourself
Try it: The vector c("4", "58", "300") holds room numbers. Pad every element with zeros to a width of 4 and save the result to ex_rooms.
Click to reveal solution
Explanation: str_pad() with pad = "0" and the default side = "left" adds enough leading zeros to make every element four characters wide, so the room numbers line up as a fixed-width column.
Related stringr functions
When str_pad() is not quite what you need, these are the next stops:
- str_trunc() does the opposite job, shortening strings that exceed a maximum length.
- str_trim() removes leading and trailing whitespace instead of adding padding.
- str_dup() repeats a string a fixed number of times, useful for building separators.
- str_c() joins strings end to end, often paired with str_pad() to assemble codes.
- str_length() counts characters, which helps you choose the right
width. - The full stringr reference documents str_pad() and its arguments.
FAQ
How do I pad a number with leading zeros in R?
Convert the number to a character vector and call str_pad() with pad = "0": str_pad(as.character(7), width = 4, pad = "0") returns "0007". The default side = "left" puts the zeros in front, which is what you want for IDs and codes. Because str_pad() is vectorised, the same call zero-pads a whole vector of numbers at once.
What is the difference between str_pad() and formatC()?
Both can zero-pad values to a fixed width. str_pad() comes from stringr, works on character vectors, and accepts any single pad character. formatC() is base R, is designed for formatting numbers, and only pads with spaces or zeros. Use str_pad() for text data and formatC() for raw numeric values.
Does str_pad() truncate strings that are too long?
No. str_pad() only ever adds characters, so a string already longer than width is returned unchanged. The width argument sets a minimum length, not a maximum. To shorten long strings to a fixed length, use str_trunc() instead.
How do I pad a string on the right side in R?
Set the side argument to "right": str_pad("R", width = 8, side = "right") returns "R ". Right-side padding leaves the text flush at the left edge and adds the fill characters after it, which left-aligns a column. The default side = "left" does the reverse and right-aligns text, and side = "both" centres it by splitting the padding across the two ends.
Can str_pad() pad with a character other than a space?
Yes. The pad argument accepts any single character, so str_pad("7", 4, pad = "0") pads with zeros and str_pad(" hi ", 9, side = "both", pad = "*") pads with asterisks. The only rule is that pad must be exactly one character; a multi-character value raises an error. To build a repeated multi-character prefix or suffix, combine str_dup() with str_c() instead of str_pad().