362

If I have a vector of type character, how can I concatenate the values into string? Here's how I would do it with paste():

sdata = c('a', 'b', 'c') paste(sdata[1], sdata[2], sdata[3], sep ='') 

yielding "abc".

But of course, that only works if I know the length of sdata ahead of time.

8 Answers 8

626
Answer recommended by R Language Collective

Try using an empty collapse argument within the paste function:

paste(sdata, collapse = '')

Thanks to http://twitter.com/onelinetips/status/7491806343

Sign up to request clarification or add additional context in comments.

1 Comment

Just a note that if sdata can contain either strings which are all of the same length or of variable lengths then paste(sdata, sep = '', collapse = '') should be used to avoid unexpected results.
52

Matt's answer is definitely the right answer. However, here's an alternative solution for comic relief purposes:

do.call(paste, c(as.list(sdata), sep = "")) 

2 Comments

you really could have worked an apply() statement in there. If you do I'll up vote you ;)
this would actually be the most elegant solution if the collapse parameter didn’t exist. so not much comedic relief if you recently actually had to do something very similar :)
15

You can use stri_paste function with collapse parameter from stringi package like this:

stri_paste(letters, collapse='') ## [1] "abcdefghijklmnopqrstuvwxyz" 

And some benchmarks:

require(microbenchmark) test <- stri_rand_lipsum(100) microbenchmark(stri_paste(test, collapse=''), paste(test,collapse=''), do.call(paste, c(as.list(test), sep=""))) Unit: microseconds expr min lq mean median uq max neval stri_paste(test, collapse = "") 137.477 139.6040 155.8157 148.5810 163.5375 226.171 100 paste(test, collapse = "") 404.139 406.4100 446.0270 432.3250 442.9825 723.793 100 do.call(paste, c(as.list(test), sep = "")) 216.937 226.0265 251.6779 237.3945 264.8935 405.989 100 

1 Comment

I had never performed benchmarks on R. Nice to learn something new.
11

tidyverse

The stringr package has a few, fast ways you could accomplish this.

str_flatten

By default will collapse your character vector with no spaces, but does have collapse argument as well:

str_flatten(sdata) # [1] "abc" 

Also has an optional last argument to use in place of the final separator.

str_c

Similar to paste with a collapse argument you need to specify to accomplish this:

str_c(sdata, collapse = "") # [1] "abc" 

str_flatten_comma

New as of stringr 1.5.0 if you want a comma delimited collapse. Here the last argument recognizes the Oxford comma:

str_flatten_comma(sdata) # similar to base R toString() # [1] "a, b, c" ## handling Oxford comma str_flatten_comma(sdata, last = ", and ") # [1] "a, b, and c" str_flatten_comma(sdata[1:2], last = ", and ") # (removes comma) # [1] "a and b" 

stringfish (faster)

For most cases stringi and stringr will provide enough speed, but if you need something faster consider the stringfish package:

library(stringfish) sf_collapse(sdata, collapse = '') # [1] "abc" 

Base R

For completeness, you could use paste0, though there is no obvious advantage here over paste:

paste0(sdata, collapse = "") 

Benchmark

Across vector sizes of 10K, 100K, 1M and 10M stringfish yields consistently faster results:

 expression string_length min median `itr/sec` `gc/sec` n_itr n_gc <bch:expr> <dbl> <bch:tm> <bch:tm> <dbl> <dbl> <int> <dbl> 1 sf_collapse 10000 149µs 163.8µs 6020. 0 3009 0 2 str_flatten 10000 166.8µs 174.2µs 5527. 0 2762 0 3 stri_paste 10000 163.9µs 176µs 5517. 0 2757 0 4 str_c 10000 186µs 200.3µs 4954. 0 2476 0 5 paste 10000 606.8µs 677.4µs 1472. 2.06 715 1 6 paste0 10000 606.3µs 681.9µs 1449. 0 725 0 7 sf_collapse 100000 1.48ms 1.55ms 643. 0 322 0 8 stri_paste 100000 1.81ms 1.96ms 490. 0 245 0 9 str_flatten 100000 1.81ms 2.04ms 486. 0 244 0 10 str_c 100000 1.84ms 2.03ms 480. 0 241 0 11 paste0 100000 6.24ms 6.73ms 147. 2.10 70 1 12 paste 100000 6.37ms 6.98ms 142. 0 72 0 13 sf_collapse 1000000 16.02ms 16.88ms 59.4 0 30 0 14 str_flatten 1000000 19.45ms 20.02ms 49.7 0 25 0 15 stri_paste 1000000 19.28ms 20.07ms 49.6 0 25 0 16 str_c 1000000 19.8ms 20.77ms 47.9 0 24 0 17 paste 1000000 64.06ms 65.41ms 15.3 0 8 0 18 paste0 1000000 64.54ms 65.75ms 15.1 0 8 0 19 sf_collapse 10000000 167.88ms 169.53ms 5.91 0 3 0 20 str_c 10000000 199.67ms 200.04ms 4.96 0 3 0 21 stri_paste 10000000 205.17ms 210.69ms 4.76 0 3 0 22 str_flatten 10000000 216.98ms 217.04ms 4.60 0 3 0 23 paste0 10000000 690.85ms 690.85ms 1.45 0 1 0 24 paste 10000000 767.12ms 767.12ms 1.30 1.30 1 1 

