2014-07-20 39 views
1

我是這個論壇的新手。我猜這樣的事情之前曾被問過,但我不確定這是否是我想要的。R中的算術級數系列

我有這樣的序列,

1 2 3 4 5 8 9 10 12 14 15 17 18 19 

所以,我希望做的是,讓所有這一切構成了一系列的數字,即屬於該組iethe數字都應該有一個恆定與前一個元素不同,並且該集合中元素的最小數目應爲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)作爲輸出,只有最大長度ONE I WANT,即(1,2,3,4,5)

我該如何在R中做到這一點?

編輯:也就是說,我想要任何形式的基本AP系列的任何差異,但總值應該大於3在該系列,它應該是最大的。

編輯2:我曾嘗試在R中使用rleacf但這並不能完全解決我的問題。

編輯3:當我做了acf,它基本上給了我可以使用的最大峯值差異。不過,我希望所有的差異成爲可能。另外,rle只是有所不同。它給了我最長連續的相似數字序列。我的情況不是這樣。

+1

這是很多問題。你應該從'rle'開始。 –

+0

這看起來很像[特色問題]之一。(http://stackoverflow.com/questions/24801741/finding-duplicate-values-in-a-single-string-of-characters-in-r) – nrussell

+1

@羅曼,我試過了,但它並沒有給我我想要的,因爲它給了我連續的長度編碼。我在發佈之前嘗試過。 :) – bjohn

回答

2

如果您正在尋找連續數字的序列,那麼cgwtools::seqle會以相同的方式找到它們,rle會找到一系列重複值。

在基本上形成這樣一個序列的任何數據子集的一般情況下,例如您引用的8,10,12,14個案,您的標準非常籠統,難以滿足。你必須從你的系列的每個元素開始,並做一個前瞻性的搜索x[j] +1, x[j]+2, x[j]+3 ...無限。這表明使用了一些基於樹的算法。

+0

我明白你的觀點。但是,如果我有一個固定長度的字符串,我們假設最大值爲15,那麼它是否需要使用樹算法? – bjohn

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給出,所以這是一種奇怪的解決方案。無論如何,它接受數字矢量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 

就像我說的那樣,它的馬虎和不雅,但它應該讓你開始。

+0

我無法對此表示感謝。真。它運作良好。但是,我只有一個疑問。在上面的例子中,「nSeq」在排序後得出「1 2 3 4 5 6 7 8 9 10 12 33 13 14 15 16 17 16 17 18 19 20 21 22 23 24 25 26」。現在,在找出序列的時候,爲什麼它只能找出那些恆定差值等於'1'的AP。是否可以修改代碼以包含輸出「2,4,6,8,10,12,14 ....」等系列?而且,差異等於3? – bjohn

+0

它應該考慮到這一點 - 它正在尋找任何類型的算術遞增序列,而不僅僅是1的遞增。注意我使用'lSeq'作爲'x'和'minSize = 5'給出的例子:第一個結果是列表是'13 16 19 22 25'(區別3);列表中的第二個是「11 13 15 17 19」(差異爲2)。 – nrussell

+0

對nSeq進行排序後,我做了這個,arithSeq(nSeq,minSize = 3),它返回兩個序列。一個來自'1 2 3 ... 10',另一個來自'17 18 19 .. 26'。我不知道爲什麼會發生這種情況? – bjohn