是否有一系列`n`元素满足包含在两个`m`元素系列之间的条件,满足`x`中的另一个条件?

时间:2015-03-18 16:32:24

标签: r search boolean boolean-logic boolean-operations

这个问题是对these excellent answers的跟进。

根据我上面链接的答案,可以从数字x的向量中计算出是否存在满足条件的任何系列的至少n元素(例如,大于50)其中n元素系列包含在至少m元素的每一侧的至少一个系列之间,这些元素不满足相同的条件(有关更多信息,请参阅上面的帖子)。我的目标是概括此函数,以允许n元素系列的不同条件,而不是m元素系列的不同条件。下面我正在考虑链接帖子的两个答案之一的例子,但是从另一个答案修改函数可能更容易进行概括。

### Function ###

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
  }

### Examples ###

x = c(20, 11, 52, 53, 10, 2, 3, 51, 34, 54, 29)
n = 2
m = 3
runfun(TFvec = x>50, list_n = list(n,m)) # FALSE

x = c(20, 11, 44, 52, 53, 10, 2, 3, 51, 34, 54, 29)
n = 2
m = 3
runfun(TFvec = x>50, list_n = list(n,m)) # TRUE

我现在试图通过允许找到一系列至少n元素来满足至少m每侧至少一个系列的条件,从而进一步推动这个函数。满足另一个条件的元素。类似的东西:

runfun2(TFvec = list(x > 50, x < 40), list_n = list(n,m))
如果在n中至少有一系列至少x个元素大于50,并且此系列包含在至少两个系列之间(每侧一个),则

将返回TRUE在m中至少x个小于40的元素。

TFvec现在是一个长度与list_n相同的列表。对于TFvec列表中的元素相同runfun2的特殊情况,与runfun完全相同。为简单起见,可以假设x的元素在两个(或更多)可能的条件下永远不会成立。

1 个答案:

答案 0 :(得分:1)

像这样,也许:

f<-function(mcond,ncond,m,n){
  q<-rep(0,length(mcond))
  q[ncond]<-2
  q[mcond]<-1

  r<-rle(q)
  possible<-which(r$values==1
             & c(r$values[-1],0)==2
             & c(0,head(r$values,-1))==2
             )
  possible<-possible[r$lengths[possible]>=m &
                     r$lengths[possible+1]>=n &
                     r$lengths[possible-1]>=n]
  list(start=1+cumsum(r$lengths)[possible-1],length=r$lengths[possible])
}

示例:

> set.seed(123)                                        
> x<-sample(100,300,T)
> f(x>50,x<40,3,2)
$start
[1]  20 294

$length
[1] 9 4

> x[18:30]
 [1]   5  33  96  89  70  65 100  66  71  55  60  29  15
> x[292:299]
[1] 11  8 89 76 82 99 11 10