Как получить позицию последнего ненулевого элемента - PullRequest
19 голосов
/ 11 апреля 2019

У меня есть двоичная переменная, представляющая, произошло событие или нет:

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)

Как я могу получить это с базой R, Tidyverse или любым другим способом?

Ответы [ 4 ]

18 голосов
/ 11 апреля 2019

Используя тот факт, что у вас есть двоичный вектор, вы получите желаемый результат:

cummax(seq_along(event) * event)
8 голосов
/ 11 апреля 2019

Всякий раз, когда вам нужно заполнить повторы значением, подумайте: Кодировка длины серии .

В этом случае вы можете определить длины серии, а затем повторить индексы 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)
1 голос
/ 11 апреля 2019

Другой вариант - найти индекс где 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
1 голос
/ 11 апреля 2019

Вы также можете сделать что-то вроде этого -

> 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
...