Один вариант:
library(dplyr)
df %>%
group_by(idx = cumsum(!(is.na(a) | a == 0)), is.na(a)) %>%
mutate(rn = row_number()) %>%
group_by(idx) %>%
mutate(a = coalesce(a, first(a) + rn)) %>%
ungroup() %>%
select(a)
Вывод:
# A tibble: 12 x 1
a
<int>
1 11127
2 0
3 0
4 11128
5 0
6 0
7 11129
8 0
9 11580
10 0
11 11581
12 0
Если скорость является проблемой, возможно, эквивалент data.table
будет немного быстрее:
library(data.table)
setDT(df)[, rn := rowid(a), .(cumsum(!(is.na(a) | a == 0)), is.na(a))][
, a := fcoalesce(a, first(a) + rn), by = cumsum(!(is.na(a) | a == 0))][
, rn := NULL]
РЕДАКТИРОВАТЬ
Группировка IMO, а затем получение индекса строки для NA
s не очень элегантно; гораздо лучше, чем вы можете видеть в других решениях (например, используя cumsum
).
Используя fcoalesce
, проблема может быть решена за один data.table
шаг:
library(data.table)
setDT(df)[, a := fcoalesce(a, first(a) + cumsum(is.na(a))), by = cumsum(!(is.na(a) | a == 0))]