R:在矩阵中创建从 1 到 10 的对角线 -> returns 只有最后一个值

R: create diagonal from 1 to 10 in matrix -> returns only last value

我需要修改一个用随机数填充的矩阵,使生成的矩阵有一条对角线,数字为 1 到 10,其他所有地方都应该为零。 我快完成了,但对角线只显示最后一个值 10,而不是数字 1 到 10。我知道我需要以某种方式缓存结果,但我不知道该怎么做。

rand_mat = matrix(sample(1:50, 100, replace = TRUE), nrow=10, ncol=10)
#10x10 matrix filled with random numbers


for (i in 1:nrow(rand_mat)) {
  #for each row
  for (j in 1:ncol(rand_mat)) {
    #for each column
    for (o in 1:10){
      #go through numbers 1 to 10 for the diagonal
      
      if(i == j){
        #if row matches column -> diagonal
      
      rand_mat[i,j] = o
      #assign numbers 1 to 10 in the diagonal
      

      }else{
        
        rand_mat[i,j] = 0
        #if location is not in the diagonal assign 0
        
      }
      
    }
    
  }
  
}

这是当前结果:

> print(rand_mat)
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]   10    0    0    0    0    0    0    0    0     0
 [2,]    0   10    0    0    0    0    0    0    0     0
 [3,]    0    0   10    0    0    0    0    0    0     0
 [4,]    0    0    0   10    0    0    0    0    0     0
 [5,]    0    0    0    0   10    0    0    0    0     0
 [6,]    0    0    0    0    0   10    0    0    0     0
 [7,]    0    0    0    0    0    0   10    0    0     0
 [8,]    0    0    0    0    0    0    0   10    0     0
 [9,]    0    0    0    0    0    0    0    0   10     0
[10,]    0    0    0    0    0    0    0    0    0    10
> 

仅使用您在问题中使用的函数:

rand_mat = matrix(sample(1:50, 100, replace = TRUE), nrow=10, ncol=10)
rand_mat <- matrix(0, 10, 10)        # Make all the elements 0.
for(i in 1:10) rand_mat[i, i] <- i   # Replace the diagonal elements

你的最内层循环是不必要的。当您遍历 j 时,您将遍历行 i 中的每个 单元格 。因此,如果 i == j 则只需要将值 i 分配给单元格,否则将 0 分配给单元格。您根本不需要变量 o

所以您的代码的 fixed-up 版本可能是:

rand_mat = matrix(sample(1:50, 100, replace = TRUE), nrow=10, ncol=10)

for (i in 1:nrow(rand_mat)) {
  #for each row
  for (j in 1:ncol(rand_mat)) {
    #for each column
      if(i == j) {
        #if row matches column -> diagonal
      
         rand_mat[i,j] <- i
         #assign row number in the diagonal
      } else {
        
        rand_mat[i,j] = 0
        #if location is not in the diagonal assign 0
        
      }
   }
}

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

或者,更简洁:

for (i in 1:nrow(rand_mat)) 
  for (j in 1:ncol(rand_mat)) 
      rand_mat[i, j] <- if(i == j) i else 0

reprex package (v2.0.1)

于 2022-05-14 创建

感谢@dcarlson,我得到了它 他们的代码肯定要短得多,但我真的很想用我的代码看看我做错了什么。结果我不得不在 if-else-loop 中写 rand_mat[o,o] = o 而不是 rand_mat[i,j] = o。所以代码现在看起来像这样:

rand_mat = matrix(sample(1:50, 100, replace = TRUE), nrow=10, ncol=10)
#10x10 matrix filled with random numbers


for (i in 1:nrow(rand_mat)) {
  #for each row
  for (j in 1:ncol(rand_mat)) {
    #for each column
    for (o in 1:10){
      #go through numbers 1 to 10 for the diagonal
      
      if(i == j){
        #if row matches column -> diagonal
      
      rand_mat[o,o] = o
      #assign numbers 1 to 10 in the diagonal

      }else{
        
        rand_mat[i,j] = 0
        #if location is not in the diagonal assign 0
        
      }
      
    }
    
  }
  
}

结果看起来像我用 @dcarlson

中的代码尝试的结果
> print(rand_mat)
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1    0    0    0    0    0    0    0    0     0
 [2,]    0    2    0    0    0    0    0    0    0     0
 [3,]    0    0    3    0    0    0    0    0    0     0
 [4,]    0    0    0    4    0    0    0    0    0     0
 [5,]    0    0    0    0    5    0    0    0    0     0
 [6,]    0    0    0    0    0    6    0    0    0     0
 [7,]    0    0    0    0    0    0    7    0    0     0
 [8,]    0    0    0    0    0    0    0    8    0     0
 [9,]    0    0    0    0    0    0    0    0    9     0
[10,]    0    0    0    0    0    0    0    0    0    10
> 

但是正如我从@Allan Cameron 那里了解到的,你不需要变量 o 所以你甚至不需要第三个 for-loop:

rand_mat = matrix(sample(1:50, 100, replace = TRUE), nrow=10, ncol=10)

for (i in 1:nrow(rand_mat)) {
  #for each row
  for (j in 1:ncol(rand_mat)) {
    #for each column
    if(i == j) {
      #if row matches column -> diagonal
      
      rand_mat[i,j] <- i
      #assign row number in the diagonal
      
    } else {
      
      rand_mat[i,j] = 0
      #if location is not in the diagonal assign 0
      
    }
  }
}

结果是一样的。感谢您的帮助!

虽然这不是执行此操作的有效方法(如评论中所述),但您可以通过删除最内层循环并将其替换为赋值来修复代码:

for (i in 1:nrow(rand_mat)) {
  for (j in 1:ncol(rand_mat)) {
    rand_mat[i,j] = if(i == j) i else 0 
      }
    }