R中的算术级数系列

时间:2014-07-20 15:25:53

标签: r pattern-matching

我是这个论坛的新手。我想之前有人问过这个问题,但我不确定这是不是我想要的。

我有这样的序列,

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中使用rleacf,但这并不能完全解决我的问题。

Edit3:当我acf时,它基本上给了我可以使用的最大峰值差异。但是,我希望所有的差异都可能。此外,rle也有所不同。它给了我最长的连续序列的相似数字。在我的情况下哪个不存在。

2 个答案:

答案 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)
  ##
}
##

所以在这个函数中有一些东西肯定可以改进 - 例如我在计算pStartpEnd的某个地方犯了一个错误,它是给定算术序列的起始和结束索引,但事实恰恰相反,这些序列的真正起始位置是作为其中一个中间数据帧的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

就像我说的那样,它的草率和不雅,但它应该让你开始。