Benchmark Code

library(bench) library(stringr) library(stringi) library(stringfish) set.seed(4) results <- press( string_length = c(1E4, 1E5, 1E6, 1E7), { x <- sample(letters, string_length, replace = T) mark( stri_paste = stri_paste(x, collapse=''), paste = paste(x,collapse=''), str_flatten = str_flatten(x), str_c = str_c(x, collapse = ""), paste0 = paste0(x, collapse = ""), sf_collapse = sf_collapse(x, collapse = ""), memory = FALSE) } ) sort_by(results, ~ list(string_length, - `itr/sec`)) |> subset(select = c(1:5, 7:9)) |> print(n = 24) 

Comments

5

Matt Turner's answer is definitely the right answer. However, in the spirit of Ken Williams' answer, you could also do:

capture.output(cat(sdata, sep="")) 

Comments

4

For sdata:

gsub(", ", "", toString(sdata)) 

For a vector of integers:

gsub(", ", "", toString(c(1:10))) 

1 Comment

This is a dangerous answer -- if there are comma-space sequences in the elements of the vector, this answer will remove them.
2

Another way would be to use glue package:

glue_collapse(glue("{sdata}")) paste(glue("{sdata}"), collapse = '') 

Comments

1

Here is a little utility function that collapses a named or unnamed list of values to a single string for easier printing. It will also print the code line itself. It's from my list examples in R page.

Generate some lists named or unnamed:

# Define Lists ls_num <- list(1,2,3) ls_str <- list('1','2','3') ls_num_str <- list(1,2,'3') # Named Lists ar_st_names <- c('e1','e2','e3') ls_num_str_named <- ls_num_str names(ls_num_str_named) <- ar_st_names # Add Element to Named List ls_num_str_named$e4 <- 'this is added' 

Here is the a function that will convert named or unnamed list to string:

ffi_lst2str <- function(ls_list, st_desc, bl_print=TRUE) { # string desc if(missing(st_desc)){ st_desc <- deparse(substitute(ls_list)) } # create string st_string_from_list = paste0(paste0(st_desc, ':'), paste(names(ls_list), ls_list, sep="=", collapse=";" )) if (bl_print){ print(st_string_from_list) } } 

Testing the function with the lists created prior:

> ffi_lst2str(ls_num) [1] "ls_num:=1;=2;=3" > ffi_lst2str(ls_str) [1] "ls_str:=1;=2;=3" > ffi_lst2str(ls_num_str) [1] "ls_num_str:=1;=2;=3" > ffi_lst2str(ls_num_str_named) [1] "ls_num_str_named:e1=1;e2=2;e3=3;e4=this is added" 

Testing the function with subset of list elements:

> ffi_lst2str(ls_num_str_named[c('e2','e3','e4')]) [1] "ls_num_str_named[c(\"e2\", \"e3\", \"e4\")]:e2=2;e3=3;e4=this is added" > ffi_lst2str(ls_num[2:3]) [1] "ls_num[2:3]:=2;=3" > ffi_lst2str(ls_str[2:3]) [1] "ls_str[2:3]:=2;=3" > ffi_lst2str(ls_num_str[2:4]) [1] "ls_num_str[2:4]:=2;=3;=NULL" > ffi_lst2str(ls_num_str_named[c('e2','e3','e4')]) [1] "ls_num_str_named[c(\"e2\", \"e3\", \"e4\")]:e2=2;e3=3;e4=this is added" 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.