Search code examples
rloopsiteration

Is there a way to make combinations of paste0 function with a list?


I have a vector of names:

names <- c("a", "b", "c", "d", "e", "f", "g", "h")

I want to make series of combinations of these names with these numbers respectively:

numbers <- c(0, 0:2, 0:3, 0:1, 0:1, 0, 0, 0)

So my combinations would be:

a0 b0 b1 b2 c0 c1 c2 c3 d0 d1 e0 e1 f0 g0 h0

How can I do it? I rather use a vectorized function than iterating.

I tried these codes but I got wrong results (possible due to recyle or somethin):

paste0(names, numbers, recycle0 = F)
paste0(names, numbers, recycle0 = T)
paste0(names, numbers |> as.list())
purrr::map_chr(names, paste0(c(0, 0:2, 0:3, 0:1, 0:1, 0, 0, 0)))

and a few others that I can't remmember clearly.


Solution

  • 1) The cumsum(...) is the indexes into names, i.e. 1 2 2 2 3 3 3 3 4 4 5 5 6 7 8, so index into the names and paste numbers onto the end. No external packages are used.

    paste0(names[cumsum(numbers == 0)], numbers)
    ## [1] "a0" "b0" "b1" "b2" "c0" "c1" "c2" "c3" "d0" "d1" "e0" "e1" "f0" "g0" "h0"
    

    2) A second approach, also based on cumsum(...), is to use rle to get the run lengths, repeat each name that number of times and then paste on the numbers. This also uses no packages.

    paste0(rep(names, rle(cumsum(numbers == 0))$lengths), numbers)
    ## [1] "a0" "b0" "b1" "b2" "c0" "c1" "c2" "c3" "d0" "d1" "e0" "e1" "f0" "g0" "h0"
    

    2a) A slightly shorter variation of this is to use table in place of rle(...)$lengths:

    paste0(rep(names, table(cumsum(numbers == 0))), numbers)
    

    3) This one does not use cumsum but it does use a package. In numbers replace the 0's with the names and the other numbers with NA. Then use na.locf0 to fill in the NA's and paste on the numbers.

    library(zoo)
    
    paste0(na.locf0(replace(NA * numbers, numbers == 0, names)), numbers)
    ## [1] "a0" "b0" "b1" "b2" "c0" "c1" "c2" "c3" "d0" "d1" "e0" "e1" "f0" "g0" "h0"
    

    Note

    Input from question

    names <- c("a", "b", "c", "d", "e", "f", "g", "h")
    numbers <- c(0, 0:2, 0:3, 0:1, 0:1, 0, 0, 0)