Skip to main content
v2026.11,858 entries · CC-BY 4.0

Concatenate in R: paste(), paste0(), str_c() and glue()

How to concatenate strings in R with paste(), paste0(), str_c() and glue(), and how each handles NA, zero-length input and recycling.

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)

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about Concatenate in R: paste(), paste0(), str_c() and glue()

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →