简体   繁体   中英

Find a pattern in a Matrix in R?

I have this 25x25 matrix called 'a' which contains 1s and 0s and I need to the total number of specific patterns in it.

    V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25
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   0
2   0  0  0  0  0  0  0  0  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
3   0  0  0  0  0  0  0  0  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
4   0  0  0  0  0  0  0  0  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
5   0  0  0  0  0  0  0  0  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
6   0  0  0  0  0  0  0  1  1   1   1   1   0   0   0   0   0   0   0   0   0   0   0   0   0
7   0  0  0  0  0  0  1  1  1   1   1   1   1   0   0   0   0   0   0   0   0   0   0   0   0
8   0  0  0  0  0  1  1  0  0   0   0   0   1   1   1   0   0   0   0   0   0   0   0   0   0
9   0  0  0  0  1  1  0  0  0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0
10  0  0  0  0  1  0  0  0  0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0
11  0  0  0  0  1  0  0  0  0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0
12  0  0  0  0  1  0  0  0  0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0
13  0  0  0  0  1  0  0  0  0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0
14  0  0  0  0  1  0  0  0  0   0   0   0   0   0   1   0   0   0   0   0   0   0   0   0   0
15  0  0  0  0  1  0  0  0  0   0   0   0   0   1   1   0   0   0   0   0   0   0   0   0   0
16  0  0  0  0  1  0  0  0  0   0   0   0   0   1   1   0   0   0   0   0   0   0   0   0   0
17  0  0  0  0  1  1  0  0  0   0   0   0   1   1   1   1   0   0   0   0   0   0   0   0   0
18  0  0  0  0  0  1  1  0  0   0   0   1   1   0   0   1   0   0   0   0   0   0   0   0   0
19  0  0  0  0  0  0  1  1  1   1   1   1   0   0   0   1   1   0   0   0   0   0   0   0   0
20  0  0  0  0  0  0  0  0  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
21  0  0  0  0  0  0  0  0  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
22  0  0  0  0  0  0  0  0  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
23  0  0  0  0  0  0  0  0  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
24  0  0  0  0  0  0  0  0  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
25  0  0  0  0  0  0  0  0  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

An example of a pattern I need to find is a left2tile pattern:

      [,1] [,2]
[1,]    1    0
[2,]    1    0

Or a right2tile pattern:

      [,1] [,2]
[1,]    0    1
[2,]    0    1

Anyone have any advice on how to solve this?

Here's a brute-force method.

Assuming a matrix :

str(a)
#  int [1:25, 1:25] 0 0 0 0 0 0 0 0 0 0 ...
#  - attr(*, "dimnames")=List of 2
#   ..$ : chr [1:25] "1" "2" "3" "4" ...
#   ..$ : chr [1:25] "V1" "V2" "V3" "V4" ...

head(matches <- which(a == left2tile[1,1], arr.ind = TRUE))
#    row col
# 9    9   5
# 10  10   5
# 11  11   5
# 12  12   5
# 13  13   5
# 14  14   5

nrow(matches)
# [1] 55

This says that there are 55 matches for the top-left element of left2tile within a , which is just a start. The first one is as [9,5] , second (column-wise) is [10,5] , etc.

From here:

matches2 <- Map(function(i,j) a[i+0:1,j+0:1], matches[,1], matches[,2])
head(matches2, 3)
# $`9`
#    V5 V6
# 9   1  1
# 10  1  0
# $`10`
#    V5 V6
# 10  1  0
# 11  1  0
# $`11`
#    V5 V6
# 11  1  0
# 12  1  0

Here, we have the first three submatrices of the matches. We can then test for equality:

(matches3 <- sapply(matches2, function(z) all(z == left2tile)))
#     9    10    11    12    13    14    15    16    17     8     9    17    18     7     8    18    19     6     7    19 
# FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
#     6     7    19     6     7    19     6     7    19     6     7    18    19     7     8    17    18     8    15    16 
# FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
#    17     8     9    10    11    12    13    14    15    16    17    17    18    19    19 
# FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE 

Where a TRUE indicates that that element within matches does contain the submatrix match. We can use

matches[matches3,]
#    row col
# 10  10   5
# 11  11   5
# 12  12   5
# 13  13   5
# 14  14   5
# 15  15   5
# 8    8  15
# 9    9  15
# 10  10  15
# 11  11  15
# 12  12  15
# 13  13  15
# 14  14  15
# 15  15  15
# 17  17  16

to give us the top-left of each submatrix within a that matches left2tile .

I would expect (and it is true here) that all of matches2[matches3] are the same as your left2tile .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM