需要帮助编码(文本最小化)

时间:2017-03-03 18:07:32

标签: r elements

我几天前发布了一个关于编码的问题(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)的开始,我想找到一个数字,该数字是比先前元素(即2)大5或更大的第一个数字。在这种情况下,数字是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

有没有办法在上面创建一个函数?

非常感谢你!

2 个答案:

答案 0 :(得分: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 :(得分: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()获取索引(减去1,因为我在Reduce调用中使用了初始值。)