首页 > 解决方案 > 如何在 R 中一次在多个不同的数据帧中找到 6 个或更多其他 0 连接的 0 的数量?

问题描述

如何在工作目录中的不同 csv 文件中保存的多个不同数据帧中的 0 的数量在其上方、下方、左侧、右侧和对角线的位置也连接到 6 个或更多 0?

我已使用以下方式读取目录中的所有 csv 文件:

csv_files <- list.files(pattern="*.csv")
csv_files <- lapply(csv_files, read.delim)

这些 csv 文件中的矩阵如下所示:

0   0   0   0   0   0   0   0   0   0
0   0   1   1   1   1   0   0   0   0
0   0   1   1   1   1   1   0   0   0
0   0   1   0   0   1   1   0   0   0
0   1   1   0   0   1   0   0   0   0
0   1   0   0   0   1   1   0   0   0
0   1   0   0   0   1   1   0   0   0
0   1   1   1   1   1   0   0   0   0
0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   0

但有些更大(即 50 x 50)。是否可以一次对所有文件执行此操作?

情况示例

一个可重现的例子:

set.seed(99) # for reproducibility
mat <- matrix(sample(c(0,1), 100, replace=TRUE), nrow=10) # sample matrix
mat

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

window <- matrix(rep(1,9), nrow=3) # window to count number of 1s
window

      [,1] [,2] [,3]
[1,]    1    1    1
[2,]    1    1    1
[3,]    1    1    1

window[2,2] <- 20  
window

      [,1] [,2] [,3]
[1,]    1    1    1
[2,]    1   20    1
[3,]    1    1    1

 sum(sapply(1:(nrow(files)-2), function(i) t(sapply(1:(ncol(mat)-2), 
 function(j) sum(window * mat[i:(i+2),j:(j+2)])))) >= 6)

[1] 43

标签: rcsvdataframe

解决方案


首先,您需要编写一个函数来计算周围至少有六个零的零的数量...

set.seed(99)                                               #for reproducibility
mat <- matrix(sample(c(0,1), 100, prob=c(0.8,0.2), 
              replace=TRUE),
              nrow=10)                                     #sample matrix

window <- matrix(rep(1,9), nrow=3)                         #window to count number of 1s
window[2,2] <- 20                                          #penalty for 1 in centre

mat
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    0    0    0    0    1    0    1    0    0     0
 [2,]    0    0    0    0    0    1    0    0    0     1
 [3,]    0    0    1    0    0    0    0    0    0     0
 [4,]    1    0    0    0    1    1    0    0    0     0
 [5,]    0    0    0    0    0    0    0    0    0     0
 [6,]    1    0    0    0    1    1    1    0    0     0
 [7,]    0    0    0    0    0    0    0    0    0     1
 [8,]    0    0    1    1    0    0    1    0    0     0
 [9,]    0    0    0    0    0    1    0    0    0     0
[10,]    0    0    0    1    0    0    1    0    1     0

window
     [,1] [,2] [,3]
[1,]    1    1    1
[2,]    1   20    1
[3,]    1    1    1

然后,此函数将计算每个 3x3 窗口中 1 的数量,如果中间有 1,则惩罚 20,并返回矩阵中总数小于 3 的条目数:

check_zeros <- function(mat){
   sum(sapply(1:(nrow(mat)-2),
                 function(i) t(sapply(1:(ncol(mat)-2),
                                      function(j) sum(window * mat[i:(i+2),j:(j+2)])
                                     )
                              )
              ) < 3)
    }

check_zeros(mat)
[1] 39

现在您可以使用

sapply(csv_files, check_zeros)

推荐阅读