A bit verbose but aiming to do the least work using base R.
foo <- function(v) {
# Updated version, uses seq.int() instead of seq()
n <- length(v)
out <- character(n * 2L)
out[seq.int(1L, n * 2L, by = 2L)] <- v
out[seq.int(2L, n * 2L, by = 2L)] <- paste0(v, ".1")
out
}
foo(vec)
# [1] "x" "x.1" "y" "y.1" "z" "z.1"
Benchmark:
# Generate 35^4 ~ 1.5 million unique characters
vec <- do.call(data.table::CJ, rep(list(c(letters, 1:9)), 4))[, do.call(paste0, .SD)]
bench::mark(
Tho = make.unique(rep(vec, each = 2)),
Ron = c(rbind(vec, paste0(vec, ".1"))),
Tim = {paste0(rep(vec, each = 2), c("", ".1"))},
Tar = as.vector(vapply(vec, \(x) c(x, paste0(x, ".1")), character(2))),
Fri = {x = c(vec, paste0(vec,".1"));sort(x)},
`M--` = {suf <- c(".1", "");data.table::CJ(vec, suf)[, paste0(vec, suf)]},
SAL = {mapply(c,vec,paste0(vec, ".1"), SIMPLIFY = F, USE.NAMES = F) |> unlist()},
s_b = foo(vec)
# Edwards not included as solution doesn't match exactly expected output
)
# expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc
# <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl>
# 1 Tho 984.11ms 984.11ms 1.02 100.7MB 2.03 1 2
# 2 Ron 239.3ms 264.44ms 3.78 57.2MB 1.89 2 1
# 3 Tim 477.86ms 482.61ms 2.07 45.8MB 0 2 0
# 4 Tar 4.83s 4.83s 0.207 57.3MB 2.49 1 12
# 5 Fri 13.46s 13.46s 0.0743 68.7MB 0 1 0
# 6 M-- 822.16ms 822.16ms 1.22 80.2MB 1.22 1 1
# 7 SAL 1.86s 1.86s 0.538 45.8MB 3.23 1 6
# 8 s_b 208.96ms 254.67ms 4.00 45.8MB 1.33 3 1