如何在R中检查一个矩阵中是否存在固定的模式?

问题描述 投票:0回答:1

我想检查一个矩阵是否存在一个固定的模式 "xxxx "或 "yyyy",(我的矩阵可以有4个x或4个y的序列,不能同时有两个。例如,如果存在4个x的序列,则匹配<- "x",否则匹配<- "y".我想按行、列和(反)对角线来检查。

主要的问题是最后一部分,将 "x "或 "y "分配给变量 "match"。

我的矩阵的例子是。

m <- matrix(NA, 6, 7)
m[6,2:5] <- "x"

我试着将x和y分配到下面的矩阵中

r <- apply(m, 1, paste, collapse="")
c <- apply(m, 2, paste, collapse="") 

if (grepl("xxxx", r, fixed = TRUE) |
      grepl("xxxx", c, fixed = TRUE)){
    match <- "x"}
  else if(grepl("yyyy", r, fixed = TRUE)|
          grepl("yyyy", c, fixed = TRUE)){
    match <- "y"}

然而,这并不奏效,因为 "grepl "返回的是一个逻辑向量,而且它只检查第一个元素是否为真。 我已经苦苦寻找了四天,甚至想不出一个方法来寻找这个模式的对角线。

我是R编程的新手,非常感谢任何帮助。

r regex matrix
1个回答
0
投票

不知道你的输出最终应该是怎样的,但原则上你可以使用 "x{4}" 作为regex,使用 applyapply. 例子:

M
#    [,1] [,2] [,3] [,4] [,5] [,6] [,7]
# [1,] "y"  NA   NA   "x"  NA   NA   NA  
# [2,] NA   "y"  NA   NA   "x"  "x"  NA  
# [3,] "y"  "y"  "y"  "y"  NA   "x"  NA  
# [4,] NA   "y"  "x"  "y"  "y"  "x"  "x" 
# [5,] NA   NA   NA   NA   NA   "x"  NA  
# [6,] NA   "x"  "x"  "x"  "x"  NA   NA 

## rows
apply(M, 1, function(x) grepl("x{4}", Reduce(paste0, x)))
# [1] FALSE FALSE FALSE FALSE FALSE  TRUE
apply(M, 1, function(x) grepl("y{4}", Reduce(paste0, x)))
# [1] FALSE FALSE  TRUE FALSE FALSE FALSE

## columns
apply(M, 2, function(x) grepl("x{4}", Reduce(paste0, x)))
# [1] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
apply(M, 2, function(x) grepl("y{4}", Reduce(paste0, x)))
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE

## diagonals
sapply(split(M, row(M) - col(M)), function(x) grepl("x{4}", Reduce(paste0, x)))
#    -6    -5    -4    -3    -2    -1     0     1     2     3     4     5 
# FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
sapply(split(M, row(M) - col(M)), function(x) grepl("y{4}", Reduce(paste0, x)))
#    -6    -5    -4    -3    -2    -1     0     1     2     3     4     5 
# FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE 

注: 对角线也归功于 @user20650

注2.编辑

stopifnot(identical(apply(m, 1, paste, collapse=""), 
                    apply(m, 1, function(x) Reduce(paste0, x))))

编辑

你可以把逻辑包进一个函数,基于 any,执行上面几行。unlist的结果,并检查是否有任何。TRUE.

checkSequence <- function(M, rx) {
  any(unlist(
    c(sapply(1:2, function(margin) apply(M, margin, function(x) grepl(rx, Reduce(paste0, x)))),
      list(sapply(split(M, row(M) - col(M)), function(x) grepl(rx, Reduce(paste0, x)))))))
}

checkSequence(M, "x{4}")
# [1] TRUE
checkSequence(M, "y{4}")
# [1] TRUE
checkSequence(M, "y{3}")
# [1] TRUE
checkSequence(M, "y{5}")
# [1] FALSE

数据:

M <- unname(as.matrix(read.table(header=T, text='
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] "y"  NA   NA   "x"  NA   NA   NA  
[2,] NA   "y"  NA   NA   "x"  "x"  NA  
[3,] "y"  "y"  "y"  "y"  NA   "x"  NA  
[4,] NA   "y"  "x"  "y"  "y"  "x"  "x" 
[5,] NA   NA   NA   NA   NA   "x"  NA  
[6,] NA   "x"  "x"  "x"  "x"  NA   NA    ')))
© www.soinside.com 2019 - 2024. All rights reserved.