Как предотвратить интерполяцию между значениями, если пропущено более 2 строк данных? - PullRequest
1 голос
/ 09 апреля 2019

Я хотел бы написать условный оператор внутри mutate_at (), чтобы функция ок. () Не интерполировала значения, в которых более двух пропущенных строк данных.

Вот данные:

dat <- data.frame(
  time = 1:10, 
  var1 = c(10, 10, 10, 12, 12, 12, 15, 15, 15, 15), 
  var2 = c( 1, NA,  3,  6, NA, NA, NA, 10,  9,  8), 
  var3 = c(10, NA, NA, 13, 14, 16, NA, 18, 19, 20)
)

Кусок кода, который я хотел бы адаптировать так, чтобы он НЕ интерполировал там, где между значениями имеется более 2 NA (то есть строки 5-7 в столбце var2 должны оставаться NA и все другие NA.должны быть интерполированы значения.

library(tidyverse)

dat_int <- dat %>%
  mutate_at(vars(c(var2, var3)),
            funs(approx(time, ., time, rule = 1, method = "linear")[["y"]]))

1 Ответ

2 голосов
/ 10 апреля 2019

Шаг 1: Создайте функцию consecutiveNA, которая может идентифицировать последовательный NA в векторе на основе порога (заданного аргументом len).

consecutiveNA <- function(x, len = 2){
  rl <- rle(is.na(x))
  logi <- rl$lengths >= len & rl$values
  rl$values <- logi
  inver <- inverse.rle(rl)
  return(inver)
}

Шаг 2: Примените функцию approx к целевым столбцам (как вы сделали).

library(tidyverse)

dat_int <- dat %>%
  mutate_at(vars(c(var2, var3)),
            funs(approx(time, ., time, rule = 1, method = "linear")[["y"]]))

Шаг 3: Примените функцию consecutiveNA ко всем столбцам в dat и преобразуйте результат в матрицу.

m_NA <- map(dat, consecutiveNA, len = 2) %>%
  as.data.frame() %>%
  as.matrix()

Шаг 4: На основе m_NA заменить те TRUE на NA в dat_int, и тогда работа завершена.Вы можете изменить len на 3 или другие числа, чтобы увидеть, работает ли он.

dat_int[m_NA] <- NA

dat_int
#    time var1 var2 var3
# 1     1   10    1   10
# 2     2   10    2   NA
# 3     3   10    3   NA
# 4     4   12    6   13
# 5     5   12   NA   14
# 6     6   12   NA   16
# 7     7   15   NA   17
# 8     8   15   10   18
# 9     9   15    9   19
# 10   10   15    8   20
...