内容简介:http://stackoverflow.com/questions/14154952/finding-pattern-in-a-matrix-in-r
我有一个8 x n矩阵,例如
set.seed(12345)
m <- matrix(sample(1:50, 800, replace=T), ncol=8)
head(m)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 37 15 30 3 4 11 35 31
[2,] 44 31 45 30 24 39 1 18
[3,] 39 49 7 36 14 43 26 24
[4,] 45 31 26 33 12 47 37 15
[5,] 23 27 34 29 30 34 17 4
[6,] 9 46 39 34 8 43 42 37
我想在矩阵中找到一个特定的模式,例如我想知道我在哪里可以找到一个37,其次在下一行10和29,后面是一个42
例如,在上述矩阵的第57:59行中
m[57:59,]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] *37 35 1 30 47 9 12 39
[2,] 5 22 *10 *29 13 5 17 36
[3,] 22 43 6 2 27 35 *42 50
A(可能无效率)的解决方案是获取包含37的所有行
sapply(1:nrow(m), function(x){37 %in% m[x,]})
然后使用几个循环来测试其他条件.
如何写一个有效的功能来做到这一点,这可以推广到任何用户给定的模式(不一定超过3行,可能的“空洞”,每行的值可变数量等).
编辑:回答各种意见
>我需要找到EXACT模式
>同一行中的顺序并不重要(如果使事情更简单,可以在每行中排序)
线必须相邻.
>我想得到返回的所有模式的(开始)位置(即,如果模式在矩阵中多次出现,我想要多个返回值).
>用户将通过GUI进入模式,我还没有决定如何.例如,要搜索上述模式,他可以写一些类似的东西
37; 10,29; 42
在哪里表示新行,并在同一行上分隔值.
同样,我们可能会寻找
50,51;;75;80,81
意思是行n中的50和51,行n 2中的75,行n 3中的80和81
这是一个广义的功能:
PatternMatcher <- function(data, pattern, idx = NULL) {
p <- unlist(pattern[1])
if(is.null(idx)){
p <- unlist(pattern[length(pattern)])
PatternMatcher(data, rev(pattern)[-1],
idx = Filter(function(n) all(p %in% intersect(data[n, ], p)),
1:nrow(data)))
} else if(length(pattern) > 1) {
PatternMatcher(data, pattern[-1],
idx = Filter(function(n) all(p %in% intersect(data[n, ], p)),
idx - 1))
} else
Filter(function(n) all(p %in% intersect(data[n, ], p)), idx - 1)
}
这是一个递归函数,它是在每次迭代中减少模式,并且只检查在上一次迭代中识别的行之后的行.列表结构允许以方便的方式传递模式:
PatternMatcher(m, list(37, list(10, 29), 42)) # [1] 57 PatternMatcher(m, list(list(45, 24, 1), 7, list(45, 31), 4)) # [1] 2 PatternMatcher(m, list(1,3)) # [1] 47 48 93
编辑:上面的函数的想法似乎很好:检查矢量模式[[1]]的所有行,并获得索引r1,然后检查行r1 1为模式[[2]]并获取r2等等,但它真的需要经历所有行的第一步很多时间.当然,每个步骤都需要很多时间. m<- 矩阵(样本(1:10,800,替换= T),ncol = 8),即当索引r1,r2,...没有太大变化时,这里是另一种方法,这里是PatternMatcher看起来非常相似,但是还有另一个函数matchRow用于查找具有向量的所有元素的行.
matchRow <- function(data, vector, idx = NULL){
if(is.null(idx)){
matchRow(data, vector[-1],
as.numeric(unique(rownames(which(data == vector[1], arr.ind = TRUE)))))
} else if(length(vector) > 0) {
matchRow(data, vector[-1],
as.numeric(unique(rownames(which(data[idx, , drop = FALSE] == vector[1], arr.ind = TRUE)))))
} else idx
}
PatternMatcher <- function(data, pattern, idx = NULL) {
p <- pattern[[1]]
if(is.null(idx)){
rownames(data) <- 1:nrow(data)
p <- pattern[[length(pattern)]]
PatternMatcher(data, rev(pattern)[-1], idx = matchRow(data, p))
} else if(length(pattern) > 1) {
PatternMatcher(data, pattern[-1], idx = matchRow(data, p, idx - 1))
} else
matchRow(data, p, idx - 1)
}
与以前的功能比较:
library(rbenchmark)
bigM <- matrix(sample(1:50, 800000, replace=T), ncol=8)
benchmark(PatternMatcher(bigM, list(37, c(10, 29), 42)),
PatternMatcher(bigM, list(1, 3)),
OldPatternMatcher(bigM, list(37, list(10, 29), 42)),
OldPatternMatcher(bigM, list(1, 3)),
replications = 10,
columns = c("test", "elapsed"))
# test elapsed
# 4 OldPatternMatcher(bigM, list(1, 3)) 61.14
# 3 OldPatternMatcher(bigM, list(37, list(10, 29), 42)) 63.28
# 2 PatternMatcher(bigM, list(1, 3)) 1.58
# 1 PatternMatcher(bigM, list(37, c(10, 29), 42)) 2.02
verybigM1 <- matrix(sample(1:40, 8000000, replace=T), ncol=20)
verybigM2 <- matrix(sample(1:140, 8000000, replace=T), ncol=20)
benchmark(PatternMatcher(verybigM1, list(37, c(10, 29), 42)),
PatternMatcher(verybigM2, list(37, c(10, 29), 42)),
find.combo(verybigM1, convert.gui.input("37;10,29;42")),
find.combo(verybigM2, convert.gui.input("37;10,29;42")),
replications = 20,
columns = c("test", "elapsed"))
# test elapsed
# 3 find.combo(verybigM1, convert.gui.input("37;10,29;42")) 17.55
# 4 find.combo(verybigM2, convert.gui.input("37;10,29;42")) 18.72
# 1 PatternMatcher(verybigM1, list(37, c(10, 29), 42)) 15.84
# 2 PatternMatcher(verybigM2, list(37, c(10, 29), 42)) 19.62
现在,模式参数应该像list(37,c(10,29),42)而不是列表(37,list(10,29),42)).最后:
fastPattern <- function(data, pattern)
PatternMatcher(data, lapply(strsplit(pattern, ";")[[1]],
function(i) as.numeric(unlist(strsplit(i, split = ",")))))
fastPattern(m, "37;10,29;42")
# [1] 57
fastPattern(m, "37;;42")
# [1] 57 4
fastPattern(m, "37;;;42")
# [1] 33 56 77
http://stackoverflow.com/questions/14154952/finding-pattern-in-a-matrix-in-r
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- C语言实现在杨氏矩阵中查找数字
- 机器学习 | SVD矩阵分解算法,对矩阵做拆分,然后呢?
- golang 算法-矩阵
- 彻底理解矩阵乘法
- [开源项目]矩阵数据的意义
- iphone – :CGAffineTransformInvert:奇异矩阵
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C程序设计的抽象思维
Eric S.Roberts / 闪四清 / 机械工业出版社 / 2012-5 / 99.00元
Eric S. Roberts所著的《C程序设计的抽象思维》是一本关于C语言的经典图书。本书共计17章,分为4部分,第一部分概述计算机导论课程中涉及的基本编程概念;第二部分讨论递归算法,其中结合大量示例,有助于读者轻松理解和掌握晦涩的概念;第三部分不仅介绍了用非递归算法实现的抽象数据类型,还提供了一些工具,有助于读者理解数据抽象的概念;第四部分重点介绍采用递归算法实现的抽象数据类型。本书重点突出,......一起来看看 《C程序设计的抽象思维》 这本书的介绍吧!
Base64 编码/解码
Base64 编码/解码
HSV CMYK 转换工具
HSV CMYK互换工具