【问题标题】:How to check if there exist a fixed pattern in a matrix in R?如何检查R中的矩阵中是否存在固定模式?
【发布时间】:2020-06-06 10:04:26
【问题描述】:

我想检查一个矩阵以查看是否存在固定模式“xxxx”或“yyyy”,(我的矩阵可以有 4 个 x 或 4 个 y 的序列,不能同时有两个。除非它小于大于 4)。然后如果例如存在 4 个 x 的序列,则匹配

主要问题在于最后一部分,将“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”返回一个逻辑向量并且它只检查第一个元素是否为真。 我已经努力寻找方法 4 天了,甚至想不出一种方法来尝试在对角线上找到这种模式。

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

【问题讨论】:

  • 给定矩阵m 的输出是什么?
  • 感谢您的评论,我刚刚更新了我的问题。希望我已经解释清楚了。 @RonakShah

标签: r regex matrix


【解决方案1】:

不确定您的输出最终应该是什么样子,但原则上您可以使用"x{4}" 作为正则表达式并使用apply/apply例子:

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 将逻辑包装到一个函数中,该函数执行上面的行,unlists 结果,并检查是否有任何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    ')))

【讨论】:

  • 这个答案在对角线部分帮助了我,但我的主要问题仍然是逻辑向量输出,如果存在,我只想要一个逻辑答案“真”,否则为“假”。所以我可以在 if else 语句中使用它。
  • 如果任何行/列/对角线包括xxxxOR yyyy,您是否应该声明yield TRUE
  • 是的,这正是我想要的。因此,如果为真,基于 x 或 y 模式,我可以将“x”或“y”分配给变量匹配。我试图在我的示例代码中展示这一点。
  • @Nel 我明白了,请查看更新。请注意,这也包括诸如yyy 之类的序列,因为它是yyyy 的子集。
  • 你的回答对我进一步了解R编程很有帮助,但是对于这个问题我还是只想要xxxx,大于4可以但不能小于。
猜你喜欢
  • 2014-05-09
  • 1970-01-01
  • 2019-03-09
  • 2011-05-16
  • 2017-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
相关资源
最近更新 更多