【问题标题】:Nested for loop for evaluating surrounding cells of matrix in R嵌套for循环用于评估R中矩阵的周围单元格
【发布时间】:2014-10-25 03:35:24
【问题描述】:

我有一个 7x7 矩阵:

Mat<-matrix(nrow=7,ncol=7)

带有某些元素:

Mat[2,2]<-37
Mat[2,4]<-39
Mat[2,6]<-24
Mat[4,2]<-35
Mat[4,4]<-36
Mat[4,6]<-26
Mat[6,2]<-26
Mat[6,4]<-31
Mat[6,6]<-39

我正在生成随机元素,并想测试它们加起来是否达到指定值

我写了以下代码:

TF<-c()
TF[1]<-isTRUE(Mat[2,2]==sum(Mat[1,1],Mat[1,2],Mat[1,3],Mat[2,1],Mat[2,3],Mat[3,1],Mat[3,2],Mat[3,3]))
TF[2]<-isTRUE(Mat[2,4]==sum(Mat[1,3],Mat[1,4],Mat[1,5],Mat[2,3],Mat[2,5],Mat[3,3],Mat[3,4],Mat[3,5]))
TF[3]<-isTRUE(Mat[2,6]==sum(Mat[1,5],Mat[1,6],Mat[1,7],Mat[2,5],Mat[2,7],Mat[3,5],Mat[3,6],Mat[3,7]))
TF[4]<-isTRUE(Mat[4,2]==sum(Mat[3,1],Mat[3,2],Mat[3,3],Mat[4,3],Mat[4,5],Mat[5,1],Mat[5,2],Mat[5,3]))
TF[5]<-isTRUE(Mat[4,4]==sum(Mat[3,3],Mat[3,4],Mat[3,5],Mat[4,3],Mat[4,5],Mat[5,3],Mat[5,4],Mat[5,5]))
TF[6]<-isTRUE(Mat[4,6]==sum(Mat[3,5],Mat[3,6],Mat[3,7],Mat[4,5],Mat[4,7],Mat[5,5],Mat[5,6],Mat[5,7]))
TF[7]<-isTRUE(Mat[6,2]==sum(Mat[5,1],Mat[5,2],Mat[5,3],Mat[6,1],Mat[6,3],Mat[7,1],Mat[7,2],Mat[7,3]))
TF[8]<-isTRUE(Mat[6,4]==sum(Mat[5,3],Mat[5,4],Mat[5,5],Mat[6,3],Mat[6,5],Mat[7,3],Mat[7,4],Mat[7,5]))
TF[9]<-isTRUE(Mat[6,6]==sum(Mat[5,5],Mat[5,6],Mat[5,7],Mat[6,5],Mat[6,7],Mat[7,5],Mat[7,6],Mat[7,7]))

现在我正在尝试使用嵌套的 for 循环使其更高效:

O<-c(2,4,6)
for (G in O)
{
for (H in O)
{
TF[]<-isTRUE(Mat[G,H]==sum(Mat[G-1,H-1],Mat[G-1,H],Mat[G-1,H+1],Mat[G,H-1],Mat[G,H+1],Mat[G+1,H-1],Mat[G+1,H],Mat[G+1,H+1]))
}
}

问题是向量元素将被覆盖,添加另一个for循环没有任何意义。 如果发现一个错误,我也很难找到重新运行模拟的方法。

【问题讨论】:

  • 如果您分配一个新对象并用新值填充它,它不会被覆盖。另外,请查看apply。此外,solve 是一个函数。您将其用作矩阵名称?
  • @RichardScriven,虽然这个问题的措辞并不出色,但我认为这个问题本身很酷。当然apply 不能真正做到这一点,因为跨行/列依赖(如果可以的话,我很好奇apply 将如何完成)。
  • @BrodieG 和 OP,如果出现错误的方式,我们深表歉意。我刚刚提到可以为新的TF 值分配一个新变量,我对您对solve 的使用感到困惑。这是一个非常有趣的问题。
  • @RichardScriven,就我而言没问题。
  • 是的,我使用 solve 作为矩阵的名称。会改变的,谢谢。如果你们有兴趣,我会让你们了解最新进展,或者也对代码提出问题和答案。我已经编写了代码,但我只是在改进它以提高工作效率。

