我想找到一种方法从矩阵中选择正确的"11"
。
您从左上角开始[1, 1]
,然后从左向右移动到方向。
每当您看到组合"01"
或"00"
时,您应该继续从左向右移动,直到找到一些"11"
。
在示例1中,正确的解决方案是位置"11"
上的[1, 3]
。
# Example 1:
(R)
# [,1] [,2] [,3]
# [1,] 01 01 11
# [2,] 11 01 11
# [3,] 01 11 10
获得"10"
后,您必须更改该行并从第二行开始。
在示例2中,代码必须以"11"
位置上的结果[2, 1]
结束。
# Example 2:
(R1)
# [,1] [,2] [,3]
# [1,] 01 10 11
# [2,] 11 01 11
# [3,] 01 11 10
以下命令适用于第二个示例,但不适用于第一个示例。
which(R == "11", arr.ind = T)
我正在寻找矩阵中正确"11"
的位置。任何想法都将受到高度赞赏!
P.S。 对于R和R1的复制:
R <- structure(c("01", "11", "01", "01", "01", "11", "11", "11", "10"), .Dim = c(3L, 3L))
R1 <- structure(c("01", "11", "01", "10", "01", "11", "11", "11", "10"), .Dim = c(3L, 3L))
答案 0 :(得分:1)
下面是一个简单的功能,可以满足您的需求。参数是矩阵m
,您要搜索的字符串strSearch
(此处为“11”)以及停止搜索给定行strStop
的字符串(此处为“10”)。
循环遍历每一行和每列,在找到停止字符串时断开,并在搜索字符串的第一个实例处返回。返回的长度为2的向量包含行索引和列索引。
如果找不到搜索字符串,则返回NA
。
R <- structure(c("01", "11", "01", "01", "01", "11", "11", "11", "10"), .Dim = c(3L, 3L))
R1 <- structure(c("01", "11", "01", "10", "01", "11", "11", "11", "10"), .Dim = c(3L, 3L))
getPosition <- function(m, strSearch, strStop) {
for (i in seq_len(nrow(m))) {
for (j in seq_len(ncol(m))) {
if (m[i, j] == strStop) break
if (m[i, j] == strSearch) return(c(i, j))
}
}
return(NA)
}
示例输出:
> getPosition(R, "11", "10")
[1] 1 3
> getPosition(R1, "11", "10")
[1] 2 1
答案 1 :(得分:1)
这有效:
find_index <- function(matr) {
# find the col index of first "10" in each row
ind10 <- apply(matr, 1, function(x) ifelse(sum(x == "10") == 0,
length(x) + 1, min(seq_len(length(x))[x == "10"])))
# find the col index of first "11" in each row
ind11 <- apply(matr, 1, function(x) ifelse(sum(x == "11") == 0,
length(x) + 1, min(seq_len(length(x))[x == "11"])))
# check if 11 is before 10
ind <- ifelse(ind10 < ind11, NA, ind11)
# select the first row where "11" is before "10"
rownumber <- which(!is.na(ind))[1]
# and its colnumber
colnumber <- ind[rownumber]
return(c(rownumber, colnumber))
}
find_index(R)
find_index(R1)
然后输出是这样的。
> find_index(R)
[1] 1 3
> find_index(R1)
[1] 2 1
>
由于您没有指定如果存在“11”,“01”,“10”,“00”以外的条目会发生什么,我忽略了这种可能性。
修改强> 由于阅读起来很复杂,我创建了一个带有文本连接的可读版本。
library(stringi)
library(dplyr)
find_11_before_10 <- function(x){
text <- x %>% paste(collapse = "|")
if(stri_detect_fixed(text, "11") &
stri_detect_regex(text, "10.+11", negate = T)){
return(which(x == "11") %>% min)
} else {
return(NA)
}
}
find_index2 <- function(matr){
ind <- apply(matr, 1, find_11_before_10)
rownumber <- which(!is.na(ind))[1]
colnumber <- ind[rownumber]
return(c(rownumber, colnumber))
}
find_index2(R)
find_index2(R1)
答案 2 :(得分:1)
以下是两种方法。
1)正则表达式将t(m)
折叠到一个以空格分隔的字符串中,并使用带有指定正则表达式的strapply
来挑选从该字符串开头到第一个11跟随00或01.提取的字符串中的空格数加1是11的位置。将其转换为行号和列号。
library(gsubfn)
v <- paste(t(m), collapse = " ")
ix <- head(strapply(v, ".*?0[01].*?11", ~ nchar(gsub("\\S", "", x)), simplify = c), 1) + 1
c(t(row(m))[ix], t(col(m))[ix])
## [1] 1 3
2)位置/查找另一种方法计算第一个00或01,w0
和ix
的位置,前11个的位置大于{ {1}}。最后
计算行号和列号。
w0
3)状态机使用switch和Reduce可以实现状态机。我们在州1开始。一旦我们找到00或01,我们转换到状态2,当在状态2时,我们转换到状态3.如果我们处于状态3或4,我们转换到状态4.状态3是状态3在00或01之后的第11个。
w0 <- Position(isTRUE, grepl("0[01]", t(m)))
ix <- Find(function(x) x > w0, which(t(m) == 11))
c(t(row(m))[ix], t(col(m))[ix])
## [1] 1 3
注意:我们将此作为输入:
transition <- function(state, x)
switch(state,
if (x == "00" || x == "01") 2 else 1,
if (x == "11") 3 else 2,
4,
4)
r <- Reduce(transition, init = 1, c(t(m)), accumulate = TRUE)[-1]
ix <- which(r == 3)
c(t(row(m))[ix], t(col(m))[ix])
## [1] 1 3
答案 3 :(得分:1)
这是另一个为你做的小功能:
foo <- function(mat, a, b) {
res <- t(apply(mat, 1, function(x) replace(x, cumsum(x == a) > 0, NA)))
res <- which(res == b, arr.ind = TRUE)
res[order(res[,1], res[,2]),][1,]
}
foo(R, "10", "11")
#row col
# 1 3
foo(R1, "10", "11")
#row col
# 2 1
这是按行进行的,用“NA”替换NA之后的所有元素,然后得到第一个“11”出现。