【问题标题】:Get a vector with the count of consecutive specific values in R获取一个向量,其中包含 R 中连续特定值的计数
【发布时间】:2020-05-31 20:00:48
【问题描述】:

我有一个如下所示的数据框:

    (TimeDate,Movement,Booked)

    1   2017-01-02 09:00:13 FALSE   TRUE
    2   2017-01-02 09:01:13 FALSE   TRUE
    3   2017-01-02 09:02:15 TRUE    TRUE
    4   2017-01-02 09:03:13 TRUE    TRUE
    5   2017-01-02 09:04:13 FALSE   FALSE
    6   2017-01-02 09:05:13 FALSE   FALSE
    7   2017-01-02 09:06:13 FALSE   TRUE
    8   2017-01-02 09:07:13 FALSE   TRUE
    9   2017-01-02 09:08:14 TRUE    TRUE
    10  2017-01-02 09:09:13 FALSE   TRUE

它有一个一分钟一分钟的日志,其中有两个布尔值对应于检测到的移动和房间预订。我想要获得的是一个向量,它计算运动和预定comumns的 (FALSE,TRUE) 的连续出现,所以在这种情况下,我想要一个像这样的结果向量:

    c(2,2,1)

第一个元素是第 1 行和第 2 行的计数,第二个元素是第 7 和 8 行,最后一个元素是第 10 行。

老实说,我什至不知道如何开始。 谢谢!

【问题讨论】:

    标签: r run-length-encoding


    【解决方案1】:

    这个怎么样?对于每一行,检查您是否获得了正确的序列,然后使用rle

    xy <- read.table(text = "FALSE   TRUE
    FALSE   TRUE
    TRUE    TRUE
    TRUE    TRUE
    FALSE   FALSE
    FALSE   FALSE
    FALSE   TRUE
    FALSE   TRUE
    TRUE    TRUE
    FALSE   TRUE", header = FALSE)
    colnames(xy) <- c("Movement", "Booked")
    
    out <- rle(apply(xy, MARGIN = 1, FUN = function(x) !isTRUE(x[1]) & isTRUE(x[2])))
    out$lengths[out$values == TRUE]
    
    [1] 2 2 1
    

    另一个更简单的选择是

    out <- rle(xy$Movement == FALSE & xy$Booked == TRUE)
    out$lengths[out$values == TRUE]
    

    【讨论】:

      【解决方案2】:

      编辑:发帖时没有看到 Roman 的相同解决方案。

      我们想要这样的东西:

      tmp <- rle(with(df, !Movement & Booked))
      tmp$lengths[tmp$values]
      

      tmp$values 的索引确保您只获得与您指定的模式相对应的行。

      希望这会有所帮助!

      【讨论】:

        【解决方案3】:

        这是rleid 的一个选项,我们根据“Movement”中的 FALSE 和 Booked TRUE 创建一个分组列,获取该列的 count

        library(dplyr)
        library(data.table)
        df1 %>%
             mutate(rl = rleid(!Movement, Booked)) %>%
             filter(!(! Movement & Booked)) %>% 
             count(rl) %>%
             pull(n)
        #[1] 2 2 1
        

        或者使用rle 来自base R

        with(df1, with(rle(paste(Movement, Booked)), lengths[values == 'FALSE TRUE']))
        #[1] 2 2 1
        

        或使用紧凑的方式

        with(df1, table(rleid(Movement, Booked)[!Movement & Booked]))
        
        #1 4 6 
        #2 2 1 
        

        数据

        df1 <- structure(list(TimeDate = c("2017-01-02 09:00:13", "2017-01-02 09:01:13", 
        "2017-01-02 09:02:15", "2017-01-02 09:03:13", "2017-01-02 09:04:13", 
        "2017-01-02 09:05:13", "2017-01-02 09:06:13", "2017-01-02 09:07:13", 
        "2017-01-02 09:08:14", "2017-01-02 09:09:13"), Movement = c(FALSE, 
        FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE), 
            Booked = c(TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, 
            TRUE, TRUE)), class = "data.frame", row.names = c("1", "2", 
        "3", "4", "5", "6", "7", "8", "9", "10"))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-07-06
          • 2021-07-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-15
          • 2023-03-20
          • 1970-01-01
          相关资源
          最近更新 更多