2011-05-16 89 views
2

我在設計一個rle命令時遇到了一些麻煩,該命令旨在查找參與者連續排列8個連續點的位置。rle命令的幫助

例如,如果:

x <- c(0,1,0,1,1,1,1,1,1,1,1,1) 

我想我一直在使用這一段代碼到11

感謝的值返回到迪文:

which(rle(x2)$values==1 & rle(x2)$lengths >= 8) 
sum(rle(x)$lengths[ 1:(min(which(rle(x)$lengths >= 8))-1) ]) + 8 

我一直在成功使用此代碼來處理我的數據。但是,我注意到它在處理我的一個數據文件時犯了一個錯誤。

例如,如果

x <- c(1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) 

代碼返回19,這是到達在該一排8個連續零的點。我不確定發生了什麼問題或者如何解決問題。

在此先感謝您的幫助。

回答

10

您需要的第一行代碼粘貼在其全部進入第二:

sum(rle(x)$lengths[ 1:(min(which(rle(x2)$values==1 & rle(x2)$lengths >= 8))-1) ]) + 8 
[1] 39 

然而,這裏是另一種方法,使用功能filter。這產生在什麼我認爲是更可讀代碼相同的結果:

which(filter(x2, rep(1/8, 8), sides=1) == 1)[1] 
[1] 39 

以這種方式使用時,filter功能基本上計算在向量中的8個值的塊的移動平均值。然後我回到這裏的均線等於1

+0

這是一個很好的答案,但FYI任何用戶也使用'dplyr'你將不得不調用'統計:: filter'以免與混淆'dplyr :: filter' – Stedy 2016-12-09 21:38:41

8

在基本的編程課程,我教的第一個值的位置,我建議學生給予適當的名稱子結果,並檢查這些子結果:

lengthOfrepeatsOfAnything<-rle(x)$lengths 
#4 2 5 11 2 2 3 2 17 
whichRepeatsAreOfOnes<-rle(x)$values==1 
#1 3 5 7 9 
repeatsOfOnesLength<-lengthOfrepeatsOfAnything * whichRepeatsAreOfOnes #TRUE = 1, FALSE=0 
#4 0 5 0 2 0 3 0 17 
whichRepeatOfOneAreLongerThanEight<-which(repeatsOfOnesLength >= 8) 
#9 
result<-NA 
if(length(whichRepeatOfOneAreLongerThanEight)>0){ 
    firstRepeatOfOneAreLongerThanEight<-whichRepeatOfOneAreLongerThanEight[1] 
    #9 
    if(firstRepeatOfOneAreLongerThanEight==1){ 
     result<-8 
    } 
    else{ 
     repeatsBeforeFirstEightOnes<-1:(firstRepeatOfOneAreLongerThanEight-1) 
     #1 2 3 4 5 6 7 8 
     lengthsOfRepeatsBeforeFirstEightOnes<-lengthOfrepeatsOfAnything[repeatsBeforeFirstEightOnes] 
     #4 2 5 11 2 2 3 2 
     result<-sum(lengthsOfRepeatsBeforeFirstEightOnes) + 8 
    } 
} 

我知道它看起來不像一個在線解決方案那樣漂亮,但它有助於弄清楚事情並挑選錯誤......此外:如果您在4個月內回顧此代碼,該怎麼辦?哪一個會更容易理解?

+1

乏味的閱讀,如果你不習慣CamelCase,但是對於可重複研究來說非常好。 +1 – 2011-05-16 07:17:39

+1

+1非常好的建議來跟蹤錯誤。 – Andrie 2011-05-16 07:27:54

1

我的建議是將代碼分解成更簡單的部分。正如@Nick所建議的那樣,您希望編寫可輕鬆調試的代碼,並使用模塊化編碼來實現這一點。

# find runs of 0s and 1s 
run_01 = rle(x) 

# find run of 1's with length >=8 
run_1 = with(run_01, which(values == 1 & lengths >=8)) 

# find starting position of run_1 
start_pos = sum(run_01$lengths[1:(run_1 - 1)]) 

# add 8 to it 
end_pos = start_pos + 8