我有v<- c(2,4,5)
和mat<- matrix(0,n,n)
。
我想替换矩阵上部的向量,我识别的每个位置,数组都替换为向量的长度数。例如,对于 n=5,输出可以是:
[,1] [,2] [,3] [,4] [,5]
[1,] 0 2 4 0 0
[2,] 0 0 5 0 0
[3,] 0 0 0 0 0
[4,] 0 0 0 0 0
[5,] 0 0 0 0 0
我尝试使用以下代码:
mat <- matrix(0, nrow = 5, ncol = 5)
for (i in 1:5){
for (j in 1:5){
if (i<j & j<= 5){
mat [upper.tri(mat, diag = FALSE)]<- v
}
}
}
但输出是:
[,1] [,2] [,3] [,4] [,5]
[1,] 0 2 4 2 2
[2,] 0 0 5 4 4
[3,] 0 0 0 5 5
[4,] 0 0 0 0 2
[5,] 0 0 0 0 0
我有两个问题:
我希望向量在矩阵中只替换一次并且不重复。
我不知道我必须在循环中的哪里替换 i 和 j 来替换矩阵的起始点以替换向量。(也许我想从矩阵中的 [3,4] 开始向量。) .例如:
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 2 4
[4,] 0 0 0 0 5
[5,] 0 0 0 0 0
最佳答案
当您从向量填充矩阵时,需要了解两件事:
- 它按列填充它们;和
- 如果向量比要填充的矩阵部分短,则向量将被回收(重复)。
此外,在您的代码中,您使用两个嵌套的 for
循环,其明显意图是仅对矩阵内的那些索引进行操作...但是您不会引用 i
和 j
在矩阵子集或赋值中,因此每次它尝试替换单个值时,都会用整个向量替换整个矩阵上三角。
这里有一个更快的方法:
mat <- matrix(0, nrow = 5, ncol = 5)
v <- c(2, 4, 5)
mat[upper.tri(mat)][seq_along(v)] <- v
mat
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 2 4 0 0
# [2,] 0 0 5 0 0
# [3,] 0 0 0 0 0
# [4,] 0 0 0 0 0
# [5,] 0 0 0 0 0
正如您所知,mat
上的第一个索引是上三角。第二个子集只是该子集的length(v)
。
如果你想在上三角的任意位置替换它,这里有一个镜头:
mat <- matrix(0, nrow = 5, ncol = 5)
ut <- upper.tri(mat)
fullv <- integer(sum(ut)) # the size of the matrix subset
fullv
# [1] 0 0 0 0 0 0 0 0 0 0
fullv[5 + seq_along(v)] <- v
fullv
# [1] 0 0 0 0 0 2 4 5 0 0
mat[ut] <- fullv
mat
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 0 0 0 4
# [2,] 0 0 0 0 5
# [3,] 0 0 0 2 0
# [4,] 0 0 0 0 0
# [5,] 0 0 0 0 0
在这里,我们演示了填充是按列完成的,这不是您所要求的。为了更好地了解这种填充是如何发生的,
mat <- matrix(0, nrow = 5, ncol = 5)
ut <- upper.tri(mat)
mat[ut] <- seq_len(sum(ut))
mat
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 1 2 4 7
# [2,] 0 0 3 5 8
# [3,] 0 0 0 6 9
# [4,] 0 0 0 0 10
# [5,] 0 0 0 0 0
因此,如果您希望 v
出现在非常具体的位置,并且按照此顺序它们不是连续的,那么您需要具体说明:
mat <- matrix(0, nrow = 5, ncol = 5)
ut <- upper.tri(mat)
mat[ut][c(6,9,10)] <- v
mat
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 0 0 0 0
# [2,] 0 0 0 0 0
# [3,] 0 0 0 2 4
# [4,] 0 0 0 0 5
# [5,] 0 0 0 0 0
关于用向量替换三角形矩阵的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61142577/