标签: r for-loop indexing


【解决方案1】:

让我们首先回答以下问题:

如何计算矩阵中每个单元格的每个周围单元格的总和?

据我所知,这实际上并非微不足道(很想看看其他人是否想出了一些很酷的东西)。这是一个潜在的解决方案,尽管还不够简洁。让我们从查看函数的结果开始。在这里,我们将创建只有 1 的矩阵,以便我们可以检查结果是否有意义(角应该添加到 3,因为只有三个连续的单元格,内部到 8 等):

> compute_neighb_sum(matrix(1, nrow=3, ncol=3))
     [,1] [,2] [,3]
[1,]    3    5    3
[2,]    5    8    5
[3,]    3    5    3
> compute_neighb_sum(matrix(1, nrow=3, ncol=5))
     [,1] [,2] [,3] [,4] [,5]
[1,]    3    5    5    5    3
[2,]    5    8    8    8    5
[3,]    3    5    5    5    3
> compute_neighb_sum(matrix(1, nrow=7, ncol=7))
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    3    5    5    5    5    5    3
[2,]    5    8    8    8    8    8    5
[3,]    5    8    8    8    8    8    5
[4,]    5    8    8    8    8    8    5
[5,]    5    8    8    8    8    8    5
[6,]    5    8    8    8    8    8    5
[7,]    3    5    5    5    5    5    3

这行得通!

现在,让我们回答您的实际问题

compute_neighb_sum(mx) == mx

这应该为所有等于其周围总和的单元格返回TRUE。让我们确认一下:

mx <- matrix(1, nrow=7, ncol=7)
mx[cbind(c(3, 6), c(3, 6))] <- 8   # make two interior cells equal two 8, which will be equal to sum of surroundings
which(compute_neighb_sum(mx) == mx, arr.ind=T) # you should look at `mx` to see what's going on

果然,我们得到了我们期望的坐标:

     row col
[1,]   3   3
[2,]   6   6

现在,函数如下:

compute_neighb_sum <- function(mx) {
  mx.ind <- cbind(        # create a 2 wide matrix of all possible indices in input
    rep(seq.int(nrow(mx)), ncol(mx)), 
    rep(seq.int(ncol(mx)), each=nrow(mx))
  )
  sum_neighb_each <- function(x) {
    near.ind <- cbind(         # for each x, y coord, create an index of all surrounding values
      rep(x[[1]] + -1:1, 3),
      rep(x[[2]] + -1:1, each=3)
    )
    near.ind.val <- near.ind[  # eliminate out of bound values, or the actual x,y coord itself
      !(
        near.ind[, 1] < 1 | near.ind[, 1] > nrow(mx)  |
        near.ind[, 2] < 1 | near.ind[, 2] > ncol(mx)  |
        (near.ind[, 1] == x[[1]] & near.ind[, 2] == x[[2]])
      ),
     ]
    sum(mx[near.ind.val])      # Now sum the surrounding cell values
  }
  `dim<-`(                     # this is just to return in same matrix format as input
    sapply(
      split(mx.ind, row(mx.ind)),   # For each x, y coordinate in input mx
      sum_neighb_each               # compute the neighbor sum
    ),
    c(nrow(mx), ncol(mx))      # dimensions of input
  )  
}

【讨论】:

  • 非常感谢@BordieG 非常好的回答。只是不知道它是否 100% 适合我的问题,但会尝试调整代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
  • 2018-05-31
  • 2021-02-24
  • 1970-01-01
  • 2019-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多