Si les performances sont une priorité, utilisez data.table
et na.omit()
avec param facultatif cols=
.
na.omit.data.table
est le plus rapide de mon benchmark (voir ci-dessous), que ce soit pour toutes les colonnes ou pour certaines colonnes (OP question 2).
Si vous ne voulez pas utiliser data.table
, utilisez complete.cases()
.
Sur une vanille data.frame
, complete.cases
est plus rapide que na.omit()
ou dplyr::drop_na()
. Notez que na.omit.data.frame
cela ne prend pas en charge cols=
.
Résultat de référence
Voici une comparaison des méthodes de base (bleu), dplyr
(rose) et data.table
(jaune) pour supprimer toutes ou sélectionner les observations manquantes, sur un ensemble de données théorique de 1 million d'observations de 20 variables numériques avec une probabilité indépendante de 5% d'être manquant, et un sous-ensemble de 4 variables pour la partie 2.
Vos résultats peuvent varier en fonction de la longueur, de la largeur et de la rareté de votre ensemble de données particulier.
Notez l'échelle logarithmique sur l'axe y.
Script de référence
#------- Adjust these assumptions for your own use case ------------
row_size <- 1e6L
col_size <- 20 # not including ID column
p_missing <- 0.05 # likelihood of missing observation (except ID col)
col_subset <- 18:21 # second part of question: filter on select columns
#------- System info for benchmark ----------------------------------
R.version # R version 3.4.3 (2017-11-30), platform = x86_64-w64-mingw32
library(data.table); packageVersion('data.table') # 1.10.4.3
library(dplyr); packageVersion('dplyr') # 0.7.4
library(tidyr); packageVersion('tidyr') # 0.8.0
library(microbenchmark)
#------- Example dataset using above assumptions --------------------
fakeData <- function(m, n, p){
set.seed(123)
m <- matrix(runif(m*n), nrow=m, ncol=n)
m[m<p] <- NA
return(m)
}
df <- cbind( data.frame(id = paste0('ID',seq(row_size)),
stringsAsFactors = FALSE),
data.frame(fakeData(row_size, col_size, p_missing) )
)
dt <- data.table(df)
par(las=3, mfcol=c(1,2), mar=c(22,4,1,1)+0.1)
boxplot(
microbenchmark(
df[complete.cases(df), ],
na.omit(df),
df %>% drop_na,
dt[complete.cases(dt), ],
na.omit(dt)
), xlab='',
main = 'Performance: Drop any NA observation',
col=c(rep('lightblue',2),'salmon',rep('beige',2))
)
boxplot(
microbenchmark(
df[complete.cases(df[,col_subset]), ],
#na.omit(df), # col subset not supported in na.omit.data.frame
df %>% drop_na(col_subset),
dt[complete.cases(dt[,col_subset,with=FALSE]), ],
na.omit(dt, cols=col_subset) # see ?na.omit.data.table
), xlab='',
main = 'Performance: Drop NA obs. in select cols',
col=c('lightblue','salmon',rep('beige',2))
)
final[complete.cases(final),]
?