Вот несколько подходов, каждый из которых, по сути, делает то же самое:
- Добавить столбец
val_tofill
, заменив все негодные значения на NA
s - Используйте один измного доступных методов для перенаправления заполнения
val_tofill
, см., например, Замена NA на последнее не-значение NA - Перезаписать столбец
val
на val_tofill
всякий раз, когда номер строки не является одним изпервые шесть группы (сгруппированные по closest.idx
)
Исходные данные
a <- data.frame(
date=as.Date('2011-1-1') + 0:59,
closest.idx=c(rep(1,20), rep(2, 20), rep(3, 20)),
is.good=c(rep(1,20), rep(1,20), rep(0, 20)),
val=c(rep(.2, 6), rep(.3, 14), rep(.4, 6), rep(.5, 14), rep(.6, 6), rep(.7, 14))
)
base + zoo :: na.locf
a$val_tofill <- zoo::na.locf(ifelse(a$is.good > 0, a$val, NA))
a$val <- unlist(
by(a, INDICES = a$closest.idx,
FUN = function(x) ifelse(seq_len(nrow(x)) < 7, x$val, x$val_tofill)
)
)
a$val_tofill <- NULL
dplyr + tidyr :: fill
library(tidyverse)
mutate(a, val_tofill = ifelse(is.good > 0, val, NA)) %>%
fill(val_tofill, .direction = "down") %>%
group_by(closest.idx) %>%
mutate(val = ifelse(row_number() < 7, val, val_tofill)) %>%
ungroup() %>%
select(-val_tofill)
data.table + zoo :: na.locf
library(data.table)
a <- setDT(a)
a[, val_tofill := zoo::na.locf(ifelse(is.good > 0, val, NA))][,
val := ifelse(seq_len(.N) < 7, val, val_tofill),
by = closest.idx
]
a$val_tofill <- NULL