Rem*_*i.b 2 search boolean-logic boolean r boolean-operations
从一系列TRUE和falses,我想创建一个返回TRUE的函数,无论n1
序列中某处是否存在至少一系列TRUE .这是这个功能:
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)
}
Run Code Online (Sandbox Code Playgroud)
测试:
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
Run Code Online (Sandbox Code Playgroud)
然后,我需要一个返回TRUE的函数,如果在给定的列表中布尔向量,则n1
至少有一系列由至少两个系列(每侧一个)包裹的TRUE n2
.这里的功能:
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)
}
Run Code Online (Sandbox Code Playgroud)
虽然这可能不是一个非常有效的功能!我没有测试过100次,但看起来它工作正常!
测试:
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
Run Code Online (Sandbox Code Playgroud)
现在,信不信由你,我想创建一个函数(fun_3
),如果在布尔向量中有一个(至少)至少n1
包含在(至少)两个(每边一个)的TRUE之间的系列,则返回TRUE 一系列的n2
谬误,其中整个事物(三个系列)被包裹在(至少)两个(每侧一个)系列n3
TRUE之间.而且由于我不得不进一步提出这个问题,我在这里请求帮助创建一个函数fun_n
,我们在其中输入两个参数TFvec
,list_n
其中list_n
是n
任何长度的列表.
你能帮我创建这个功能fun_n
吗?
为方便起见,记录阈值数量的长度
n = length(list_n)
Run Code Online (Sandbox Code Playgroud)
将TRUE和FALSE的向量表示为行程编码,为方便起见记住每次运行的长度
r = rle(TFvec); l = r$length
Run Code Online (Sandbox Code Playgroud)
查找可能的起始位置
idx = which(l >= list_n[1] & r$value)
Run Code Online (Sandbox Code Playgroud)
确保起始位置足够嵌入以满足所有测试
idx = idx[idx > n - 1 & idx + n - 1 <= length(l)]
Run Code Online (Sandbox Code Playgroud)
然后检查连续远程运行的长度是否与条件一致,仅保留那些起始点
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]
}
Run Code Online (Sandbox Code Playgroud)
如果剩下任何值idx
,则这些是满足条件的rle的索引; 初始向量中的起始点是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
}
Run Code Online (Sandbox Code Playgroud)
这很快,并允许运行> =阈值,如问题中所规定的; 例如
x = sample(c(TRUE, FALSE), 1000000, TRUE)
system.time(runfun(x, rep(2, 5)))
Run Code Online (Sandbox Code Playgroud)
在不到1/5秒内完成.
有趣的概括允许灵活的条件,例如精确的运行list_n
,如在rollapply解决方案中
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
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
74 次 |
最近记录: |