Условное среднее для нескольких столбцов в R? - PullRequest
0 голосов
/ 05 ноября 2019

Мои данные таковы:

train <- data.frame(y=c(1,2,1,1), x1=c(2,4,NA,5), x2=c(8,NA,6,12))

Мне нужно заменить для каждой переменной x отсутствующие значения (NA) на среднее значение этого столбца, но среднее значение должно быть рассчитано с использованием значений этой переменной xкоторые имеют соответствующее значение y, равное значению y строки этого пропущенного значения.

Например: в строке, где NA столбца x1, значение y равно 1, так чтопропущенное значение следует заменить на среднее от 2 до 5 (которые представляют собой значения x1, для которых y также равно 1).

Мой код такой, но среднее значение не является условным:

for(i in 1:ncol(train)){
  train[is.na(train[,i]), i] <- mean(train[,i], na.rm = TRUE)
}

Ответы [ 3 ]

0 голосов
/ 05 ноября 2019

Мы можем использовать na.aggregate после группировки по столбцу 'y'

library(dplyr)
library(zoo)
train %>%
  group_by(y) %>%
   mutate_at(vars(-one_of(group_vars(.))),
             ~if(all(is.na(.))) NA_real_ else na.aggregate(.))
# A tibble: 4 x 3
# Groups:   y [2]
#      y    x1    x2
#  <dbl> <dbl> <dbl>
#1     1   2       8
#2     2   4      NA
#3     1   3.5     6
#4     1   5      12

Или применить na.aggregate после split, когда набор данных list равен data.frameна основе столбца 'y'

train[-1] <- unsplit(lapply(split(train[-1], train$y), na.aggregate), train$y)
0 голосов
/ 06 ноября 2019

Рассмотрим ave для группового среднего значения, заключенного в условие ifelse для NA или нет:

# ITERATE THROUGH ALL COLUMNS BUT FIRST
for(i in c("x1", "x2")) {    
    train[[i]] <- ifelse(test = is.na(train[[i]]), 
                         yes = ave(train[[i]], train$y, FUN=function(x) mean(x, na.rm=TRUE)), 
                         no = train[[i]])
}

train   
#   y  x1  x2
# 1 1 2.0   8
# 2 2 4.0 NaN
# 3 1 3.5   6
# 4 1 5.0  12
0 голосов
/ 05 ноября 2019
library(dplyr)
train %>%
    group_by(y) %>%
    mutate_at(vars(-y), function(v){
        if_else(is.na(v), mean(v, na.rm = TRUE), v)
    }) %>%
    ungroup()
## A tibble: 4 x 3
#      y    x1    x2
#  <dbl> <dbl> <dbl>
#1     1   2       8
#2     2   4     NaN
#3     1   3.5     6
#4     1   5      12
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...