1

Let's say I have a vector of strings:

vec <- c("D", "A", "B", "A")

I would like to insert a modified string (concatenate "_2" at the end of the strings) immediately after the original string, without sorting.

Expected output:

[1] "D"   "D_2" "A"   "A_2" "B"   "B_2" "A"   "A_2"

I am looking for solutions simpler than the one I shared below, which I think could be unnecessarily over-complicated.

benson23
  • 16,369
  • 9
  • 19
  • 38

4 Answers4

4

Try c + rbind along with paste0

> c(rbind(vec, paste0(vec, "_2")))
[1] "D"   "D_2" "A"   "A_2" "B"   "B_2" "A"   "A_2"

or a longer version with outer

> c(t(outer(vec, c("", "_2"), paste0)))
[1] "D"   "D_2" "A"   "A_2" "B"   "B_2" "A"   "A_2"

If you don't mind the efficiency, you can try

> scan(text = gsub("(.*)", "\\1 \\1_2", vec), what = "", quiet = TRUE)
[1] "D"   "D_2" "A"   "A_2" "B"   "B_2" "A"   "A_2"

since scan might be slow when having long vectors.

ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
4

You can also use vctrs::vec_interleave:

library(vctrs)
vec_interleave(vec, paste0(vec, "_2"))
#[1] "D"   "D_2" "A"   "A_2" "B"   "B_2" "A"   "A_2"

Or, add "_2" in every other element:

paste0(rep(vec, each = 2), c("", "_2"))
#[1] "D"   "D_2" "A"   "A_2" "B"   "B_2" "A"   "A_2"
Maël
  • 45,206
  • 3
  • 29
  • 67
1

Use sprintf to concatenate the original and modified strings together with a symbol that you sure will not appear in the original strings, then split them and unlist.

unlist(strsplit(sprintf("%s@%s_2", vec, vec), "@"))
[1] "D"   "D_2" "A"   "A_2" "B"   "B_2" "A"   "A_2"
benson23
  • 16,369
  • 9
  • 19
  • 38
1

An option might be to rep vec and replace every second.

replace(rep(vec, each=2), c(FALSE, TRUE), paste0(vec, "_2"))
#[1] "D"   "D_2" "A"   "A_2" "B"   "B_2" "A"   "A_2"
GKi
  • 37,245
  • 2
  • 26
  • 48