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?
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)
}
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)
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
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))
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.
# 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
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[]
Il y a aussi la solution rapide en utilisant le imputeTS package:
library(imputeTS)
na.mean(yourDataFrame)