A Vector to an Upper Triangle Matrix by Row in R

a vector to an upper Triangle matrix by row in R

Here's one option

b[lower.tri(b, diag=FALSE)] <- a
b <- t(b)
b
# [,1] [,2] [,3] [,4]
# [1,] 0 1 2 3
# [2,] 0 0 4 5
# [3,] 0 0 0 6
# [4,] 0 0 0 0

Alternatively, reorder a as required and assign that into the upper-right triangle:

ut <- upper.tri(b, diag=FALSE)
b[ut] <- a[order(row(ut)[ut], col(ut)[ut])]
b
[,1] [,2] [,3] [,4]
[1,] 0 1 2 3
[2,] 0 0 4 5
[3,] 0 0 0 6
[4,] 0 0 0 0

Converting a vector in R into a lower/upper triangular matrix in specific order

You can fill up the upper triangular matrix by doing

mat <- matrix(0, nrow = 4, ncol = 4)
mat[upper.tri(mat, diag = TRUE)] <- v

mat
# [,1] [,2] [,3] [,4]
#[1,] 1 2 4 7
#[2,] 0 3 5 8
#[3,] 0 0 6 9
#[4,] 0 0 0 10

Lower triangle doesn't follow the same sequence as upper triangle so doing

mat[lower.tri(mat, diag = TRUE)] <- v

doesn't give the expected outcome.

We can get the indices of lower triangle, order them according to row and then update the matrix

order_mat <- which(lower.tri(mat, diag = TRUE), arr.ind = TRUE)
mat[order_mat[order(order_mat[, 1]), ]] <- v

mat
# [,1] [,2] [,3] [,4]
#[1,] 1 0 0 0
#[2,] 2 3 0 0
#[3,] 4 5 6 0
#[4,] 7 8 9 10

Or as @Gregor commented a much simpler way is to transpose the upper triangular result

mat <- matrix(0, nrow = 4, ncol = 4)
mat[upper.tri(mat, diag = TRUE)] <- v #Upper triangle
t(mat) #Lower triangle

Extracting values of upper triangle by row order

We can do a transpose and take the lower.tri

t(mat)[lower.tri(t(mat))]
#[1] 5 9 13 10 14 15

replace a vector to an upper Triangle matrix with different length

You could adjust the length of v to that of the upper triangle. This yields some NA values that you can replace with zeroes.

u.tri <- upper.tri(mat, diag=FALSE)
mat[u.tri] <- `length<-`(v, length(u.tri))
mat[is.na(mat)] <- 0
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 1 2 4 0
# [2,] 0 0 3 5 0
# [3,] 0 0 0 6 0
# [4,] 0 0 0 0 0
# [5,] 0 0 0 0 0

Fill lower matrix with vector by row, not column

Just read it into the upper triangular portion, rather than the lower:

S <- diag(6)
S[upper.tri(S, diag=TRUE)] <- d
t(S)

Replacing upper triangular matrix elements in row order

The value insertions are in column order (in matrix, data.frame). We may assign on the lower.tri and then get the transpose

ex_mat_new[lower.tri(ex_mat_new)] <- rank(-(t(ex_mat)[lower.tri(ex_mat)]))
ex_mat_new <- t(ex_mat_new)
ex_mat_new[lower.tri(ex_mat_new)] <- ex_mat[lower.tri(ex_mat)]

-output

> ex_mat_new
[,1] [,2] [,3] [,4]
[1,] 0.4270634 2.0000000 5.0000000 3.0000000
[2,] 2.0556220 1.1157322 1.0000000 6.0000000
[3,] 1.2252602 0.1063053 0.6396099 4.0000000
[4,] 0.3614062 1.1118661 0.5000143 0.2491543

or this can be done in a single line with replace

t(replace(t(ex_mat), lower.tri(ex_mat), rank(-(t(ex_mat)[lower.tri(ex_mat)]))))

-output

       [,1]      [,2]      [,3]      [,4]
[1,] 0.4270634 2.0000000 5.0000000 3.0000000
[2,] 2.0556220 1.1157322 1.0000000 6.0000000
[3,] 1.2252602 0.1063053 0.6396099 4.0000000
[4,] 0.3614062 1.1118661 0.5000143 0.2491543

data

ex_mat <- structure(c(0.4270634, 2.055622, 1.2252602, 0.3614062, 2.192089, 
1.1157322, 0.1063053, 1.1118661, 0.5647472, 2.6723637, 0.6396099,
0.5000143, 1.7149861, 0.3155507, 0.7903348, 0.2491543), .Dim = c(4L,
4L), .Dimnames = list(NULL, NULL))

Converting a vector in R into a lower triangular matrix in specific order

Here's one way:

x <- c(2, 4, 7)
M <- matrix(0, length(x), length(x))
M[lower.tri(M, diag = TRUE)] <- rev(x)[sequence(length(x):1)]
M
# [,1] [,2] [,3]
# [1,] 7 0 0
# [2,] 4 7 0
# [3,] 2 4 7

Outer in R but only get upper matrix?

We can use upper.tri from base R to create a logical matrix and subset the elements

out <- outer(x, x, f)
out[upper.tri(out)]

Instead of using outer, this can be done with combn

combn(x, 2, FUN = f)

Also, for a fast option,

arrangements::combinations(x, k = 2)

can return the combinations and then apply the 'f' on those



Related Topics



Leave a reply



Submit