Применение среднего вменения по большому подмножеству переменных в R

У меня есть набор данных с 498 переменными различных типов, числовыми, логическими, датами и другими, и у меня есть это как фрейм данных в R со строками для наблюдений и столбцами для переменных. Существует определенное подмножество этих переменных, для которых я хотел бы заменить их отсутствующие значения средним значением для этой переменной.

Я закодировал эту очень простую функцию для вменения среднего значения:

impute.mean <- function(x) replace(x, is.na(x), mean(x, na.rm = TRUE))

И это прекрасно работает, если я применяю к отдельной переменной, скажем, набор данных $variableA:

dataset$variableA <- impute.mean(dataset$variableA)

И это дает мне именно то, что я хочу для переменной one, но поскольку у меня есть довольно большое подмножество переменных, для которых мне нужно сделать это, я бы не хотел делать это вручную, проходя через каждая переменная, которая нуждается в условном исчислении.

Моим первым побуждением было использовать одну из функций применения в R, чтобы сделать это эффективно, однако я, похоже, не понимаю, как именно это сделать.

Грубая первая попытка заключалась в использовании стандартного применения:

newdataset <- apply(dataset, 2, impute.mean)

Очевидно, что это немного грубо, так как функция пытается применить функцию ко всем столбцам, включая переменные, которые не являются числовыми, однако это кажется разумной отправной точкой, даже если это может генерировать ряд предупреждений. Увы, этот способ не сработал и все мои переменные остались прежними.

Я также провел несколько экспериментов с lapply, mapply, ddply, но пока безуспешно.

В идеале я хотел бы иметь возможность сделать что-то вроде этого:

relevantVariables <- c("variableA1", "variableA2", ..., "variableA293")
newdataset <- magical.apply(dataset, relevantVariables, impute.mean)

Есть ли какая-то функция применения, которая работает таким образом?

В качестве альтернативы, есть ли другой эффективный способ сделать это?


person Henrik Nordmark    schedule 25.06.2013    source источник


Ответы (2)


Вы можете сделать это эффективно с помощью пакета data.table:

SetNAsToMean <- function(dt, vars) {                                                                                                                             
  # Sets NA values of columns to the column means                                                                                                                
  #                                                                                                                                                              
  # Args:                                                                                                                                                        
  #   dt: data.table object to work with                                                                                                                         
  #   vars: vector of column names to replace NAs                                                                                                                
  #                                                                                                                                                              
  # Returns:                                                                                                                                                     
  #   Nothing. Alters data.table in place.                                                                                                                       
  #                                                                                                                                                              
  # Example:                                                                                                                                                     
  #   dt <- data.table(num1 = c(1, NA, 3),                                                                                                                       
  #                    num2 = c(NA, NA, 4),                                                                                                                      
  #                    char1 = rep("a", 3))                                                                                                                      
  #   SetNAsToMean(dt, c("num1", "num2"))                                                                                                                        
  #   # Alternatively, set all numeric columns                                                                                                                    
  #   numerics <- which(lapply(dt, class) == "numeric")                                                                                                           
  #   SetNAsToMean(dt, numerics)
  require(data.table)
  for (var in vars) {                                                                                                                                            
    set(dt, which(is.na(dt[[var]])), var, mean(dt[[var]], na.rm=T))                                                                                              
  }                                                                                                                                                              
}           
person Max Ghenis    schedule 29.03.2014

Вас бы это удовлетворило?

for (j in 1:length(dataset[1,]))
    {

        if (is.numeric(dataset[,j]))
        {
            for(k in 1:length(dataset[,1]))
            {
                if(is.na(dataset[k,j]))
                {
                    dataset[k,j] <- mean(dataset[,j],na.rm=T)
                }
            }
        }
    }
person Vincent    schedule 25.06.2013