# How can two strings be concatenated?

How can I concatenate (merge, combine) two values? For example I have:

``````tmp = cbind("GAD", "AB")
tmp
#      [,1]  [,2]
``````

My goal is to concatenate the two values in "tmp" to one string:

``````tmp_new = "GAD,AB"
``````

Which function can do this for me?

• Most answers here break if the strings are vectors, as @RichardScriven's answer notes.
– smci
May 7, 2016 at 4:12
• @smci what about the small answer i have posted? any suggestions to improve it? Jan 23, 2017 at 13:47

``````paste()
``````

is the way to go. As the previous posters pointed out, paste can do two things:

concatenate values into one "string", e.g.

``````> paste("Hello", "world", sep=" ")
[1] "Hello world"
``````

where the argument `sep` specifies the character(s) to be used between the arguments to concatenate, or collapse character vectors

``````> x <- c("Hello", "World")
> x
[1] "Hello" "World"
> paste(x, collapse="--")
[1] "Hello--World"
``````

where the argument `collapse` specifies the character(s) to be used between the elements of the vector to be collapsed.

You can even combine both:

``````> paste(x, "and some more", sep="|-|", collapse="--")
[1] "Hello|-|and some more--World|-|and some more"
``````
• Mixing up strings and vectors or vectors of different lengths is a bit too flexible in `paste()` for my liking. For instance, `paste(c('a','b'),'blah', c(1,2,3))` results in `"a blah 1" "b blah 2" "a blah 3"`. Basically, it creates a vector of strings the same length as the longest vector that's passed in, and loops the other vectors/strings to the same length. Plenty of room for accidental behaviour there. Jul 8, 2014 at 7:12
• True - but can you provide an alternative approach which addresses the question? Jul 9, 2014 at 9:57
• no - your answer is correct (as are most of the other answers that say the same thing). I was just noting that paste's behaviour is unusual in its flexibility. Jul 9, 2014 at 11:07
• @naught101 I wouldn't consider it unusual by R's standards. Vector recycling is a common property of R functions. Keep in mind that 'blah' is a vector of length 1. The recycling property makes it easy to do something like `paste0("blah", 1:3)` to get `"blah1" "blah2" "blah3"`. Jul 18, 2014 at 7:34
• Yes, I should be complaining about R, not just paste :P . It's actually inconsistent across R - `data.frame()` doesn't let you do it if vectors aren't a multiple of each other. `matrix()` spits out warnings, but `array()` doesn't. Kind of annoying. Really, they should all spit out warnings unless some option is set... Jul 19, 2014 at 10:58

`help.search()` is a handy function, e.g.

``````> help.search("concatenate")
``````

will lead you to `paste()`.

For the first non-`paste()` answer, we can look at `stringr::str_c()` (and then `toString()` below). It hasn't been around as long as this question, so I think it's useful to mention that it also exists.

Very simple to use, as you can see.

``````tmp <- cbind("GAD", "AB")
library(stringr)
str_c(tmp, collapse = ",")
``````

From its documentation file description, it fits this problem nicely.

To understand how str_c works, you need to imagine that you are building up a matrix of strings. Each input argument forms a column, and is expanded to the length of the longest argument, using the usual recyling rules. The sep string is inserted between each column. If collapse is NULL each row is collapsed into a single string. If non-NULL that string is inserted at the end of each row, and the entire matrix collapsed to a single string.

Added 4/13/2016: It's not exactly the same as your desired output (extra space), but no one has mentioned it either. `toString()` is basically a version of `paste()` with `collapse = ", "` hard-coded, so you can do

``````toString(tmp)
``````
• Heh, this is the only answer that addresses the fact that tmp is a vector, and not just a bunch of values - `paste` doesn't do vectors. The other option is `do.call(paste, as.list(tmp))`. Feb 3, 2016 at 1:54

As others have pointed out, `paste()` is the way to go. But it can get annoying to have to type `paste(str1, str2, str3, sep='')` everytime you want the non-default separator.

You can very easily create wrapper functions that make life much simpler. For instance, if you find yourself concatenating strings with no separator really often, you can do:

``````p <- function(..., sep='') {
paste(..., sep=sep, collapse=sep)
}
``````

or if you often want to join strings from a vector (like `implode()` from PHP):

``````implode <- function(..., sep='') {
paste(..., collapse=sep)
}
``````

Allows you do do this:

``````p('a', 'b', 'c')
#[1] "abc"
vec <- c('a', 'b', 'c')
implode(vec)
#[1] "abc"
implode(vec, sep=', ')
#[1] "a, b, c"
``````

Also, there is the built-in `paste0`, which does the same thing as my `implode`, but without allowing custom separators. It's slightly more efficient than `paste()`.

• how is this more efficient than paste? Feb 22 at 16:59
• @Jorge what "this" are you referring to? Feb 23 at 22:10
``````> tmp = paste("GAD", "AB", sep = ",")
> tmp
``````

I found this from Google by searching for R concatenate strings: http://stat.ethz.ch/R-manual/R-patched/library/base/html/paste.html

