I need to create a square matrix based on a vector of varying length where the indices of the vector populate the upper triangular only without recycling of the vector elements.
I tried the following R code:
# example vector (could be longer or shorter!)
v <- letters[1:8]
# calculate dimensions of square matrix
n <- ceiling((-1 + sqrt(1 + 8 * length(v))) / 2)
# create empty matrix
m <- matrix(NA, nrow=n, ncol=n)
# populate the matrix
m[lower.tri(m, diag=TRUE)] <- 1:length(v)
m <- t(m)
And the resulting matrix looks like that:
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] NA 5 6 7
[3,] NA NA 8 1
[4,] NA NA NA 2
How can I populate the matrix in a way that only that part of the upper triangular is filled which does not require recycling of vector index elements?
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] NA NA 5 6
[3,] NA NA NA 7
[4,] NA NA NA 8
Thanks alot for the help!
Something like this?
f <- function(v) {
n <- length(v)
# number of rows of the square matrix
m <- ceiling(sqrt(0.25 + 2*n) - 0.5)
x <- array(NA, rep(m, 2))
s <- pmin(m + 1L - row(x), col(x)) + pmax(m + 1L - row(x), col(x))/n + (m + 1L)*upper.tri(x)
x[sort(order(s)[1:n])] <- v
t(x)
}
Testing vectors up to length 14:
lapply(1:14, \(i) f(1:i))
#> [[1]]
#> [,1]
#> [1,] 1
#>
#> [[2]]
#> [,1] [,2]
#> [1,] 1 2
#> [2,] NA NA
#>
#> [[3]]
#> [,1] [,2]
#> [1,] 1 2
#> [2,] NA 3
#>
#> [[4]]
#> [,1] [,2] [,3]
#> [1,] 1 2 3
#> [2,] NA NA 4
#> [3,] NA NA NA
#>
#> [[5]]
#> [,1] [,2] [,3]
#> [1,] 1 2 3
#> [2,] NA NA 4
#> [3,] NA NA 5
#>
#> [[6]]
#> [,1] [,2] [,3]
#> [1,] 1 2 3
#> [2,] NA 4 5
#> [3,] NA NA 6
#>
#> [[7]]
#> [,1] [,2] [,3] [,4]
#> [1,] 1 2 3 4
#> [2,] NA NA NA 5
#> [3,] NA NA NA 6
#> [4,] NA NA NA 7
#>
#> [[8]]
#> [,1] [,2] [,3] [,4]
#> [1,] 1 2 3 4
#> [2,] NA NA 5 6
#> [3,] NA NA NA 7
#> [4,] NA NA NA 8
#>
#> [[9]]
#> [,1] [,2] [,3] [,4]
#> [1,] 1 2 3 4
#> [2,] NA 5 6 7
#> [3,] NA NA NA 8
#> [4,] NA NA NA 9
#>
#> [[10]]
#> [,1] [,2] [,3] [,4]
#> [1,] 1 2 3 4
#> [2,] NA 5 6 7
#> [3,] NA NA 8 9
#> [4,] NA NA NA 10
#>
#> [[11]]
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 2 3 4 5
#> [2,] NA NA 6 7 8
#> [3,] NA NA NA NA 9
#> [4,] NA NA NA NA 10
#> [5,] NA NA NA NA 11
#>
#> [[12]]
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 2 3 4 5
#> [2,] NA NA 6 7 8
#> [3,] NA NA NA 9 10
#> [4,] NA NA NA NA 11
#> [5,] NA NA NA NA 12
#>
#> [[13]]
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 2 3 4 5
#> [2,] NA 6 7 8 9
#> [3,] NA NA NA 10 11
#> [4,] NA NA NA NA 12
#> [5,] NA NA NA NA 13
#>
#> [[14]]
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 2 3 4 5
#> [2,] NA 6 7 8 9
#> [3,] NA NA NA 10 11
#> [4,] NA NA NA 12 13
#> [5,] NA NA NA NA 14