2017-03-03 53 views
1

我發佈了一個關於編碼幾天前的問題(Need help code mock sampling)。我注意到可能有太多的背景。因此,從帖子開始,我最大限度地減少了我的問題。任何反饋將不勝感激。需要幫助編碼(文本最小化)

我有隨機數這樣的:

pass.theo <- c(2,4,12,13,14,19,21,27,30,31,32,35,36,38,41,44,49,50,52,57,59,60,61,63,65,68,79,80,86,92,96,100) 

所述第一數目的開始時(即,2)在此特定情況下,我想找到一個數字,表示大於或等於5的第一數目比以前的元素(即2)。在這種情況下,數字是12.然後從數字12中,我想找到另一個第一個數字是5或大於,並繼續,直到結束。用上面的數字,我手動生成了這個代碼,但是需要一般的代碼來進行。

tf <- c(
pass.theo[2]-pass.theo[1] > 5, # 
pass.theo[3]-pass.theo[1] > 5, # select 
pass.theo[4]-pass.theo[3] > 5, # 
pass.theo[5]-pass.theo[3] > 5, # 
pass.theo[6]-pass.theo[3] > 5, # select 
pass.theo[7]-pass.theo[6] > 5, # 
pass.theo[8]-pass.theo[6] > 5, # select 
pass.theo[9]-pass.theo[8] > 5, 
pass.theo[10]-pass.theo[8] > 5, 
pass.theo[11]-pass.theo[8] > 5, 
pass.theo[12]-pass.theo[8] > 5, # select 
pass.theo[13]-pass.theo[12] > 5, 
pass.theo[14]-pass.theo[12] > 5, 
pass.theo[15]-pass.theo[12] > 5, # select 
pass.theo[16]-pass.theo[15] > 5, 
pass.theo[17]-pass.theo[15] > 5, # select 
pass.theo[18]-pass.theo[17] > 5, 
pass.theo[19]-pass.theo[17] > 5, 
pass.theo[20]-pass.theo[17] > 5, # select 
pass.theo[21]-pass.theo[20] > 5, 
pass.theo[22]-pass.theo[20] > 5, 
pass.theo[23]-pass.theo[20] > 5, 
pass.theo[24]-pass.theo[20] > 5, # select 
pass.theo[25]-pass.theo[24] > 5, 
pass.theo[26]-pass.theo[24] > 5, 
pass.theo[27]-pass.theo[24] > 5, # select 
pass.theo[28]-pass.theo[27] > 5, 
pass.theo[29]-pass.theo[27] > 5, # select 
pass.theo[30]-pass.theo[29] > 5, # select 
pass.theo[31]-pass.theo[30] > 5, 
pass.theo[32]-pass.theo[30] > 5 # select 
) 
tf 
passes <- c(pass.theo[1], pass.theo[-1][tf]) 

expected.select <- ifelse(pass.theo %in% passes, 'select', 'drop') 
cbind(pass.theo, expected.select) 
     pass.theo expected.select 
# [1,] "2"  "select"  
# [2,] "4"  "drop"   
# [3,] "12"  "select"  
# [4,] "13"  "drop"   
# [5,] "14"  "drop"   
# [6,] "19"  "select"  
# [7,] "21"  "drop"   
# [8,] "27"  "select"  
# [9,] "30"  "drop"   
#[10,] "31"  "drop"   
#[11,] "32"  "drop"   
#[12,] "35"  "select"  
#[13,] "36"  "drop"   
#[14,] "38"  "drop"   
#[15,] "41"  "select"  
#[16,] "44"  "drop"   
#[17,] "49"  "select"  
#[18,] "50"  "drop"   
#[19,] "52"  "drop"   
#[20,] "57"  "select"  
#[21,] "59"  "drop"   
#[22,] "60"  "drop"   
#[23,] "61"  "drop"   
#[24,] "63"  "select"  
#[25,] "65"  "drop"   
#[26,] "68"  "drop"   
#[27,] "79"  "select"  
#[28,] "80"  "drop"   
#[29,] "86"  "select"  
#[30,] "92"  "select"  
#[31,] "96"  "drop"   
#[32,] "100"  "select" 

我想包含第一個元素always並從pass.theo的其餘部分選擇tf == TRUE。

