当前,我正在处理显示一系列活动的数据,我希望从这些序列中提取遵循特定模式的行。
一些示例序列:
set.seed(12345)
m <- matrix(sample(1:10, 800, replace=T), ncol=8)
m[sample(1:100, 20, replace=T), 8] <- NA #sequences have variable lengths
head(m)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 4 2 3 1 1 2 4 4
[2,] 5 4 5 3 3 4 1 2
[3,] 4 5 1 4 2 5 3 3
[4,] 5 4 3 4 2 5 4 NA
[5,] 3 3 4 3 3 4 2 1
[6,] 1 5 4 4 1 5 5 4
一种解决方案是使用两个for循环来检查每一行的可能模式,但是我已经体验到,当矩阵变大时,计算时间会快速增长。我已经尝试过以下示例代码,其大小为3,活动1之后是活动2和活动3:
pattern <- list(1,2,3)
g <- list()
for (i in 1:NROW(m)){
if (any(m[i,]==pattern[1], na.rm = TRUE) & any(m[i,]==pattern[2], na.rm = TRUE) & any(m[i,]==pattern[3], na.rm = TRUE)){
for(ii in 1:(NCOL(m)-2)){
if((m[i,ii]==pattern[1]) & (m[i,ii+1]==pattern[2]) & (m[i,ii+2]==pattern[3])){
g <- append(g,i)
}
}
}
}
此循环似乎有效,因为它提供了一个列表,其中包含与模式(行28、32和99)匹配的行的索引。但是,此方法不能扩展用于较长/较短的模式。另外,在此示例中,检查了模式“ 1-> 2-> 3”,但我也希望可以检查“ 1->(2、4或5)-> 3”等模式。
我希望编写一个类似于this question中接受的答案的函数,其中输入需要矩阵和显示为列表的模式。但是我的R知识有限,我可以寻求帮助。
答案 0 :(得分:0)
我们可以从创建一个向量开始,该向量将矩阵的每一行折叠为单个字符串(在这种情况下,由空格分隔)。然后我们可以很容易地grep
。
mm<-apply(m,1,paste,collapse=" ")
grep("1 2 3", mm)
integer(0)
grep("1 [245] 3", mm)
[1] 14 83
第一行grep行提供了简单的搜索(结果为零)。 grep的第二行显示了如何搜索更复杂的模式-这将搜索第二个示例,即1-> 2、4或5-> 3。
请注意,grep
将为您提供与您的模式匹配的行的索引。另外,grepl
将为您提供与m
相同长度的逻辑向量,其中TRUE表示匹配。