R: Улучшить производительность для функции обработки NA

У меня есть функция, которую я использую для обработки NA в R, но ее запуск на большом наборе данных может занять некоторое время. Мне было любопытно, есть ли у кого-нибудь предложения по улучшению производительности. Общий смысл этого заключается в том, что если столбец имеет числовое значение NA, оно преобразуется в -1000 и добавляется столбец флагов, а если это фактор NA, вызывается функция addNA().

Вот набор данных:

df1 <- data.frame(id = 1:20, target = round(runif(20),0), col1 = runif(20), col2 = runif(20), col3 = factor(letters[1:20]))
set.seed(456)
df1[sample(1:nrow(df1),5),'col1'] <- NA
df1[sample(1:nrow(df1),5),'col2'] <- NA
df1[sample(1:nrow(df1),5),'col3'] <- NA

Вот функция и использование:

varsToUse <- c('col1','col2','col3')


fixNa <- function(x, varList){

        for(i in 1:length(varList)){  # i = 1
          colNam1 <- varList[i]
          if(class(x[,colNam1]) %in% c('numeric','integer')){
            newColName <- paste(colNam1,'_isNA',sep='')
            x[,newColName] <- ifelse(is.na(x[,colNam1]), 1, 0)
            x[,colNam1] <- ifelse(is.na(x[,colNam1]), -1000, x[,colNam1])
            varList <- c(varList, newColName)
            print(i);flush.console()
          }

          if(class(x[,colNam1]) %in% c('factor')){
            x[,colNam1] <- addNA(x[,colNam1])
          }
        }
    return(x)
}

df1 <- fixNa(df1, varsToUse)

Какие-либо предложения?


person screechOwl    schedule 17.11.2013    source источник


Ответы (1)


Это быстрее:

fixNa2 <- function(x, varlist){
   for(i in seq_along(varlist)){  # i = 1
     if(class(x[,varlist[i]]) %in% c('numeric','integer')){
       newColName <- paste(varlist[i],'_isNA',sep='')
       x[,newColName] <- as.numeric(is.na(x[,varlist[i]]))
       x[is.na(x[,varlist[i]]),varlist[i]] <- -1000
     }
     else if(class(x[,varlist[i]]) %in% c('factor')){
       x[,varlist[i]] <- addNA(x[,varlist[i]])
     }
   }
   return(x)
}

Он пропускает печать, конструкции ifelse и некоторые другие второстепенные вещи.

Сравнительный анализ:

> library(microbenchmark)
> microbenchmark(fixNa(df1, varsToUse),fixNa2(df1, varsToUse))
Unit: microseconds
                   expr      min        lq   median        uq       max neval
  fixNa(df1, varsToUse) 8505.560 9893.6455 9990.829 10135.546 12557.622   100
 fixNa2(df1, varsToUse)  909.868  970.8715 1013.594  1062.474  4490.446   100
person Thomas    schedule 17.11.2013