【问题标题】:Get start and end ranges from a sequence containing gaps从包含间隙的序列中获取开始和结束范围
【发布时间】:2021-08-09 00:29:50
【问题描述】:

假设我有以下数据:

c(1:4,7:15,20:23,25,30:35,40,41)

我想从该向量中获取开始和结束范围。但是,我想跳过没有自然前任和后继的单个值(在示例中:25)。换句话说,应该至少有两个连续的值来构成一个“范围”。

本例中的起始范围是:1, 7, 20, 30, 40 它们对应的结束范围是:4, 15, 23, 35, 41

有没有优雅的内置解决方案?我几乎陷入了 for 循环地狱。

【问题讨论】:

    标签: r


    【解决方案1】:

    确定diff(x) > 1 的位置,通过将TRUE 添加到序列的开头或结尾来适当地滞后。 (diff(x) 生成一个比x 短一个元素的向量。)& 子句去掉了单例值。

    dx1 <- c(TRUE,diff(x)>1)
    dx2 <- c(diff(x)>1, TRUE)
    start <- x[dx1 & !dx2]
    end <-   x[dx2 & !dx1]
    

    可能还有一个类似 rle(diff(x)==1) 的解决方案,但它会比上面的解决方案稍微复杂一些(例如,如果您想识别特定长度的运行,它可能会很有用)。

    【讨论】:

    • 天哪!你用 4 行代码搞定了……非常感谢!
    【解决方案2】:

    不会对@Ben Bolker 的解决方案增加太多,但另一种方法可能是:

    ind <- aggregate(x ~ cumsum(c(FALSE, diff(x)) > 1), FUN = function(x) (length(x) > 1) * range(x))
    ind$x[ind$x[, 1] != 0, ]
    
         [,1] [,2]
    [1,]    1    4
    [2,]    7   15
    [3,]   20   23
    [4,]   30   35
    [5,]   40   41
    

    【讨论】:

      猜你喜欢
      • 2017-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多