Je ne suis pas sûr de savoir comment passer en boucle sur chaque colonne pour remplacer les valeurs de NA par la moyenne de colonne. Lorsque je tente de remplacer une colonne à l’aide de ce qui suit, cela fonctionne bien.
Column1[is.na(Column1)] <- round(mean(Column1, na.rm = TRUE))
Le code pour boucler 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ées. Quelqu'un pourrait m'aider avec ça?
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 cadre de données de colonnes numériques:
library(Zoo)
na.aggregate(DF)
AJOUTÉE:
En utilisant uniquement la base de R, définissez une fonction qui le fait pour une colonne, puis lapply à 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 si vous pouvez remplacer l’entrée:
DF[] <- lapply(DF, NA2mean)
Pour ajouter aux alternatives, en utilisant les exemples de données de @ akrun, je procéderais comme suit:
d1[] <- lapply(d1, function(x) {
x[is.na(x)] <- mean(x, na.rm = TRUE)
x
})
d1
Vous pouvez aussi 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é à la place d'une boucle for
.
d1[] <- lapply(d1, function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x))
Cela n’a aucun avantage par rapport à la boucle for, bien que ce soit peut-être plus facile si vous avez également 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
Similaire à la réponse indiquée par @Thomas, Ceci peut également être effectué à l'aide de la méthode ifelse()
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ù, Les arguments à ifelse(TEST, YES , NO)
sont: -
TEST- condition logique à vérifier
OUI- exécuté si la condition est vraie
NO- sinon lorsque la condition est fausse
et ave(x, ..., FUN = mean)
est la méthode de R utilisée pour calculer les moyennes de sous-ensembles de x []
Il existe aussi une solution rapide en utilisant le paquet imputeTS :
library(imputeTS)
na.mean(yourDataFrame)
dplyr
's mutate_all
ou mutate_at
pourrait être utile ici:
library(dplyr)
set.seed(10)
df <- data.frame(a = sample(c(NA, 1:3) , replace = TRUE, 10),
b = sample(c(NA, 101:103), replace = TRUE, 10),
c = sample(c(NA, 201:203), replace = TRUE, 10))
df
#> a b c
#> 1 2 102 203
#> 2 1 102 202
#> 3 1 NA 203
#> 4 2 102 201
#> 5 NA 101 201
#> 6 NA 101 202
#> 7 1 NA 203
#> 8 1 101 NA
#> 9 2 101 203
#> 10 1 103 201
df %>% mutate_all(~ifelse(is.na(.x), mean(.x, na.rm = TRUE), .x))
#> a b c
#> 1 2.000 102.000 203.0000
#> 2 1.000 102.000 202.0000
#> 3 1.000 101.625 203.0000
#> 4 2.000 102.000 201.0000
#> 5 1.375 101.000 201.0000
#> 6 1.375 101.000 202.0000
#> 7 1.000 101.625 203.0000
#> 8 1.000 101.000 202.1111
#> 9 2.000 101.000 203.0000
#> 10 1.000 103.000 201.0000
df %>% mutate_at(vars(a, b),~ifelse(is.na(.x), mean(.x, na.rm = TRUE), .x))
#> a b c
#> 1 2.000 102.000 203
#> 2 1.000 102.000 202
#> 3 1.000 101.625 203
#> 4 2.000 102.000 201
#> 5 1.375 101.000 201
#> 6 1.375 101.000 202
#> 7 1.000 101.625 203
#> 8 1.000 101.000 NA
#> 9 2.000 101.000 203
#> 10 1.000 103.000 201