[英]How to check if there exist a fixed pattern in a matrix in R?
I want to check a matrix to see if there exist a fixed pattern "xxxx" or "yyyy", (my matrix can have sequence of either 4 x's or 4 y's, not both at the same time. unless it is less than 4).我想检查一个矩阵,看看是否存在固定模式“xxxx”或“yyyy”,(我的矩阵可以有4个x或4个y的序列,不能同时有。除非它小于4) . Then if for example a sequence of 4 x exists, match <- "x", otherwise match <- "y".
然后,例如,如果存在 4 个 x 的序列,则匹配 <-“x”,否则匹配 <-“y”。 I want to check it row-wise, column-wise and (anti)diagonal-wise.
我想按行、按列和(反)对角线检查它。
The main problem is with the last part, to assign "x" or "y" to the variable "match".主要问题在于最后一部分,将“x”或“y”分配给变量“match”。
An example of my matrix is:我的矩阵的一个例子是:
m <- matrix(NA, 6, 7)
m[6,2:5] <- "x"
I tried as below for x and y:我对 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"}
However, it does not work since "grepl" returns a logical vector and it only checks if the first element is true.但是,它不起作用,因为“grepl”返回一个逻辑向量并且它只检查第一个元素是否为真。 I've been struggling to find a way for 4 days already, could not even think of a way to try to find this pattern diagonal wise.
我已经努力寻找 4 天的方法了,甚至想不出一种方法来尝试以对角线方式找到这种模式。
I am new to programming with R, would very much appreciate any help.我是使用 R 编程的新手,非常感谢任何帮助。
Not sure about how your output finally should look like, but in principle you could use "x{4}"
as regex and use apply
/ apply
.不确定您的 output 最终应该是什么样子,但原则上您可以使用
"x{4}"
作为正则表达式并使用apply
/ apply
。 Example:例子:
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
Note: Credits for the diagonals also to @user20650注意:对角线也归功于@user20650
Note 2:笔记2:
stopifnot(identical(apply(m, 1, paste, collapse=""),
apply(m, 1, function(x) Reduce(paste0, x))))
You could wrap the logic into a function, based on any
, that executes the lines above, unlist
s the result, and checks if there's any TRUE
.您可以将逻辑包装到 function 中,基于
any
,执行上面的行, unlist
s 结果,并检查是否有任何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
Data:数据:
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 ')))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.