Ограничить na.locf в пакете зоопарка - PullRequest
0 голосов
/ 13 сентября 2018

Я хотел бы сделать последнее наблюдение, перенесенное для переменной, но только до 2 наблюдений. То есть для пробелов в данных из 3 или более NA я перенесу только последнее наблюдение для следующих двух наблюдений, а остальное оставлю как NA.

Если я делаю это с zoo::na.locf, параметр maxgap подразумевает, что если зазор больше 2, никакой NA не заменяется. Даже не последний 2. Есть ли альтернатива?

x <- c(NA,3,4,5,6,NA,NA,NA,7,8)
zoo::na.locf(x, maxgap = 2) # Doesn't replace the first 2 NAs of after the 6 as the gap of NA is 3. 
Desired_output <- c(NA,3,4,5,6,6,6,NA,7,8)

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Решение с использованием базы R:

ave(x, cumsum(!is.na(x)), FUN = function(i){ i[1:pmin(length(i), 3)] <- i[1]; i })
# [1] NA  3  4  5  6  6  6 NA  7  8

cumsum(!is.na(x)) группирует каждый прогон NA с самым последним не NA значением.

function(i){ i[1:pmin(length(i), 3)] <- i[1]; i } преобразует первые два NA с каждой группы в ведущее не NA значение этой группы.

0 голосов
/ 13 сентября 2018

Сначала примените na.locf0 с maxgap = 2, давая x0 и определите переменную группировки g, используя rleid из пакета data.table.Для каждой такой группы используйте ave, чтобы применить keeper, которая, если вся группа является NA, заменяет ее на c (1, 1, NA, ..., NA) и в противном случае выводит все 1.Умножьте na.locf0(x) на это.

library(data.table)
library(zoo)

mg <- 2
x0 <- na.locf0(x, maxgap = mg)
g <- rleid(is.na(x0))
keeper <- function(x) if (all(is.na(x)))  ifelse(seq_along(x) <= mg, 1, NA) else 1
na.locf0(x) * ave(x0, g, FUN = keeper)
## [1] NA  3  4  5  6  6  6 NA  7  8
...