寻找`n1` TRUEs裹在两个`n2` FALSEs之间,n3` TRUEs等之间的'包裹在整个事情 [英] Finding `n1` TRUEs wrapped in between two `n2` FALSEs, the whole thing wrapped in between `n3` TRUEs, etc
问题描述
从TRUEs和falses的顺序,我想使返回TRUE是否有系列的至少 N1
TRUEs某处序列中的一个函数。下面是该函数:
From a sequence of TRUEs and falses, I wanted to make a function that returns TRUE whether there is a series of at least n1
TRUEs somewhere in the sequence. Here is that function:
fun_1 = function(TFvec, n1){
nbT = 0
solution = -1
for (i in 1:length(x)){
if (x[i]){
nbT = nbT + 1
if (nbT == n1){
return(T)
break
}
} else {
nbT = 0
}
}
return (F)
}
测试:
x = c(T,F,T,T,F,F,T,T,T,F,F,T,F,F)
fun_1(x,3) # TRUE
fun_1(x,4) # FALSE
然后,我需要返回TRUE如果在给定列表布尔向量,还有一系列至少 N1
TRUEs由至少两个系列的包(一个的函数:在的每边)N2
falses。这里的功能:
Then, I needed a function that returns TRUE if in a given list boolean vector, there is a series of at least n1
TRUEs wrapped by at least two series (one on each side) of n2
falses. Here the function:
fun_2 = function(TFvec, n1, n2){
if (n2 == 0){
fun_1(TFvec, n2)
}
nbFB = 0
nbFA = 0
nbT = 0
solution = -1
last = F
for (i in 1:length(TFvec)){
if(TFvec[i]){
nbT = nbT + 1
if (nbT == n1 & nbFB >= n2){
solution = i-n1+1
}
last = T
} else {
if (last){
nbFB = 0
nbFA = 0
}
nbFB = nbFB + 1
nbFA = nbFA + 1
nbT = 0
if (nbFA == n2 & solution!=-1){
return(T)
}
last = F
}
}
return(F)
}
有可能不是一个非常有效的功能,但!我没有测试它的100倍,但它看起来像它工作正常!
It is maybe not a very efficient function though! And I haven't tested it 100 times but it looks like it works fine!
测试:
x = c(T,F,T,T,F,F,T,T,T,F,F,T,F,F)
fun_2(x, 3, 2) # TRUE
fun_2(x, 3, 3) # FALSE
现在,不管你信不信,我想一个函数( fun_3
)如果布尔向量有一个(至少)系列返回TRUE至少 N1
TRUEs包裹在中间(至少)两个(每边一个)系列的N2
falses哪里整个事情(三个系列)之间的包装在(至少)两个(每边一个)系列的N3
TRUEs。正如恐怕要进一步把这个问题,我问这里寻求帮助创建一个函数 fun_n
在我们进入两个参数 TFvec
和 list_n
,其中 list_n
是列表ñ
任意长度的。
Now, believe it or not, I'd like to make a function (fun_3
) that returns TRUE if in the boolean vector there is a (at least) series of at least n1
TRUEs wrapped in between (at least) two (one on each side) series of n2
falses where the whole thing (the three series) are wrapped in between (at least) two (one on each side) series of n3
TRUEs. And as I am afraid to have to bring this problem even further, I am asking here for help to create a function fun_n
in which we enter two arguments TFvec
and list_n
where list_n
is a list of n
of any length.
你能帮我创造功能 fun_n
?
Can you help me to create the function fun_n
?
推荐答案
为了方便起见,记录阈值的数量的长度
For convenience, record the length of the number of thresholds
n = length(list_n)
重新present真假向量作为运行长度编码,记住每次运行的方便长度
Represent the vector of TRUE and FALSE as a run-length encoding, remembering the length of each run for convenience
r = rle(TFvec); l = r$length
查找可能起始位置
Find possible starting locations
idx = which(l >= list_n[1] & r$value)
确认的起始位置嵌入足以满足所有测试
Make sure the starting locations are embedded enough to satisfy all tests
idx = idx[idx > n - 1 & idx + n - 1 <= length(l)]
然后检查远程连续运行的长度与病情相符,只保留那些起点是
Then check that lengths of successively remote runs are consistent with the condition, keeping only those starting points that are
for (i in seq_len(n - 1)) {
if (length(idx) == 0)
break # no solution
thresh = list_n[i + 1]
test = (l[idx + i] >= thresh) & (l[idx - i] >= thresh)
idx = idx[test]
}
如果有在 idx的
留下的任何值,则这些索引到满足条件的RLE;起点(S)的初始向量是 cumsum(1)实施IDX - 1] + 1
If there are any values left in idx
, then these are the indexes into the rle satisfying the condition; the starting point(s) in the initial vector are cumsum(l)[idx - 1] + 1
.
组合:
runfun = function(TFvec, list_n) {
## setup
n = length(list_n)
r = rle(TFvec); l = r$length
## initial condition
idx = which(l >= list_n[1] & r$value)
idx = idx[idx > n - 1 & idx + n - 1 <= length(l)]
## adjacent conditions
for (i in seq_len(n - 1)) {
if (length(idx) == 0)
break # no solution
thresh = list_n[i + 1]
test = (l[idx + i] >= thresh) & (l[idx - i] >= thresh)
idx = idx[test]
}
## starts = cumsum(l)[idx - 1] + 1
## any luck?
length(idx) != 0
}
这是速度快,并允许运行> =门槛,规定中的问题;例如:
This is fast and allows for runs >= the threshold, as stipulated in the question; for example
x = sample(c(TRUE, FALSE), 1000000, TRUE)
system.time(runfun(x, rep(2, 5)))
在第二小于1/5完成
completes in less than 1/5th of a second.
一个有趣的泛化允许灵活的条件,例如,刚好运行 list_n
,如rollapply解决方案
A fun generalization allows for flexible condition, e.g., runs of exactly list_n
, as in the rollapply solution
runfun = function(TFvec, list_n, cond=`>=`) {
## setup
n = length(list_n)
r = rle(TFvec); l = r$length
## initial condition
idx = which(cond(l, list_n[1]) & r$value)
idx = idx[idx > n - 1 & idx + n - 1 <= length(l)]
## adjacent conditions
for (i in seq_len(n - 1)) {
if (length(idx) == 0)
break # no solution
thresh = list_n[i + 1]
test = cond(l[idx + i], thresh) & cond(l[idx - i], thresh)
idx = idx[test]
}
## starts = cumsum(l)[idx - 1] + 1
## any luck?
length(idx) != 0
}
这篇关于寻找`n1` TRUEs裹在两个`n2` FALSEs之间,n3` TRUEs等之间的'包裹在整个事情的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!