Как заменить НС средним из ближайших двух значений - PullRequest
2 голосов
/ 06 апреля 2020

У меня есть эти данные:

data <- structure(list(A = c(10L, 25L, NA, 17L, 8L, 3L), B = c(2L, NA, 
NA, NA, NA, 2L), C = c(NA, 4L, 6L, 4L, 3L, NA)), class = "data.frame", row.names = c(NA, 
-6L))

Я хочу заменить NA в каждом столбце средним из двух ближайших доступных значений в этом столбце. Для результата должно быть, как показано ниже:

data <- structure(list(A = c(10L, 25L, 21L, 17L, 8L, 3L), B = c(2L, 2L, 
2L, 2L, 2L, 2L), C = c(4L, 4L, 6L, 4L, 3L, 3L)), class = "data.frame", row.names = c(NA, 
-6L))

Ответы [ 2 ]

2 голосов
/ 07 апреля 2020

Вот базовое решение R с использованием approx с опцией rule=2

data[] <- Map(function(x) approx(seq_along(x)[!is.na(x)],
                                 na.omit(x),
                                 seq_along(x),
                                 rule = 2)$y, 
              data)

, такой что

> data
   A B C
1 10 2 4
2 25 2 4
3 21 2 6
4 17 2 4
5  8 2 3
6  3 2 3
2 голосов
/ 06 апреля 2020

Мы можем использовать na.approx

library(zoo)
data[] <- lapply(data,  function(x) na.locf0(na.approx(x, na.rm = FALSE)))

Или с tidyverse

library(dplyr)
library(tidyr)
data %>%
  mutate_all(na.approx, na.rm = FALSE) %>%
  fill(everything(), .direction = 'updown')
#  A B C
#1 10 2 4
#2 25 2 4
#3 21 2 6
#4 17 2 4
#5  8 2 3
#6  3 2 3

data

data <- structure(list(A = c(10L, 25L, NA, 17L, 8L, 3L), 
   B = c(2L, NA, NA, NA, NA, 2L), 
   C = c(NA, 4L, 6L, 4L, 3L, NA)), class = "data.frame", row.names = c(NA, -6L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...