【问题标题】:Get start and end index of runs of values [duplicate]获取值运行的开始和结束索引[重复]
【发布时间】:2017-10-26 18:30:37
【问题描述】:

我有一个向量:

a <- c(1, 1, 0, 0, 1, 2, 0, 0)

我想获得每次运行相等值的开始和结束索引:

number start  end
0        3     4
0        7     8
1        1     2
1        5     5
2        6     6

【问题讨论】:

    标签: r sequence


    【解决方案1】:

    来自基础 R 的解决方案。

    a <- c(1,1,0,0,1,2,0,0)
    
    # Get run length encoding
    b <- rle(a)
    
    # Create a data frame
    dt <- data.frame(number = b$values, lengths = b$lengths)
    # Get the end
    dt$end <- cumsum(dt$lengths)
    # Get the start
    dt$start <- dt$end - dt$lengths + 1
    
    # Select columns
    dt <- dt[, c("number", "start", "end")]
    # Sort rows
    dt <- dt[order(dt$number), ]
    
    dt
    #  number start end
    #2      0     3   4
    #5      0     7   8
    #1      1     1   2
    #3      1     5   5
    #4      2     6   6
    

    更新

    这里有一个使用with的解决方案,让代码更简洁。

    with(rle(a), data.frame(number = values,
                            start = cumsum(lengths) - lengths + 1,
                            end = cumsum(lengths))[order(values),])
    #  number start end
    #2      0     3   4
    #5      0     7   8
    #1      1     1   2
    #3      1     5   5
    #4      2     6   6
    

    【讨论】:

    • @d.b 感谢您的提示。
    【解决方案2】:

    通过使用来自data.tabledplyrrleid

    library(data.table)
    library(dplyr)
    a=c(1,1,0,0,1,2,0,0)
    df=data.frame(number=c(1,1,0,0,1,2,0,0))
    df$Id=data.table::rleid(df$number)
    df$rowname=seq(1:length(a))
    df%>%group_by(Id,number)%>%summarise(start=first(rowname),end=last(rowname))%>%arrange(number)
    
    # Groups:   Id [5]
         Id number start   end
      <int> <dbl> <int> <int>
    1     2     0     3     4
    2     5     0     7     8
    3     1     1     1     2
    4     3     1     5     5
    5     4     2     6     6
    

    【讨论】:

      【解决方案3】:

      在基础 R 中使用 for 循环的解决方案:

      a <- c(1, 1, 0, 0, 1, 2, 0, 0)
      
      start <- 1
      res <- data.frame()
      v <- c(a, -1) # add number that is different from all other numbers
      
      for (index in 1:(length(v) - 1)) {
        if (v[index] != v[index + 1]) {
          res <- rbind(res, 
                       data.frame(element = v[index], start = start, stop = index))
          start <- index + 1
        }
      }
      

      这给出了:

        element start stop
      1       1     1    2
      2       0     3    4
      3       1     5    5
      4       2     6    6
      5       0     7    8
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-17
        • 1970-01-01
        • 2017-10-08
        • 1970-01-01
        • 2018-12-29
        • 1970-01-01
        • 2020-11-19
        • 1970-01-01
        相关资源
        最近更新 更多