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.
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"
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)