-1

Hi I have a dataset with 4 columns (all numeric) and I am replacing missing value with mean value of column. Below code is neither giving error nor replacing value.

mi <- function(x){
  for( col in 1:ncol(x)){
    for( row in 1:nrow(x)){
      ifelse(is.na(x[row, col]), x[row,col] <- mean(x[, col], na.rm = TRUE), x[row, col])
    }
  }
}

please suggest..

bartektartanus
  • 15,284
  • 6
  • 74
  • 102
  • 4
    Please make a reproducible example. See http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example for some tips on how to do that. – Roman Luštrik Apr 19 '14 at 09:20

3 Answers3

1

Here's a pretty straightforward approach (with some reproducible sample data):

Some sample data:

set.seed(1)
df <- data.frame(matrix(sample(c(NA, 1:10), 100, TRUE), ncol = 4))
head(df)
#   X1 X2 X3 X4
# 1  2  4  5  9
# 2  4 NA  9  9
# 3  6  4  4  4
# 4  9  9  2  8
# 5  2  3 NA 10
# 6  9  5  1  4

Let's make a copy and replace NA with the column means.

df2 <- df
df2[] <- lapply(df2, function(x) { x[is.na(x)] <- mean(x, na.rm=TRUE); x })
head(df2)
#   X1       X2 X3 X4
# 1  2 4.000000  5  9
# 2  4 5.956522  9  9
# 3  6 4.000000  4  4
# 4  9 9.000000  2  8
# 5  2 3.000000  5 10
# 6  9 5.000000  1  4

Verify the correct values were inserted. Compare df2[2, 2] with the following:

mean(df$X2, na.rm = TRUE)
# [1] 5.956522
A5C1D2H2I1M1N2O1R2T1
  • 190,393
  • 28
  • 405
  • 485
0

The argument x is a copy of the original. You need to return the modified value:

mi <- function(x){
  for( col in 1:ncol(x)){
    for( row in 1:nrow(x)){
      ifelse(is.na(x[row, col]), x[row,col] <- mean(x[, col], na.rm = TRUE), x[row, col])
    }
  }
  return(x)
}
ggoossen
  • 1
  • 2
0

Or like this:

x <- matrix(sample(c(NA,1:10),100,TRUE),nrow=10)
x
          [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
     [1,]    7    7    1    6    7    3   10    4   NA     2
     [2,]    3    2    7    9    1    4    2    5   10     1
     [3,]   10    4    2    8    7    4    1    8    8     3
     [4,]    7    7    6    9    2    6   NA    6    6    10
     [5,]    1   NA    5    9    9    4   NA    5    8     2
     [6,]    4    4    9    3    9    4    5   NA    5     1
     [7,]   NA    2    2    2    9    2   10   NA    8     7
     [8,]   10    8    7    1    5    2    9    7   10     5
     [9,]    6    3   10    9    8    6    7   10    3    10
    [10,]    7    9    5    2    2    9    5    6   NA     9
means <- colMeans(x,na.rm=TRUE)
for(i in 1:ncol(x)){
   x[is.na(x[,i]),i] <- means[i]
}
x
               [,1]     [,2] [,3] [,4] [,5] [,6]   [,7]   [,8]  [,9] [,10]
     [1,]  7.000000 7.000000    1    6    7    3 10.000  4.000  7.25     2
     [2,]  3.000000 2.000000    7    9    1    4  2.000  5.000 10.00     1
     [3,] 10.000000 4.000000    2    8    7    4  1.000  8.000  8.00     3
     [4,]  7.000000 7.000000    6    9    2    6  6.125  6.000  6.00    10
     [5,]  1.000000 5.111111    5    9    9    4  6.125  5.000  8.00     2
     [6,]  4.000000 4.000000    9    3    9    4  5.000  6.375  5.00     1
     [7,]  6.111111 2.000000    2    2    9    2 10.000  6.375  8.00     7
     [8,] 10.000000 8.000000    7    1    5    2  9.000  7.000 10.00     5
     [9,]  6.000000 3.000000   10    9    8    6  7.000 10.000  3.00    10
    [10,]  7.000000 9.000000    5    2    2    9  5.000  6.000  7.25     9

This is not quite exactly what you are looking for but might be useful. This function substitute all NA with median (in every column):

require(randomForest)
x <- matrix(sample(c(NA,1:10),100,TRUE),nrow=10)
na.roughfix(x)
bartektartanus
  • 15,284
  • 6
  • 74
  • 102