r dataframe na missing-data

Inserte NA aleatoriamente en el marco de datos proporcionalmente



dataframe missing-data (5)

Tengo un marco de datos completo. Quiero que el 20% de los valores en el marco de datos sean reemplazados por NA para simular datos faltantes al azar.

A <- c(1:10) B <- c(11:20) C <- c(21:30) df<- data.frame(A,B,C)

¿Alguien puede sugerir una forma rápida de hacerlo?


¿Puedo sugerir una primera función (ggNAadd) diseñada para hacer esto y mejorarla con una segunda función que proporcione una distribución gráfica de los NA creados (ggNA)

Lo que es bueno es la posibilidad de ingresar una proporción de un número fijo de NA.

ggNAadd = function(data, amount, plot=F){ temp <- data amount2 <- ifelse(amount<1, round(prod(dim(data))*amount), amount) if (amount2 >= prod(dim(data))) stop("exceeded data size") for (i in 1:amount2) temp[sample.int(nrow(temp), 1), sample.int(ncol(temp), 1)] <- NA if (plot) print(ggNA(temp)) return(temp) }

Y la función de trazado:

ggNA = function(data, alpha=0.5){ require(ggplot2) DF <- data if (!is.matrix(data)) DF <- as.matrix(DF) to.plot <- cbind.data.frame(''y''=rep(1:nrow(DF), each=ncol(DF)), ''x''=as.logical(t(is.na(DF)))*rep(1:ncol(DF), nrow(DF))) size <- 20 / log( prod(dim(DF)) ) # size of point depend on size of table g <- ggplot(data=to.plot) + aes(x,y) + geom_point(size=size, color="red", alpha=alpha) + scale_y_reverse() + xlim(1,ncol(DF)) + ggtitle("location of NAs in the data frame") + xlab("columns") + ylab("lines") pc <- round(sum(is.na(DF))/prod(dim(DF))*100, 2) # % NA print(paste("percentage of NA data: ", pc)) return(g) }

Lo que da (usando ggplot2 como salida gráfica):

ggNAadd(df, amount=0.20, plot=TRUE) ## [1] "percentage of NA data: 20" ## A B c ## 1 1 11 21 ## 2 2 12 22 ## 3 3 13 23 ## 4 4 NA 24 ## ..

Por supuesto, como se mencionó anteriormente, si pregunta demasiadas NA, el porcentaje real disminuirá debido a las repeticiones.


Mismo resultado, utilizando distribución binomial:

dd=dim(df) nna=20/100 #overall df1<-df df1[matrix(rbinom(prod(dd), size=1,prob=nna)==1,nrow=dd[1])]<-NA df1


Puede eliminar la lista de data.frame y luego tomar una muestra aleatoria y luego volver a colocarla en data.frame.

df <- unlist(df) n <- length(df) * 0.15 df[sample(df, n)] <- NA as.data.frame(matrix(df, ncol=3))

Se puede hacer de muchas maneras diferentes usando sample ().


Si está de humor para usar purrr lugar de lapply , también puede hacerlo así:

> library(purrr) > df <- data.frame(A = 1:10, B = 11:20, C = 21:30) > df A B C 1 1 11 21 2 2 12 22 3 3 13 23 4 4 14 24 5 5 15 25 6 6 16 26 7 7 17 27 8 8 18 28 9 9 19 29 10 10 20 30 > map_df(df, function(x) {x[sample(c(TRUE, NA), prob = c(0.8, 0.2), size = length(x), replace = TRUE)]}) # A tibble: 10 x 3 A B C <int> <int> <int> 1 1 11 21 2 2 12 22 3 NA 13 NA 4 4 14 NA 5 5 15 25 6 6 16 26 7 7 17 27 8 8 NA 28 9 9 19 29 10 10 20 30


df <- data.frame(A = 1:10, B = 11:20, c = 21:30) head(df) ## A B c ## 1 1 11 21 ## 2 2 12 22 ## 3 3 13 23 ## 4 4 14 24 ## 5 5 15 25 ## 6 6 16 26 as.data.frame(lapply(df, function(cc) cc[ sample(c(TRUE, NA), prob = c(0.85, 0.15), size = length(cc), replace = TRUE) ])) ## A B c ## 1 1 11 21 ## 2 2 12 22 ## 3 3 13 23 ## 4 4 14 24 ## 5 5 NA 25 ## 6 6 16 26 ## 7 NA 17 27 ## 8 8 18 28 ## 9 9 19 29 ## 10 10 20 30

Es un proceso aleatorio, por lo que podría no dar el 15% cada vez.