数字序列识别

5

继另一个问题之后的开发:

在R中识别重复数字序列

我已经使用了上面那个问题的答案来识别我的数据中的序列,这没有问题,但是当涉及到识别不同数字的序列时,我就卡住了,例如:序列可能是:126,126,25而不是重复的数字。

我目前正在使用与上述问题相同的代码(rle)

示例数据:

   d<-read.table(text='Date.Time Aerial
794  "2012-10-01 08:18:00"      1
795  "2012-10-01 08:34:00"      1
796  "2012-10-01 08:39:00"      1
797  "2012-10-01 08:42:00"      1
798  "2012-10-01 08:48:00"      1
799  "2012-10-01 08:54:00"      1
800  "2012-10-01 08:58:00"      1
801  "2012-10-01 09:04:00"      1
802  "2012-10-01 09:05:00"      1
803  "2012-10-01 09:11:00"      1
1576 "2012-10-01 09:17:00"      2
1577 "2012-10-01 09:18:00"      2
804  "2012-10-01 09:19:00"      1
805  "2012-10-01 09:20:00"      1
1580 "2012-10-01 09:21:00"      2
1581 "2012-10-01 09:23:00"      2
806  "2012-10-01 09:25:00"      1
807  "2012-10-01 09:32:00"      1
808  "2012-10-01 09:37:00"      1
809  "2012-10-01 09:43:00"      1', header=TRUE, stringsAsFactors=FALSE, row.names=1)

代码可以识别重复的数字序列(同一个数字重复4次):

tmp <- rle(d$Aerial)
d$newCol <- rep(tmp$lengths>=4, times = tmp$lengths)

然而,我不知道如何识别包含不同数字的序列,例如序列可能是:1,2,2,1(如d$Aerial中)于“2012-10-01 09:11:00”

有各种不同的模式。这些数据是在给定时间和给定天线上检测信号的结果,但为了保持问题开放,我已将其简化如上所述。因此,该模式为1,2,2,1,即在天线列中先检测到第1个,然后是第2个、第2个,最后是第1个。当发生这种模式时,它指示动物的行为移动。如果我能够识别它,我就可以对其进行更多的计算。

上面的代码表示当一个数字重复出现4次时,但它无法识别4个彼此不同的数字的重复:1,2,2,1

这个序列(1,2,2,1)可能会在数据中出现多次,我想每次都能识别它。


2
你的问题对我来说还不够清晰。你能举个恰当的例子进一步解释一下吗?同时你的问题和那篇文章有什么不同之处呢?如果你期待得到好的回答,你应该认真花时间思考如何表达你的问题。 - Arun
也许描述你正在尝试解决的问题会有所帮助... 你是否有一组正在寻找的模式?你是如何确定它们的? - Justin
你已经给了我们数据,很好!但是你的问题还不够清晰。我想你是在寻找从1到2、2到1、1到2和2到1的转换,它们分别出现在11、13、15、17位置?如果是这样,请尝试使用以下代码:which(c(0, diff(d$Aerial)) != 0)(或者head(cumsum(rle(d$Aerial)$lengths)+1, -1))。如果不是,请再次编辑您的问题以更清晰地解释。 - Arun
有各种不同的模式,数据是在给定时间和给定天线上检测到的信号,但为了保持问题开放,我已将其简化如上所述,因此该模式为1、2、2、1,即在Aerial 1、然后是2、然后是2、最后是1(在Aerial列中)。在我的数据中,当出现这种模式时,它表示动物的行为移动。如果我能够识别它,那么我就可以对它进行更多的计算。 - Salmo salar
那么,在第一次出现c(1,2,2,1)之后,任何更多的c(1,2,2,1)出现都应该被视为“重复序列”?除非您有更多的限制条件,否则您将不得不识别数据中的每个4+长度序列,并搜索它们的重复。我怀疑这个搜索空间会非常巨大,如果没有更多的限制条件,就不可能实现。 - Marius
2个回答

4

暴力解决方案:

pat <- c(1,2,2,1)
x <- sapply(1:(nrow(d)-length(pat)), function(x) all(d$Aerial[x:(x+length(pat)-1)] == pat))

d[which(x),]  # "which" prevents recycling of the shorter vector "x"
##               Date.Time Aerial
## 803 2012-10-01 09:11:00      1
## 805 2012-10-01 09:20:00      1

zoorollapply函数可以用于此目的:

require(zoo)
x <- rollapply(d$Aerial, length(pat), FUN=function(x) all(x == pat))

d[which(x),]
##               Date.Time Aerial
## 803 2012-10-01 09:11:00      1
## 805 2012-10-01 09:20:00      1

对于已经删除的评论,要查找与模式的最后一个字符匹配的行:

d[which(x)+length(pat)-1,]
##               Date.Time Aerial
## 804 2012-10-01 09:19:00      1
## 806 2012-10-01 09:25:00      1

4
如果你事先不知道模式是什么(这是我最初从你的问题中得出的),那么这里有一个蛮力解决方案,可以找到给定长度的重复模式:
pattern_length = 4
patterns = list()
for (i in 1:(nrow(d) - pattern_length)) {
  patterns[[i]] = d$Aerial[i:(i + pattern_length - 1)]
}
unique(patterns[duplicated(patterns)])

[[1]]
[1] 1 1 1 1

[[2]]
[1] 1 1 2 2

[[3]]
[1] 1 2 2 1

[[4]]
[1] 2 2 1 1

你可以将这些内容输入到Matthew Lundberg的答案中。

啊,我明白了!谢谢,是的,我已经知道这个模式,因为它暗示了特定的行为! - Salmo salar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接