我是这个论坛的新手。我想之前有人问过这个问题,但我不确定这是不是我想要的。
我有这样的序列,
1 2 3 4 5 8 9 10 12 14 15 17 18 19
所以,我想做的是,得到形成一系列的所有数字,属于该集合的数字应该与前一个元素有一个恒定的差异,并且元素的最小数量应该是3在那一套。
即,我可以看到(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且它应该是最大的。
Edit2:我尝试在R中使用rle
和acf
,但这并不能完全解决我的问题。
Edit3:当我acf
时,它基本上给了我可以使用的最大峰值差异。但是,我希望所有的差异都可能。此外,rle
也有所不同。它给了我最长的连续序列的相似数字。在我的情况下哪个不存在。
答案 0 :(得分:2)
如果您正在查找连续数字的序列,那么cgwtools::seqle
会以rle
找到重复值序列的相同方式为您找到它们。
在基本上构成此类序列的任何数据子集的一般情况下,例如您引用的8,10,12,14
案例,您的标准非常普遍,难以满足。您必须从系列的每个元素开始,并对x[j] +1, x[j]+2, x[j]+3 ...
无限广告进行前瞻性搜索。这表明使用一些基于树的算法。
答案 1 :(得分:1)
这是一个潜在的解决方案 - 虽然是一个非常丑陋,草率的:
##
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)
##
}
##
所以在这个函数中有一些东西肯定可以改进 - 例如我在计算pStart
和pEnd
的某个地方犯了一个错误,它是给定算术序列的起始和结束索引,但事实恰恰相反,这些序列的真正起始位置是作为其中一个中间数据帧的rownumbers给出的,所以这是一种hacky类型的解决方案。无论如何,它接受数字向量x
和最小长度参数minSize
。它将返回一个列表,其中包含符合上述标准的序列信息。
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
就像我说的那样,它的草率和不雅,但它应该让你开始。