给矩阵对角线元素赋值

12

我需要在for循环中访问和分配m*n矩阵的单个槽位。到目前为止的代码:

rowCount <- 9
similMatrix = matrix(nrow = rowCount - 1, ncol = rowCount)
show(similMatrix)
for(i in (rowCount - 1)){
  for (j in rowCount)
    if (i == j){
      similMatrix[i == j] <- 0;
    }
}
show(similMatrix)

所以如果i等于j,矩阵中的NA值需要替换为0。


你没有得到期望的输出吗? - rotating_image
2个回答

40
你想使用函数diag<-
m <- matrix(1:12, nrow=3)
m
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

diag(m) <- 0
m
     [,1] [,2] [,3] [,4]
[1,]    0    4    7   10
[2,]    2    0    8   11
[3,]    3    6    0   12

1
那个“删除我的答案并点赞其他答案”的按钮在哪里? - mnel
谢谢,它有效了,但是我现在怎么为m[1,2]赋值呢? - DI MI

14

针对将“对角线”元素置零的目的,您已经得到了一个答案,但我想知道您是否希望得到更一般的东西。失败的原因有两个:索引构造错误和索引错误。这个代码将成功:

for(i in 1:(rowCount - 1)){  # need an expression that retruns a sequence
  for (j in 1:rowCount)      # ditto
    if (i == j){
      similMatrix[i,j] <- 0;  # need to index the matrix with two element if using i,j
    }
}
#----------
> show(similMatrix)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    0   NA   NA   NA   NA   NA   NA   NA   NA
[2,]   NA    0   NA   NA   NA   NA   NA   NA   NA
[3,]   NA   NA    0   NA   NA   NA   NA   NA   NA
[4,]   NA   NA   NA    0   NA   NA   NA   NA   NA
[5,]   NA   NA   NA   NA    0   NA   NA   NA   NA
[6,]   NA   NA   NA   NA   NA    0   NA   NA   NA
[7,]   NA   NA   NA   NA   NA   NA    0   NA   NA
[8,]   NA   NA   NA   NA   NA   NA   NA    0   NA

但在R中使用循环通常被认为是最后的手段(有时是出于错误的原因)。有一种更简洁的方法来执行相同的“循环”操作,而且它适用范围比只设置对角线要广泛得多。

similMatrix[ row(similMatrix) == col(similMatrix) ] <- 0
> similMatrix
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    0   NA   NA   NA   NA   NA   NA   NA   NA
[2,]   NA    0   NA   NA   NA   NA   NA   NA   NA
[3,]   NA   NA    0   NA   NA   NA   NA   NA   NA
[4,]   NA   NA   NA    0   NA   NA   NA   NA   NA
[5,]   NA   NA   NA   NA    0   NA   NA   NA   NA
[6,]   NA   NA   NA   NA   NA    0   NA   NA   NA
[7,]   NA   NA   NA   NA   NA   NA    0   NA   NA
[8,]   NA   NA   NA   NA   NA   NA   NA    0   NA

如果您想将次对角线设置为零,您可以使用以下代码:

similMatrix[ row(similMatrix)-1 == col(similMatrix) ] <- 0

您可以使用以下方法避免生成额外的行和列矩阵:

 mind <- min( dim(similMatrix) )
 # avoid going outside dimensions if not symmetric
 similMatrix[ cbind( seq(maxd),seq(maxd) ) <- 0

1
我想row(mat)col(mat)会生成两个矩阵,这难道不意味着我们在这里要三倍的内存消耗吗?如果mat很大,我想这可能会引起问题。 - qed
非常正确。我没有看到任何警告,这些都是大矩阵。我提供的“紧凑性”在表达上,但正如你所指出的,这可能在内存占用方面不够紧凑。可以想象使用similMatrix[cbind(1:(rowCount - 1), 1:(rowCount - 1)] <- 0,我猜它会在内存和速度方面表现更好。我认为这可能比mat[diag(mat)] <-0方法的占用空间更小。 - IRTFM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接