passes 

有沒有辦法讓上面的功能?

非常感謝您提前!

+3

*「找到數字th at是5或大於以前的元素「*僅僅是diff(pass.theo)> 5',但與您的代碼不匹配。聽起來像你的邏輯比這更復雜一點。 – r2evans

+0

因此,當計算結果返回TRUE時,被扣除的索引似乎會發生變化。 –

+0

感謝您的意見。我試圖澄清更多以上。例如,如果我找到的第一個數字(即12)等於或大於數字2,那麼我想從數字12中重複它,以便下一個數字是19等等。 – Steve

回答

2
pass.theo <- c(2,4,12,13,14,19,21,27,30,31,32,35,36,38,41,44,49,50,52,57,59,60,61,63,65,68,79,80,86,92,96,100) 
# to keep the original pass.theo untouched 
dat <- pass.theo 
for (i in seq_along(pass.theo)[-1]) { 
    if ((dat[i] - dat[i-1]) < 5) dat[i] <- dat[i-1] 
} 
ret <- c(FALSE, diff(dat) >= 5) 

出於演示,我將它們綁定,所以你可以看到發生了什麼:

data.frame(pass.theo = pass.theo, mod = dat, ret = ret) 
# pass.theo mod ret 
# 1   2 2 FALSE 
# 2   4 2 FALSE 
# 3   12 12 TRUE 
# 4   13 12 FALSE 
# 5   14 12 FALSE 
# 6   19 19 TRUE 
# 7   21 19 FALSE 
# 8   27 27 TRUE 
# 9   30 27 FALSE 
# 10  31 27 FALSE 
# 11  32 32 TRUE 
# 12  35 32 FALSE 
# 13  36 32 FALSE 
# 14  38 38 TRUE 
# 15  41 38 FALSE 
# 16  44 44 TRUE 
# 17  49 49 TRUE 
# 18  50 49 FALSE 
# 19  52 49 FALSE 
# 20  57 57 TRUE 
# 21  59 57 FALSE 
# 22  60 57 FALSE 
# 23  61 57 FALSE 
# 24  63 63 TRUE 
# 25  65 63 FALSE 
# 26  68 68 TRUE 
# 27  79 79 TRUE 
# 28  80 79 FALSE 
# 29  86 86 TRUE 
# 30  92 92 TRUE 
# 31  96 92 FALSE 
# 32  100 100 TRUE 

我不是迭代地改變這樣的載體的粉絲,但我不知道的其他工具正確地沿着矢量滾動。

編輯:

實際上,其靈感來自@ MrFlick的Reduce(應該想到這一點),可以更換for循環用:

dat2 <- Reduce(function(a,b) if ((b-a)<5) a else b, 
       pass.theo, accumulate = TRUE) 

然後

c(FALSE, diff(dat2) >= 5) 

與我上面的ret相同。 (我不是試圖竊取@ MrFlick的回答,他應該採取信貸提示Reduce在我的馬虎/低效for循環。

+1

你真的清理了Reduce呼叫,所以我完全贊同。 – MrFlick

+1

我經常傾向於'動物園:: rollapply'類似的東西,但它沒有*積累*,因爲我希望。我覺得'Reduce(...,accumulate = TRUE)'是一個非常值得讚賞的滾動函數。 ('Reduce'正在做一個''for'循環的事實是我必須接受的技術性:-) – r2evans

+0

嗨r2evans。這很棒!!!儘管如此,我將不得不花時間來理解你的代碼。非常感謝您的幫助和所有其他人的意見! – Steve

2

下面是使用Reduce()

pp<-which(sapply(Reduce(function(a,b) { 
    aa <- a[[1]] 
    if (b-aa>5) { 
     return(list(b, T)) 
    } else { 
     return(list(aa, F)) 
    } 
}, pass.theo, init=list(pass.theo[1],F), accumulate=T), `[[`, 2)) - 1 
passes <- c(pass.theo[1], pass.theo[pp]) 

基本上我用Reduce()步驟配對的方法然後使用sapply()來提取發生更改的值,並使用which()獲取索引(因爲我在Reduce調用中使用了初始值,所以減去1)

+0

非常感謝您的幫助,MrFlick !!! – Steve