2017-03-03 23 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