【问题标题】:How to accumulate streaks in vector如何在向量中累积条纹
【发布时间】:2021-12-06 10:15:36
【问题描述】:

我以这种方式有一个 0 和 1 的序列:

xx <- c(1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1)

我想创建一个向量来累积零的条纹并将累积的条纹添加到下一个可能的值 1。这个特定向量中的结果应该是:

yy <- c(1, 1, 1, 0, 0, 3, 0, 2, 0, 0, 0, 4)

在 R 中最快、最有效的方法是什么?

【问题讨论】:

    标签: r vector accumulate


    【解决方案1】:

    base R 的一个解决方案可能是:

    with(rle(xx), rep(values + c(0, head(lengths * (values == 0), -1)), lengths))
    
     [1] 1 1 1 0 0 3 0 2 0 0 0 4
    

    【讨论】:

      【解决方案2】:

      这个基本的 R 实现可能不是最有效的实现,因此如果其他人提出答案,比较性能会很有趣。

      代码

      idx_add <- which(xx == 1 & c(NA, xx[-length(xx)]) == 0)
      xx_rle <- rle(xx)
      n_add <- xx_rle$lengths[xx_rle$values == 0]
      yy <- xx
      yy[idx_add] <- yy[idx_add] + n_add
      

      解释

      idx_add <- which(xx == 1 & c(NA, xx[-length(xx)]) == 0)
      

      这一行在xx 中查找我们将添加到的索引。在这些地方,我们有一个1,前面至少有一个0。所以我们得到c(6, 8, 12)

      xx_rle <- rle(xx)
      

      这里我们使用rle()(运行长度编码)函数来获取向量xx中所有连续值条纹的长度。 xx_rle 有两个元素,lengths,条纹的长度;和values,它们的值(1s 和0s)。

      n_add <- xx_rle$lengths[xx_rle$values == 0]
      

      这里我们只提取零条纹的条纹长度。

      yy <- xx
      yy[idx_add] <- yy[idx_add] + n_add
      

      现在创建xx 的副本,并将零条纹长度添加到条纹之后的第一个1。这会给你想要的结果!

      【讨论】:

        【解决方案3】:

        使用dplyr

        数据:

        xx <- c(1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1)
        

        代码:

        yy <- as.data.frame(xx) %>% 
          mutate(group = ifelse(xx != 0, 1, 0),
                 group = cumsum(group) + 1,
                 group = ifelse(xx != 0, 0, group)) %>% 
          group_by(group) %>% 
          mutate(group = n() + 1) %>% 
          ungroup() %>% 
          mutate(yy = ifelse(xx != 0 & lag(xx) == 0, lag(group), xx),
                 yy = ifelse(is.na(yy),xx,yy)) %>% 
          select(yy) %>% 
          pull()
        

        输出:

        [1] 1 1 1 0 0 3 0 2 0 0 0 4
        

        【讨论】:

          猜你喜欢
          • 2017-06-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-20
          • 1970-01-01
          • 2018-03-28
          相关资源
          最近更新 更多