Written and maintained by CASRAI Editorial Board
Last updated
To concatenate strings in R, use paste0() to join values with nothing between them, paste() to join them with a separator (a space by default), or the collapse argument to fold a whole vector into one string. The tidyverse offers str_c() in stringr and glue() in the glue package. They look interchangeable, but they treat missing values and empty inputs differently, and that difference is where most silent errors in data-cleaning scripts come from. This guide covers the tasks first, then a side-by-side table of those edge cases.
What it is used for in research
Researchers concatenate strings constantly when preparing data: building a participant or sample ID from a site code and a number, assembling a label for a plot axis, creating a file name for each run of an analysis, or combining a first and last name into one column. Because the result often becomes a key used to merge data sets, an unnoticed "NA" or a dropped row in a joined string can corrupt a later step. Careful string handling is part of keeping an analysis reproducible. If you need to collapse many rows into one string, see the separate guide on collapse in R.
Install or access (official source only)
paste() and paste0() are part of base R, so nothing needs installing. They are documented in the base R manual page for paste. str_c() comes from the stringr package and glue() from the glue package; both are released on CRAN and are installed and loaded in the usual way:
install.packages(c("stringr", "glue"))
library(stringr)
library(glue)
Step-by-step task
1. Join values with no separator: paste0()
paste0() is paste() with sep = ""; the R documentation describes it as slightly more efficient. Arguments are converted with as.character and joined element by element.
paste0("site", 1:3)
# "site1" "site2" "site3"
2. Join values with a separator: paste()
The usage is paste(..., sep = " ", collapse = NULL, recycle0 = FALSE). Set sep to choose what goes between the pieces.
paste("Letter", "A", sep = ": ")
# "Letter: A"
3. Fold a vector into one string: collapse
The two arguments do different jobs. sep goes between the arguments you pass, element by element, and returns a vector. collapse then joins that vector into a single string. Per the documentation, if collapse is a string the result is always a single string.
paste0(c("a", "b", "c"), collapse = "")
# "abc"
4. The stringr equivalent: str_c()
The usage is str_c(..., sep = "", collapse = NULL). Its own page examples include str_c(letters, collapse = ""), which returns the 26 letters as one string, and str_c("Letter", letters, sep = ": "). The stringr documentation notes that for collapsing it is generally better to use str_flatten().
5. Insert values inside a template: glue()
With glue(), expressions inside braces are evaluated as R code and spliced into the text. The separator argument .sep defaults to "". For a data frame, glue_data() returns one string per row. Doubled braces produce literal braces.
Output and how to read it
A call without collapse returns a character vector with one element per input position; with a string collapse you get exactly one element. Two results need a second look every time: the literal text "NA", and character(0), an empty vector. Both are explained in the next sections.
How paste0(), str_c() and glue() differ on edge cases
The comparison below uses the behaviour documented on the base R, stringr and glue reference pages.
| Situation | paste0() | str_c() | glue() |
|---|---|---|---|
| A missing value (NA) | NA is coerced to the text “NA”: paste0(c("a", NA, "b"), "-d") gives “a-d” “NA-d” “b-d” |
Any string combined with a missing value is missing: the same input gives “a-d” NA “b-d” | .na defaults to “NA”; set it to NULL so NA propagates |
| A zero-length input | paste0("x", character()) returns “x” |
str_c("x", character()) returns character(0) |
.null defaults to character(), making the whole output character(0); set it to NULL to drop the input as paste0 does |
| Unequal lengths | paste0(1:2, 1:3) recycles and returns “11” “22” “13” |
str_c(1:2, 1:3) raises an error (tidyverse recycling rules) |
Not applicable: values are inserted by name inside the template |
The stringr documentation recommends str_replace_na() or dplyr::coalesce() when you want a missing value to show up as text rather than make the whole result missing.
Troubleshooting
“NA” appears inside my strings
Base paste() and paste0() convert a missing value to the text “NA”, so an ID such as "NA-d" can slip into a merge key. Either remove or recode missing values before joining, or switch to str_c(), which returns a missing value instead so the problem is visible.
I got a longer vector than I expected
Base R recycles shorter inputs against longer ones without complaint, which is how paste0(1:2, 1:3) returns three elements. If your inputs should be the same length, str_c() will stop with an error and tell you.
An empty column produced “x” or character(0)
The documentation states that zero-length arguments are recycled as "" unless recycle0 = TRUE and collapse is NULL. If all inputs are zero-length, the result has length zero, unless collapse is non-NULL, in which case it is "". Setting recycle0 = TRUE makes paste() return a zero-length result for an empty input instead of a stray “x”.
sep or collapse gives an error
Neither sep nor collapse can be NA in paste(); pass a string.
Free alternatives (table)
All three approaches are free and open source; the choice is about behaviour, not cost.
| Function | Where it comes from | Use it when |
|---|---|---|
paste() / paste0() |
Base R, no install | You want no dependencies and are happy with NA becoming “NA” |
str_c() |
stringr, from CRAN | You want missing values to stay missing and mismatched lengths to raise an error |
glue() / glue_data() |
glue, from CRAN | You are filling a text template from variables or from each row of a data frame |
Joined strings are often used as labels in graphics; see ggplot colour options and plotting a line in R. Once your IDs and labels are built, a typical next step is modelling; see logistic regression in R.
FAQ
How do I concatenate strings in R?
Use paste0("a", "b") for no separator, or paste("a", "b", sep = "-") for a chosen separator. Both are base R.
How do I concatenate a string in R with a vector?
Pass the string and the vector together: paste0("site", 1:3) returns one result per element because the single string is recycled. Add collapse if you want one combined string instead.
What is the difference between paste() and paste0()?
paste0() is paste(..., sep = ""), so it has no separator argument and is documented as slightly more efficient. paste() separates items with a space unless you set sep.
What is the difference between sep and collapse?
sep joins the arguments element by element; collapse joins the resulting elements into one string.
Should I use paste0() or str_c()?
Use paste0() when you need no package and NA as text is acceptable. Use str_c() when a missing value should make the result missing, or when you want unequal lengths to raise an error.
Sources (official docs)
- R documentation: paste (base R, R-devel manual), checked 2026-10-29
- stringr reference: str_c(), checked 2026-10-29
- glue reference: glue(), checked 2026-10-29







