2017-03-03 10 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" 

最初の要素を常に含め、残りの部分からtf == TRUEを選択します。

passes 

上記の機能を実現する方法はありますか?

ありがとうございます!あなたが見ることができるように

+3

*数字thを見つけるat * 5は以前の要素 "*よりも単純に' diff(pass.theo)> 5'になりますが、これはあなたのコードと一致しません。あなたのロジックのような音は、それより少し複雑です。 – r2evans

+0

したがって、計算結果がTRUEになると、減算されるインデックスが変わるように見えます。 –

+0

コメントありがとうございます。私は上記を明確にしようとした。例えば、私が最初の数字(すなわち、12)が5より大きい、または2より大きい数字を見つけたら、それから、それを次の数字が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 

を私は繰り返し、このようなベクトルを変えるのファンではないんだけど、私は知りませんベクトルに沿って正しく回転する他のツール。

編集:次に

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

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

実は、MrFlickのReduce(そのことを考えているはずです)@からインスピレーションを取って、あなたとforループを置き換えることができます

は上記の私のretと同じです。 (私はMrFlickの答え@盗むしようとしていないよ、彼は私のずさん/非効率的forループ上Reduceを示唆ための信用を取る必要がありますが。

+1

私は完全に承認するので、Reduceコールを実際にクリーンアップしました。 – MrFlick

+1

私はしばしば 'zoo :: 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

関連する問題