Remplacer les valeurs manquantes par la colonne moyenne

Je ne sais pas comment boucler chaque colonne pour remplacer les valeurs de NA par la moyenne de la colonne. Quand j'essaye de remplacer pour une colonne en utilisant ce qui suit, cela fonctionne bien.

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

Le code pour faire une boucle sur les colonnes ne fonctionne pas:

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

les valeurs ne sont pas remplacés. Quelqu'un peut-il m'aider avec cela?

28
demandé sur zx8754 2014-09-14 20:50:17

8 réponses

une modification relativement simple de votre code devrait résoudre le problème:

for(i in 1:ncol(data)){
  data[is.na(data[,i]), i] <- mean(data[,i], na.rm = TRUE)
}
45
répondu Thomas 2014-09-14 17:07:27

Si DF est votre bloc de données des colonnes numériques:

library(zoo)
na.aggregate(DF)

ajouté:

en utilisant seulement la base de R définissez une fonction qui le fait pour une colonne et ensuite lapidement à chaque colonne:

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

la dernière ligne peut être remplacée par la suivante s'il est possible d'écraser l'entrée:

DF[] <- lapply(DF, NA2mean)
35
répondu G. Grothendieck 2017-05-14 13:38:14

Pour ajouter des options, à l'aide de @akrun de l'échantillon de données, je voudrais faire le suivant:

d1[] <- lapply(d1, function(x) { 
  x[is.na(x)] <- mean(x, na.rm = TRUE)
  x
})
d1
9
répondu A5C1D2H2I1M1N2O1R2T1 2014-09-14 17:43:24

Vous pouvez également essayer:

 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))
5
répondu akrun 2014-09-14 17:19:45

lapply peut être utilisé au lieu d'un for boucle.

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

cela n'a pas vraiment d'avantages par rapport à la boucle for, mais peut-être est-ce plus facile si vous avez aussi des colonnes non numériques, auquel cas

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

est presque aussi facile.

3
répondu Ista 2016-12-17 15:51:48
# 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
2
répondu shekhar 2017-05-24 18:39:35

semblable à la réponse de @Thomas, Cela peut aussi être fait en utilisant ifelse() méthode de 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])
}

où, Argumentsifelse(TEST, YES , NO): -

TEST- condition logique à vérifier

Oui - exécuté si la condition est True

NO- d'autre lorsque la condition est Fausse

et ave(x, ..., FUN = mean) c'est la méthode dans la R utilisée pour le calcul des moyennes des sous-ensembles de x[]

1
répondu Aseem Yadav 2017-03-28 06:07:27

Il y a aussi la solution rapide en utilisant le imputeTS package:

library(imputeTS)
na.mean(yourDataFrame)
1
répondu stats0007 2018-05-04 00:20:04