【问题标题】:Count values within moving matrix subset计算移动矩阵子集中的值
【发布时间】:2017-07-24 15:56:50
【问题描述】:

说出下面的矩阵

mat = round(matrix(runif(100), ncol = 5))
mat
      [,1] [,2] [,3] [,4] [,5]
 [1,]    0    1    0    1    0
 [2,]    0    0    1    1    1
 [3,]    1    1    1    1    1
 [4,]    1    0    1    0    1
 [5,]    1    0    0    1    1
 [6,]    1    0    0    1    1
 [7,]    1    0    1    1    1
 [8,]    1    1    1    0    1
 [9,]    0    0    0    1    0
[10,]    0    0    0    1    1
[11,]    0    0    0    0    0
[12,]    1    1    0    0    1
[13,]    1    1    0    1    0
[14,]    1    0    1    0    1
[15,]    0    1    1    0    0
[16,]    1    1    0    1    1
[17,]    1    1    1    0    1
[18,]    1    1    1    1    1
[19,]    0    1    0    0    1
[20,]    1    1    0    0    0

我想生成一个新矩阵,它是原始矩阵每个单元格周围 3x3 方形子集中的“1”数。 例如

mat_sum
           [,1] [,2] [,3] [,4] [,5]
    [1,]    1    2    4    4    3
    [2,]    3    5    6    7    5
    [3,]    3    6    6    8    5
    etc.

我尝试了以下循环,但它没有给出我需要的东西

for(x in 1:(nrow(mat)-3)){
    for (y in 1:(ncol(mat)-3)){
        mat2[x,y] = sum(mat[c(x:x+2), c(y:y+2)] == 1))
}}

我需要能够将子集扩展到我的数据上的 10x10 框(> 1000x1000 单元格)。任何提示表示赞赏!谢谢

【问题讨论】:

    标签: r matrix subset


    【解决方案1】:
    #DATA
    set.seed(42)
    mat = round(matrix(runif(20), ncol = 5))
    mat
    #     [,1] [,2] [,3] [,4] [,5]
    #[1,]    1    1    1    1    1
    #[2,]    1    1    1    0    0
    #[3,]    0    1    0    0    0
    #[4,]    1    0    1    1    1
    

    对于ith 行和jth 列中的每个元素,获取矩阵中i-1i+1 行和j-1j+1 列中的元素总和。如果值超出范围,请根据需要替换为最小或最大索引。

    t(sapply(1:NROW(mat), function(i)
        sapply(1:NCOL(mat), function(j)
            sum(mat[max(1, i-1):min(NROW(mat), i+1), max(1, j-1):min(NCOL(mat), j + 1)]))))
    #     [,1] [,2] [,3] [,4] [,5]
    #[1,]    4    6    5    4    2
    #[2,]    5    7    6    4    2
    #[3,]    4    6    5    4    2
    #[4,]    2    3    3    3    2
    

    【讨论】:

    • 感谢 d.b,但我没有得到和你一样的桌子.. :-/
    • 啊确实不是!我忘记了 runif 每次都会给出一个随机数据集 ;-) 它工作得很好!
    【解决方案2】:

    最简单的方法是编写一个获取邻居的函数,然后求和。

    set.seed(42)
    
    mat = round(matrix(runif(100), ncol = 5))
    mat_sum = matrix(nrow=20, ncol=5)
    
    for(x in seq_len(nrow(mat))) {
      for (y in seq_len(ncol(mat))) {
        mat_sum[x,y] <- sum(getNeighbors(x, y, mat))
      }
    }
    
    getNeighbors <- function(x, y, mat) {
      unlist(mat[((x-2):(x)) %% nrow(mat) + 1, ((y-2):(y)) %% ncol(mat) + 1])
    }
    

    你不需要和 1 比较,因为 sum(1, 1, 0) 和 sum(TRUE, TRUE, FALSE) 是一样的。

    【讨论】:

    • 感谢 ConCave,我了解您的建议。唯一的问题是当单元格位于边缘时。子集不完整,并使用矩阵另一侧的值完成
    • 我现在看到这不是预期的行为——我只看了右上角并没有看到它们不应该环绕,因为上面有很多零底端。现在修正我的答案。
    猜你喜欢
    • 2020-03-21
    • 2012-02-27
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 2011-04-11
    • 1970-01-01
    相关资源
    最近更新 更多