Home > database >  How in R distribute the elements of one list/vector to another when their number is unequal?
How in R distribute the elements of one list/vector to another when their number is unequal?

Time:10-10

I create a list of 10 items

number_of_items = 10
list_of_items <- do.call('paste0',expand.grid("q", c(1:number_of_items)))
list_of_items 
[1] "q1"  "q2"  "q3"  "q4"  "q5"  "q6"  "q7"  "q8"  "q9"  "q10"

which I would like to separate up to 4 "lines" consecutively. It can be a series of four strings (even better than list/vectors), the separator does not matter to me. It is known that you cannot distribute it perfectly evenly, because 10 is not divisible by 4. So the effect I would like to achieve is something like this:

> q1 q5 q9
> q2 q6 q10
> q3 q7
> q4 q8

My first thought was to sequentially copy the elements using paste into new strings like this:

number_of_rows = 4
strings = rep ("", times=number_of_rows)
j = 1

for (i in 1:number_of_items) {
strings[j] = paste(strings[j], list_of_items[i], sep = " ") 
j = j 1
if (j > number_of_rows ) { j = 1}
}
substring(strings,2)
> [1] "q1 q5 q9"  "q2 q6 q10" "q3 q7"     "q4 q8"

but since I'm new to R, maybe there is an easy way to do it in a single/simple/elegant way?

CodePudding user response:

You can add a number of empty strings on to your vector, equal to 4 minus the length of your vector modulo 4. This will give you a vector with a length divisible by 4, so that you can always turn it into a matrix with 4 rows, regardless of the initial number of elements.

mat <- list_of_items |>
  c(rep("", 4 - (length(list_of_items) %% 4))) |>
  matrix(nrow = 4)

mat
#>      [,1] [,2] [,3] 
#> [1,] "q1" "q5" "q9" 
#> [2,] "q2" "q6" "q10"
#> [3,] "q3" "q7" ""   
#> [4,] "q4" "q8" ""  

If desired, this can be converted to a vector of 4 strings using apply and paste. Here I have used cat to print the result at the end of the pipe

apply(mat, 1, paste, collapse = ' ') |>
  cat(sep = '\n')
#> q1 q5 q9
#> q2 q6 q10
#> q3 q7 
#> q4 q8 
  • Related