【问题标题】:How to obtain a position of last non-zero element如何获得最后一个非零元素的位置
【发布时间】:2019-09-02 05:01:36
【问题描述】:

我有一个表示事件是否发生的二进制变量:

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

我需要获取一个变量来指示最后一个事件发生的时间。预期的输出是:

last_event <- c(0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 13, 13, 13, 13)

如何使用 base R、tidyverse 或任何其他方式获得它?

【问题讨论】:

    标签: r tidyverse base


    【解决方案1】:

    利用你有一个二进制向量的事实,以下给出了你想要的输出:

    cummax(seq_along(event) * event)
    

    【讨论】:

    • 是的!比我的解决方案优雅得多。我正在考虑累积和,但我没有想到将索引乘以二进制向量。
    • 或不加乘法cummax(ifelse(event, seq_along(event), 0))
    • @jogo 如果event 的类型是logical,那么该解决方案是有意义的。由于 R 的隐式转换,它甚至对数字向量也有效,但是……嗯。
    【解决方案2】:

    当你需要用一个值填充重复时,想想run-length encoding

    在这种情况下,您可以确定运行长度,然后根据次数重复count == 0 的索引:

    lengths = rle(event == 0)$lengths
    nonzeros = which(event != 0)
    runs = c(0, rep(nonzeros, each = 2))
    result = rep(runs, lengths)
    

    替代方案,替换 RLE 中的运行,然后将其反转:

    rle = rle(event == 0)
    nonzeros = which(event != 0)
    rle$values = c(0, rep(nonzeros, each = 2))
    result = inverse.rle(rle)
    

    【讨论】:

      【解决方案3】:

      你也可以这样做-

      > zero.locf <- function(x) {
        v <- x!=0
        c(0, x[v])[cumsum(v)+1]
      }
      
      > zero.locf(1:length(event)*event)
      
      [1]  0  0  0  0  5  5  5  5  5  5  5  5 13 13 13 13
      

      【讨论】:

        【解决方案4】:

        另一种选择是找到event == 1 所在的索引并根据length 重复它。

        rep(c(0, which(event == 1)), tapply(event, cumsum(event == 1), length))
        #[1]  0  0  0  0  5  5  5  5  5  5  5  5 13 13 13 13
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-13
          • 1970-01-01
          相关资源
          最近更新 更多