【问题标题】:finding interval indices of values in a vector, when intervals may be overlapped当区间可能重叠时,查找向量中值的区间索引
【发布时间】:2023-03-04 13:19:01
【问题描述】:

我想在属于区间的向量中找到值的索引,这些区间由结束值向量和 1)“回顾”值区间和 2)前 N 个值定义。

假设我有

x <- c(1,3,4,5,7,8,9,10,13,14,15,16,17,18) #the vector of interest
v_end <- c(5, 7, 15) #the end values
l<-3 #look-back value interval
N<-3 #number of value to look back

我想要的是以下输出的第二列和第三列。

       x i n
 [1,]  1 0 1
 [2,]  3 1 1
 [3,]  4 1 1
 [4,]  5 1 1
 [5,]  7 1 1
 [6,]  8 0 0
 [7,]  9 0 0
 [8,] 10 0 1
 [9,] 13 1 1
[10,] 14 1 1
[11,] 15 1 1
[12,] 16 0 0
[13,] 17 0 0
[14,] 18 0 0

注意 v_end 和 l 产生三个区间 [2,5],[4,7],[12,15]。 [2,5]和[4,7]有重叠,本质上是[2,7]。 并且,v_end 和 l 产生三个区间 [1,5]、[3,7]、[10,15]。再次有重叠。

任务类似于函数findInterval{base},但不能解决。

【问题讨论】:

    标签: r find intervals


    【解决方案1】:

    已经订购了“v_end”和“x”(对于“N”情况),“l”情况的间隔是:

    ints = cbind(start = v_end - l, end = v_end)
    ints
    #     start end
    #[1,]     2   5
    #[2,]     4   7
    #[3,]    12  15
    

    它们的重叠可以归为:

    overlap_groups = cumsum(c(TRUE, ints[-nrow(ints), "end"] < ints[-1, "start"]))
    

    可用于减少重叠的间隔:

    group_end = cumsum(rle(overlap_groups)$lengths)
    group_start = c(1L, group_end [-length(group_end )] + 1L)
    
    ints2 = cbind(start = ints[group_start, "start"], end = ints[group_end, "end"])
    ints2
    #     start end
    #[1,]     2   7
    #[2,]    12  15
    

    然后使用findInterval:

    istart = findInterval(x, ints2[, "start"])
    iend = findInterval(x, ints2[, "end"], left.open = TRUE)
    
    i = as.integer((istart - iend) == 1L)
    i
    # [1] 0 1 1 1 1 0 0 0 1 1 1 0 0 0
    

    对于“N”的情况,以:

    ints = cbind(start = x[match(v_end, x) - N], end = v_end)
    ints
    #     start end
    #[1,]     1   5
    #[2,]     3   7
    #[3,]    10  15
    

    按照上述步骤,我们得到:

    #.....
    n = as.integer((istart - iend) == 1L)
    n
    # [1] 1 1 1 1 1 0 0 1 1 1 1 0 0 0
    

    通常,用于此类操作的便捷工具是“IRanges”包,在这里,它使方法变得简单:

    library(IRanges)
    
    xrng = IRanges(x, x)
    i = as.integer(overlapsAny(xrng, reduce(IRanges(v_end - l, v_end), min.gapwidth = 0)))
    i
    # [1] 0 1 1 1 1 0 0 0 1 1 1 0 0 0
    n = as.integer(overlapsAny(xrng, reduce(IRanges(x[match(v_end, x) - N], v_end), min.gapwidth = 0)))
    n
    # [1] 1 1 1 1 1 0 0 1 1 1 1 0 0 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-17
      • 2022-01-26
      • 2014-11-07
      • 1970-01-01
      • 2020-01-28
      相关资源
      最近更新 更多