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

항상 첫 번째 요소를 포함하고 나머지는 pass.theo에서 tf == TRUE를 선택하고 싶습니다.

passes 

위의 기능을 만드는 방법이 있습니까?

미리 감사드립니다. 당신이 볼 수 있도록

+3

* 수를 찾는다. at 5가 이전 요소보다 큽니다. "* 단순히 diff (pass.theo)> 5 '가되지만 코드와 일치하지 않습니다. 당신의 논리가 그보다 조금 더 복잡하다는 소리가납니다. – r2evans

+0

따라서 계산에서 TRUE를 반환하면 빼기 인덱스가 변경됩니다. –

+0

의견에 감사드립니다. 나는 위에서 더 명확하게하려고 노력했다. 예를 들어 5보다 크거나 2보다 큰 첫 번째 숫자 (예 : 12)를 찾으면 다음 숫자가 19가되도록 숫자 12에서 반복하고 싶습니다. – 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의 대답 @ 훔치려 아니에요, 그가 내 실수/비효율적 for 루프를 통해 Reduce 제안에 대한 크레딧을해야합니다.

+1

전화를 줄이면 완전히 승인됩니다. – MrFlick

+1

처음에는'zoo :: rollapply'를 향한 경향이 있습니다. 그러나 희망하지 않기 때문에 * 누적되지 않습니다. 나는'Reduce (..., accumulate = TRUE) '와 같은 느낌이 그 논쟁에 대해 너무나 감사하고 있습니다. ('Reduce'가 후드에서'for' 루프를 수행한다는 사실은 제가 받아 들여야 할 기술적 인 부분입니다 :-) – r2evans

+0

안녕하세요 r2evans. 이것은 대단하다 !!! 그래도 코드를 이해하는 데 시간을 할애해야합니다. 의견을 보내 주셔서 대단히 감사합니다. – Steve

2

여기에

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()는 기본적으로 나는 페어 단계로 Reduce()를 사용하여 사용하는 방법입니다 요소를 통해 현재 가장 낮은 값을 전달하는 동안 나는 sapply()을 사용하여 변경이 발생한 값을 추출하고 을 사용하여 인덱스를 얻습니다 (Reduce 호출에서 초기 값을 사용했기 때문에 1을 뺍니다).

+0

감사합니다. MrFlick !!! – Steve