在编码方面需要帮助(文本最小化)
Need helps in coding (text minimized)
几天前我 post 回答了一个关于编码的问题 (Need help code mock sampling)。我注意到可能有太多的上下文。因此,从 post 开始,我尽量减少了我的问题。任何反馈将不胜感激。
我有这样的随机数:
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)的数字。在这种情况下,数字是 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"
我想始终包含第一个元素,select tf==TRUE 来自 pass.theo 的其余部分。
passes
有没有办法实现上面的功能?
非常感谢您!
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 的回答,他应该因在我的 sloppy/inefficient for
循环中建议 Reduce
而受到赞扬。
这是一个使用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
调用中使用了初始值)。
几天前我 post 回答了一个关于编码的问题 (Need help code mock sampling)。我注意到可能有太多的上下文。因此,从 post 开始,我尽量减少了我的问题。任何反馈将不胜感激。
我有这样的随机数:
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)的数字。在这种情况下,数字是 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"
我想始终包含第一个元素,select tf==TRUE 来自 pass.theo 的其余部分。
passes
有没有办法实现上面的功能?
非常感谢您!
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 的回答,他应该因在我的 sloppy/inefficient for
循环中建议 Reduce
而受到赞扬。
这是一个使用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
调用中使用了初始值)。