Using the base of combn
, we'll iterate using lapply
/Map
to shape things well.
I'll use up to five levels:
some <- lapply(1:5, combn, x=5)
some
# [[1]]
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 2 3 4 5
# [[2]]
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 1 1 1 1 2 2 2 3 3 4
# [2,] 2 3 4 5 3 4 5 4 5 5
# [[3]]
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 1 1 1 1 1 1 2 2 2 3
# [2,] 2 2 2 3 3 4 3 3 4 4
# [3,] 3 4 5 4 5 5 4 5 5 5
# [[4]]
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 1 1 2
# [2,] 2 2 2 3 3
# [3,] 3 3 4 4 4
# [4,] 4 5 5 5 5
# [[5]]
# [,1]
# [1,] 1
# [2,] 2
# [3,] 3
# [4,] 4
# [5,] 5
Since they have different numbers of rows, we need to normalize them.
some2 <- Map(function(m, nr, nc) rbind(m, matrix(NA, nr=nr-nrow(m), nc=ncol(m))), some, 5, 10)
some2
# [[1]]
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 2 3 4 5
# [2,] NA NA NA NA NA
# [3,] NA NA NA NA NA
# [4,] NA NA NA NA NA
# [5,] NA NA NA NA NA
# [[2]]
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 1 1 1 1 2 2 2 3 3 4
# [2,] 2 3 4 5 3 4 5 4 5 5
# [3,] NA NA NA NA NA NA NA NA NA NA
# [4,] NA NA NA NA NA NA NA NA NA NA
# [5,] NA NA NA NA NA NA NA NA NA NA
# [[3]]
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 1 1 1 1 1 1 2 2 2 3
# [2,] 2 2 2 3 3 4 3 3 4 4
# [3,] 3 4 5 4 5 5 4 5 5 5
# [4,] NA NA NA NA NA NA NA NA NA NA
# [5,] NA NA NA NA NA NA NA NA NA NA
# [[4]]
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 1 1 1 2
# [2,] 2 2 2 3 3
# [3,] 3 3 4 4 4
# [4,] 4 5 5 5 5
# [5,] NA NA NA NA NA
# [[5]]
# [,1]
# [1,] 1
# [2,] 2
# [3,] 3
# [4,] 4
# [5,] 5
From here, just binding them into one so that you can iterate over all combinations:
out <- do.call(cbind, some2)
out
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16]
# [1,] 1 2 3 4 5 1 1 1 1 2 2 2 3 3 4 1
# [2,] NA NA NA NA NA 2 3 4 5 3 4 5 4 5 5 2
# [3,] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 3
# [4,] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
# [5,] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
# [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26] [,27] [,28] [,29] [,30] [,31]
# [1,] 1 1 1 1 1 2 2 2 3 1 1 1 1 2 1
# [2,] 2 2 3 3 4 3 3 4 4 2 2 2 3 3 2
# [3,] 4 5 4 5 5 4 5 5 5 3 3 4 4 4 3
# [4,] NA NA NA NA NA NA NA NA NA 4 5 5 5 5 4
# [5,] NA NA NA NA NA NA NA NA NA NA NA NA NA NA 5
Granted, you don't strictly need to combine them into one matrix here: you can iterate over each column of each of the some
list.
With this code, you can easily replace your own levels:
mylevels <- c("fee", "fie", "foe", "fum", "quux")
out[] <- mylevels[out]
out
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
# [1,] "fee" "fie" "foe" "fum" "quux" "fee" "fee" "fee" "fee" "fie" "fie" "fie" "foe" "foe"
# [2,] NA NA NA NA NA "fie" "foe" "fum" "quux" "foe" "fum" "quux" "fum" "quux"
# [3,] NA NA NA NA NA NA NA NA NA NA NA NA NA NA
# [4,] NA NA NA NA NA NA NA NA NA NA NA NA NA NA
# [5,] NA NA NA NA NA NA NA NA NA NA NA NA NA NA
# [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26] [,27]
# [1,] "fum" "fee" "fee" "fee" "fee" "fee" "fee" "fie" "fie" "fie" "foe" "fee" "fee"
# [2,] "quux" "fie" "fie" "fie" "foe" "foe" "fum" "foe" "foe" "fum" "fum" "fie" "fie"
# [3,] NA "foe" "fum" "quux" "fum" "quux" "quux" "fum" "quux" "quux" "quux" "foe" "foe"
# [4,] NA NA NA NA NA NA NA NA NA NA NA "fum" "quux"
# [5,] NA NA NA NA NA NA NA NA NA NA NA NA NA
# [,28] [,29] [,30] [,31]
# [1,] "fee" "fee" "fie" "fee"
# [2,] "fie" "foe" "foe" "fie"
# [3,] "fum" "fum" "fum" "foe"
# [4,] "quux" "quux" "quux" "fum"
# [5,] NA NA NA "quux"
(My assumption is that you will safely ignore NA
values in whatever function you're using to regress on these levels.)