R中的算术级数
我是这个论坛的新手。我想以前有人问过类似的问题,但我不确定这是否是我想要的 我有一个这样的序列R中的算术级数,r,pattern-matching,R,Pattern Matching,我是这个论坛的新手。我想以前有人问过类似的问题,但我不确定这是否是我想要的 我有一个这样的序列 1 2 3 4 5 8 9 10 12 14 15 17 18 19 所以,我想做的是,得到所有形成一个系列的数字,也就是说,属于这个集合的数字都应该和前面的元素有一个常数差,而且这个集合中元素的最小数量应该是3 i、 例如,我可以看到(1,2,3,4,5)形成一个这样的序列,其中数字出现在间隔1之后,并且该集合的总大小为5,满足最小阈值标准。 (1,3,5)形成这样一种模式,其中数字在间隔2之后出
1 2 3 4 5 8 9 10 12 14 15 17 18 19
所以,我想做的是,得到所有形成一个系列的数字,也就是说,属于这个集合的数字都应该和前面的元素有一个常数差,而且这个集合中元素的最小数量应该是3
i、 例如,我可以看到(1,2,3,4,5)
形成一个这样的序列,其中数字出现在间隔1之后,并且该集合的总大小为5,满足最小阈值标准。
(1,3,5)
形成这样一种模式,其中数字在间隔2之后出现
(8,10,12,14)
以2的间隔形成另一个这样的图案。所以,正如你所看到的,重复的间隔可以是任何东西
另外,对于一个特定的集合,我想要它的最大值。我不希望,(8,10,12)
(尽管它满足最小阈值3和常数差)作为输出,并且只作为我想要的最大长度,即(8,10,12,14)
类似地,对于(1,2,3,4,5)
,我不希望(1,2,3)
或(2,3,4,5)
作为输出,只需要我想要的最大长度,即(1,2,3,4,5)
我在R怎么做
编辑:也就是说,我想要形成一个基本AP系列的任何集合,具有任何差异,但是该系列的总值应该大于3,并且应该是最大值
编辑2:我曾尝试在R中使用rle
和acf
,但这并不能完全解决我的问题
编辑3:当我做acf时,它基本上给了我可以使用的最大峰值差。然而,我希望所有可能的差异。而且,
rle
完全不同。它给了我类似数字的最长连续序列。这在我的情况下是不存在的 如果您正在查找连续的数字序列,则cgwtools::sekle
将以与rle
查找重复值序列相同的方式为您查找它们
在一般情况下,基本上是构成这种序列的数据的任何子集,例如您引用的
8,10,12,14
案例,您的标准非常笼统,很难满足。您必须从系列的每个元素开始,对x[j]+1,x[j]+2,x[j]+3…
。这建议使用一些基于树的算法 这里有一个潜在的解决方案——尽管这是一个非常丑陋、草率的解决方案:
##
arithSeq <- function(x=nSeq, minSize=4){
##
dx <- diff(x,lag=1)
Runs <- rle(diff(x))
##
rLens <- Runs[[1]]
rVals <- Runs[[2]]
pStart <- c(
rep(1,rLens[1]),
rep(cumsum(1+rLens[-length(rLens)]),times=rLens[-1])
)
pEnd <- pStart + c(
rep(rLens[1]-1, rLens[1]),
rep(rLens[-1],times=rLens[-1])
)
pGrp <- rep(1:length(rLens),times=rLens)
pLen <- rep(rLens, times=rLens)
dAll <- data.frame(
pStart=pStart,
pEnd=pEnd,
pGrp=pGrp,
pLen=pLen,
runVal=rep(rVals,rLens)
)
##
dSub <- subset(dAll, pLen >= minSize - 1)
##
uVals <- unique(dSub$runVal)
##
maxSub <- subset(dSub, runVal==uVals[1])
maxLen <- max(maxSub$pLen)
maxSub <- subset(maxSub, pLen==maxLen)
##
if(length(uVals) > 1){
for(i in 2:length(uVals)){
iSub <- subset(dSub, runVal==uVals[i])
iMaxLen <- max(iSub$pLen)
iSub <- subset(iSub, pLen==iMaxLen)
maxSub <- rbind(
maxSub,
iSub)
maxSub
}
##
}
##
deDup <- maxSub[!duplicated(maxSub),]
seqStarts <- as.numeric(rownames(deDup))
outList <- list(NULL); length(outList) <- nrow(deDup)
for(i in 1:nrow(deDup)){
outList[[i]] <- list(
Sequence = x[seqStarts[i]:(seqStarts[i]+deDup[i,"pLen"])],
Length=deDup[i,"pLen"]+1,
StartPosition=seqStarts[i],
EndPosition=seqStarts[i]+deDup[i,"pLen"])
outList
}
##
return(outList)
##
}
##
正如我所说,这是一个草率和不雅的行为,但它应该让你开始。这是很多问题。你应该从
rle
开始。这看起来很像@Roman,我试过了,但它没有给我想要的,因为它给了我连续长度编码。我在发帖前确实试过了。:)@nrussell,是的,正如我所说,类似这样的问题以前已经被问过了,在发布之前我已经看过了。但是,我的完全不同,尽管它们有一些相似之处@bjohn在解决这个问题的最佳尝试中加入可复制的代码,并描述其不足之处,这将是一个好主意。我理解你的观点。但是,如果我有一个固定长度的字符串,比如说最大值为15,那么,它还需要使用树算法吗?对此我非常感谢。真正地它工作得很好。然而,我只有一个疑问。上例中的nSeq
在排序“1234567891023314151617171717181818192523242526”后产生。现在,在找出其中的序列时,为什么它只找出那些常数差等于1
的AP呢。是否可以修改代码以包括输出序列,如2,4,6,8,10,12,14….
?而且,当差值等于3时,它应该考虑到这一点——它寻找的是任何类型的算术递增序列,而不仅仅是1的增量。注意我使用lSeq
作为x
和minSize=5
给出的示例:列表中的第一个结果是13 16 19 22 25
(差异为3);列表中的第二个是11151719
(2的差异)。对nSeq
进行排序后,我这样做了,arithSeq(nSeq,minSize=3)
,它返回两个序列。一个来自12310
,另一个来自1718。。26
。我不知道为什么会发生这种情况?哦,我明白你的意思了——发生这种情况是因为它们的长度相同(10)。如果有两个或两个以上具有相同增量的算术序列,则取最长的一个;但如果有多个序列具有相同的增量和长度,它只返回具有该(最大)长度的所有序列。另一种选择是任意选择其中一个,这很容易实现代码>的增量为2
和序列3 6 9 12代码>的增量为3
。为什么它不返回这些系列?
set.seed(1234)
lSeq <- sample(1:25,100000,replace=TRUE)
nSeq <- c(1:10,12,33,13:17,16:26)
##
> arithSeq(nSeq)
[[1]]
[[1]]$Sequence
[1] 16 17 18 19 20 21 22 23 24 25 26
[[1]]$Length
[1] 11
[[1]]$StartPosition
[1] 18
[[1]]$EndPosition
[1] 28
##
> arithSeq(x=lSeq,minSize=5)
[[1]]
[[1]]$Sequence
[1] 13 16 19 22 25
[[1]]$Length
[1] 5
[[1]]$StartPosition
[1] 12760
[[1]]$EndPosition
[1] 12764
[[2]]
[[2]]$Sequence
[1] 11 13 15 17 19
[[2]]$Length
[1] 5
[[2]]$StartPosition
[1] 37988
[[2]]$EndPosition
[1] 37992