rguides

paste0()

paste0(..., collapse = NULL)

paste0() concatenates strings end-to-end, unlike paste() which inserts a space by default. It’s the fastest way to join strings in R when you don’t need a separator.

Syntax

paste0(..., collapse = NULL)

Parameters

ParameterTypeDefaultDescription
...any,Objects to convert to character and concatenate
collapsecharacterNULLOptional string to collapse the result into a single string

Examples

Basic usage

# No separator between elements
paste0("Hello", "World")
# [1] "HelloWorld"

# Multiple strings
paste0("a", "b", "c")
# [1] "abc"

paste0() accepts any number of arguments and converts each to character before joining. The conversion uses as.character() internally, so numeric values, logicals, and factors are all handled automatically. Unlike paste(), no separator is inserted — characters are joined directly, making paste0() the idiomatic choice when constructing identifiers, file names, or any string where adjacent characters should touch without whitespace between them.

Combining with vectors

# Vectorized - recycles shorter vectors
prefix <- "file"
nums <- 1:3
paste0(prefix, nums)
# [1] "file1" "file2" "file3"

# Collapse into single string
files <- c("data.csv", "model.rds", "output.png")
paste0(files, collapse = ", ")
# [1] "data.csv, model.rds, output.png"

The collapse argument controls whether paste0() returns a character vector (when collapse = NULL, the default) or a single string (when collapse is set to a delimiter). Vectorized concatenation without collapsing is the more common use case, producing one output string per set of inputs. Collapsing is useful for joining an existing character vector into a single delimited string for display, logging, or constructing SQL IN clauses with comma-separated values.

Creating names dynamically

# Generate column names
cols <- c("age", "score", "rank")
paste0(cols, "_new")
# [1] "age_new" "score_new" "rank_new"

# Create file paths
folder <- "output/"
file <- "results"
ext <- ".csv"
paste0(folder, file, ext)
# [1] "output/results.csv"

Generating names programmatically with paste0() is a common pattern in data analysis workflows where you need to create column names for transformed variables, construct file paths from directory and filename components, or build identifier strings from prefixes and numeric suffixes. For file path construction specifically, consider using file.path() instead — it handles platform-specific path separators and normalizes slashes automatically, making your code portable across Windows, macOS, and Linux.

Common patterns

Building SQL queries:

table <- "users"
col <- "name"
query <- paste0("SELECT ", col, " FROM ", table)

Building SQL by pasting strings is convenient for quick scripts but dangerous in production code — if col or table comes from user input, the resulting query is vulnerable to SQL injection. For database work, use the DBI package with parameterized queries (dbBind() or sqlInterpolate()) instead. The example above is safe only when both variables contain hardcoded, trusted values from within your own script.

Dynamic variable names:

prefix <- "result"
for (i in 1:3) {
  assign(paste0(prefix, i), i * 10)
}

paste0() vs paste() vs sprintf()

paste0(...) is exactly equivalent to paste(..., sep = ""), it concatenates strings with no separator. It exists as a convenience function because no-separator concatenation is so common.

paste0() is vectorized and recycles inputs: paste0("x", 1:5) produces c("x1", "x2", "x3", "x4", "x5"). This makes it the most efficient way to generate sequences of labeled variable names, file paths, or identifier strings.

For generating variable names to assign dynamically, paste0(prefix, i) combined with assign() or list() is a common pattern. For constructing file paths, file.path() is preferable to paste0() because it handles path separators correctly across operating systems.

When building SQL queries or HTML strings with user-supplied values, never use paste0() directly, use parameterized queries or HTML-safe encoding functions to prevent injection. paste0() provides no escaping or sanitization.

paste0() vs paste() and sprintf()

paste0() is equivalent to paste(..., sep = ""), it concatenates strings with no separator. It is the idiom for string building without delimiters, which appears constantly in constructing file paths, variable names, SQL fragments, and HTML strings. paste0("user_", id) is simpler to read than paste("user_", id, sep = "").

Like paste(), paste0() vectorizes over all arguments: paste0(prefix, 1:3, suffix) gives a three-element vector if prefix and suffix are scalars. When arguments are vectors of different lengths, recycling applies. paste0(c("a","b"), c("1","2","3")) would recycle the first vector, producing c("a1","b2","a3"). If this recycling is unintentional, check that argument lengths match or use mapply().

sprintf() is preferable to paste0() when the output has a fixed template with multiple variables and mixed types. sprintf("User %d logged in at %s", id, time) is more readable than paste0("User ", id, " logged in at ", time) when there are three or more interpolated values. For simple two-part concatenation, paste0() is more concise.

Avoid building SQL queries or shell commands by pasting user-supplied strings — this creates SQL injection or shell injection vulnerabilities. Use parameterized queries (via the DBI package) and shQuote() for shell arguments instead. paste0() is safe for constructing strings from controlled, internal values, but not for anything containing external input.

See also