Alternatively, if your objective is to output directly to a file or stdout, you can use `cat`:

``````cat(s1, s2, sep=", ")
``````
• So what the point posting a `paste` answer 4 years later when there are about a dozen of `paste` answers already? Jan 9, 2017 at 9:31
• At the time I found it helpful to summarize multiple answers for myself. The objective was not to collect votes but to help others filter through the many offered solutions. Often that's what I'm looking for. Jan 9, 2017 at 12:37
• @DavidArenburg Whats the point in your comment? Dec 13, 2020 at 17:21
• @Error404 The point is to prevent duplicated answers- isn't it obvious? If you will post an answer, and I'll come 4 years later and repost your answer on the same thread, would that make sense? Dec 13, 2020 at 17:29

You can create you own operator :

``````'%&%' <- function(x, y)paste0(x,y)
"new" %&% "operator"
[1] newoperator`
``````

You can also redefine 'and' (`&`) operator :

``````'&' <- function(x, y)paste0(x,y)
"dirty" & "trick"
"dirtytrick"
``````

messing with baseline syntax is ugly, but so is using `paste()/paste0()` if you work only with your own code you can (almost always) replace logical `& and` operator with `*` and do multiplication of logical values instead of using logical 'and &'

• @Richard Scriven mayby I don't understand, but it seems straightforward, compare : `paste0(as.matrix(iris[1:4]) , as.matrix(iris[1:4]))` and `as.matrix(iris[1:4]) %&% as.matrix(iris[1:4])`
– Qbik
May 16, 2016 at 12:50
• very very good! & is standard for concatenation in many languages, I actually think R should have had it by default. strongly recommend this way Aug 17, 2019 at 10:47

Another way:

``````sprintf("%s you can add other static strings here %s",string1,string2)
``````

It sometimes useful than `paste()` function. `%s` denotes the place where the subjective strings will be included.

Note that this will come in handy as you try to build a path:

``````sprintf("/%s", paste("this", "is", "a", "path", sep="/"))
``````

output

``````/this/is/a/path
``````
• for C programmers dealing with R, sprintf is familiar and useful for "concatenating two strings" Nov 28, 2016 at 5:24
• Much better imho. `paste` is not flexible enough if you want to append something to a string. Apr 5, 2017 at 9:38

Given the matrix, tmp, that you created:

``````paste(tmp[1,], collapse = ",")
``````

I assume there is some reason why you're creating a matrix using cbind, as opposed to simply:

``````tmp <- "GAD,AB"
``````

Consider the case where the strings are columns and the result should be a new column:

``````df <- data.frame(a = letters[1:5], b = LETTERS[1:5], c = 1:5)

df\$new_col <- do.call(paste, c(df[c("a", "b")], sep = ", "))
df
#  a b c new_col
#1 a A 1    a, A
#2 b B 2    b, B
#3 c C 3    c, C
#4 d D 4    d, D
#5 e E 5    e, E
``````

Optionally, skip the `[c("a", "b")]` subsetting if all columns needs to be pasted.

``````# you can also try str_c from stringr package as mentioned by other users too!
do.call(str_c, c(df[c("a", "b")], sep = ", "))
``````
• Ok but `stringi, stringr` libraries are faster.
– smci
Jan 24, 2017 at 0:16

`glue` is a new function, data class, and package that has been developed as part of the `tidyverse`, with a lot of extended functionality. It combines features from paste, sprintf, and the previous other answers.

``````tmp <- tibble::tibble(firststring = "GAD", secondstring = "AB")
(tmp_new <- glue::glue_data(tmp, "{firststring},{secondstring}"))
``````

Created on 2019-03-06 by the reprex package (v0.2.1)

Yes, it's overkill for the simple example in this question, but powerful for many situations. (see https://glue.tidyverse.org/)

Quick example compared to `paste` with `with` below. The `glue` code was a bit easier to type and looks a bit easier to read.

``````tmp <- tibble::tibble(firststring = c("GAD", "GAD2", "GAD3"), secondstring = c("AB1", "AB2", "AB3"))
(tmp_new <- glue::glue_data(tmp, "{firststring} and {secondstring} went to the park for a walk. {firststring} forgot his keys."))
#> GAD and AB1 went to the park for a walk. GAD forgot his keys.
#> GAD2 and AB2 went to the park for a walk. GAD2 forgot his keys.
#> GAD3 and AB3 went to the park for a walk. GAD3 forgot his keys.
(with(tmp, paste(firststring, "and", secondstring, "went to the park for a walk.", firststring, "forgot his keys.")))
#> [1] "GAD and AB1 went to the park for a walk. GAD forgot his keys."
#> [2] "GAD2 and AB2 went to the park for a walk. GAD2 forgot his keys."
#> [3] "GAD3 and AB3 went to the park for a walk. GAD3 forgot his keys."
``````

Created on 2019-03-06 by the reprex package (v0.2.1)

``````x <- capture.output(cat(data, sep = ","))
`````` data <- c("GAD", "AB")