n-Concatenation of a vector of length N (n divides N) without looping (in R)

Viewed 56

Suppose we have a 1D string vector V of length N, where N is a given natural non-zero integer. Let us introduce a number n such that N%%n==0 (n divides N).

I would like to obtain the vector U such that the 1st component is the concatenation of the first n components of V, the 2nd component is the concatenation of the second n components of '''V''', etc., and this without using any loop, plus n is a variable (basically it is derived in another part of a bigger code).

Thus, given N, say V=as.character(1:N). Introduce n with N%%n==0. I would like to do without loop (also possibly without if) and in one line:

U = c()
if (length(V)/n>1) {
  for (t in 1:(length(V)/n)) {
    U = paste(U, V[ ngroup(1:length(V),n,ifelse(t==n,0,t)) ], sep='')
  }
} else { U=paste(V,collapse='') }

where the function ngroup simply is given by

ngroup <- function(x,n,r) which(x%%n == r) # r: number in [0, 1, 2, ..., n-1].

As an example, if N=8 and n=2, we straightforwardly have ngroup(1:length(V),n,1) = c(1,3,5,7) (odd numbers) and ngroup(1:length(V),n,0) = c(2,4,6,8) (even numbers), thus

U = paste(V[c(1,3,5,7)], V[c(2,4,6,8)], sep='')

so that U is the vector ["V[1]V[2]" "V[3]V[4]" "V[5]V[6]" "V[7]V[8]"] symbolically written (concatenate V[1] with V[2], V[3] with V[4], etc.).

Perhaps we could do something with the 'apply' family of functions, but I'm not at-ease in this situation. I thank you very much for your assistance!

2 Answers

Without loops as requested (*apply is a loop):

V <- letters[1:24]
n <- 3

foo <- function(V, n) {
  stopifnot(length(V) %% n == 0)
  M <- matrix(V, nrow = n)
  do.call(paste0, asplit(M, 1))
}

foo(V, n)
#[1] "abc" "def" "ghi" "jkl" "mno" "pqr" "stu" "vwx"

Maybe you can try

sapply(split(V, ceiling(seq_along(V)/n)),paste0, collapse = "")

or

do.call(paste0,as.data.frame(do.call(rbind,split(V, ceiling(seq_along(V)/n)))))

Example

V <- letters[1:24]
n <- 3

such that

> sapply(split(V, ceiling(seq_along(V)/n)),paste0, collapse = "")
    1     2     3     4     5     6     7     8
"abc" "def" "ghi" "jkl" "mno" "pqr" "stu" "vwx"
Related