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