Заменить отсутствующие значения на среднее значение столбца

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

Column1[is.na(Column1)] <- round(mean(Column1, na.rm = TRUE))

код для цикла по столбцам не работает:

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

значения не заменить. Кто-нибудь может мне помочь?

8 ответов


относительно простая модификация вашего кода должна решить проблему:

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

если DF - Это ваш фрейм данных числовых столбцов:

library(zoo)
na.aggregate(DF)

добавлено:

используя только базу R, определите функцию, которая делает это для одного столбца, а затем lapply для каждого столбца:

NA2mean <- function(x) replace(x, is.na(x), mean(x, na.rm = TRUE))
replace(DF, TRUE, lapply(DF, NA2mean))

последняя строка может быть заменена следующей, если можно перезаписать ввод:

DF[] <- lapply(DF, NA2mean)

чтобы добавить к альтернативам, используя примеры данных @akrun, я бы сделал следующее:

d1[] <- lapply(d1, function(x) { 
  x[is.na(x)] <- mean(x, na.rm = TRUE)
  x
})
d1

вы также можете попробовать:

 cM <- colMeans(d1, na.rm=TRUE)
 indx <- which(is.na(d1), arr.ind=TRUE)
 d1[indx] <- cM[indx[,2]]
 d1  

сведения

set.seed(42)
d1 <- as.data.frame(matrix(sample(c(NA,0:5), 5*10, replace=TRUE), ncol=10))

lapply можно использовать вместо for петли.

d1[] <- lapply(d1, function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x))

это на самом деле не имеет никаких преимуществ перед циклом for, хотя, возможно, это проще, если у вас есть нечисловые столбцы, а в этом случае

d1[sapply(d1, is.numeric)] <- lapply(d1[sapply(d1, is.numeric)], function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x))

почти так же легко.


# Lets say I have a dataframe , df as following -
df <- data.frame(a=c(2,3,4,NA,5,NA),b=c(1,2,3,4,NA,NA))

# create a custom function
fillNAwithMean <- function(x){
    na_index <- which(is.na(x))        
    mean_x <- mean(x, na.rm=T)
    x[na_index] <- mean_x
    return(x)
}

(df <- apply(df,2,fillNAwithMean))
   a   b
2.0 1.0
3.0 2.0
4.0 3.0
3.5 4.0
5.0 2.5
3.5 2.5

похоже на ответ, указанный @Thomas, Это также можно сделать с помощью ifelse() метод R:

for(i in 1:ncol(data)){
  data[,i]=ifelse(is.na(data[,i]),
                  ave(data[,i],FUN=function(y) mean(y, na.rm = TRUE)),
                  data[,i])
}

где, Аргументы to ifelse(TEST, YES , NO) являются:

тест- логическое условие для проверки

да- выполняется, если условие True

нет- else, когда условие ложно

и ave(x, ..., FUN = mean) метод в R используется для вычисления средних подмножеств x[]


существует также быстрое решение с помощью imputeTS:

library(imputeTS)
na.mean(yourDataFrame)