Я хотел бы сделать последнее наблюдение, перенесенное на переменную, но только до двух наблюдений. То есть для пробелов в данных 3 или более NA я бы перенес только последнее наблюдение для следующих 2 наблюдений, а остальные оставил как 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)
4
user3507584 13 Сен 2018 в 16:47

2 ответа

Лучший ответ

Решение с использованием базы 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 значение этой группы.

3
mt1022 13 Сен 2018 в 14:26

Сначала примените na.locf0 с maxgap = 2, дающим x0, и определите группирующую переменную g, используя rleid из пакета data.table. Для каждой такой группы используйте ave, чтобы применить keeper, который, если вся группа является NA, заменяет ее на c (1, 1, NA, ..., NA), а в противном случае выводит все единицы. Умножьте на это 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
4
G. Grothendieck 13 Сен 2018 в 14:22