studio - estructura visual de un data.frame: ubicaciones de NA y mucho más
plot en r (4)
Quiero representar la estructura de un marco de datos (o matriz, o tabla de datos) en una sola gráfica con codificación por colores. Supongo que podría ser muy útil para muchas personas que manejan varios tipos de datos, para visualizarlos de un vistazo.
Quizás alguien ya haya desarrollado un paquete para hacerlo, pero no pude encontrar uno (solo esto ). Así que aquí está una maqueta aproximada de mi "visión", una especie de mapa de calor, que se muestra en los códigos de color:
- las ubicaciones de NA,
- la clase de variables (factores (¿cuántos niveles?), numéricos (con gradiente de color, ceros, valores atípicos ...), cadenas)
- dimensiones
- etc .....
Hasta ahora, acabo de escribir una función para trazar las ubicaciones de NA que dice así:
ggSTR = 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")
pc <- round(sum(is.na(DF))/prod(dim(DF))*100, 2) # % NA
print(paste("percentage of NA data: ", pc))
return(g)
}
Toma cualquier data.frame en la entrada y devuelve esta imagen:
Es un desafío demasiado grande para mí lograr la primera imagen.
¿Has encontrado el servicio de huellas dactilares CSV ? Crea una imagen similar, aunque no con todos los detalles que ha descrito anteriormente, y no está basada en R. Hay una versión R de una idea similar en R-ohjelmointi.org , pero el texto está en finlandés. La función principal es csvSormenjalki()
. Tal vez eso podría adaptarse aún más para cumplir con su visión completa?
Sé que hay un paquete que muestra valores perdidos fácilmente, pero mi google-fu no es muy bueno en este momento. Encontré, sin embargo, una función llamada tableplot
, que le dará una gran visión general de su marco de datos. No sé si mostrará o no los datos que faltan.
Aquí está el enlace:
http://www.ancienteco.com/2012/05/quickly-visualize-your-whole-dataset.html
eventualmente se me ocurre una secuencia de comandos para trazar la mayoría de las especificaciones. Lo presento aquí, algunos podrían estar interesados, ¡aunque la sintaxis está lejos de ser "elegante"!
Tenga en cuenta que la función principal ''colstr'' tiene 3 argumentos: - una entrada (df o matriz o incluso un solo vector) - un número de fila máximo para trazar - una opción para exportar a png en el directorio de trabajo.
la salida da, por ejemplo:
# PACKAGES
require(ggplot2)
require(RColorBrewer)
require(reshape2)
# Test if an object is empty (data.frame, matrix, vector)
is.empty = function (input) {
df <- data.frame(input)
(is.null(df) || nrow(df) == 0 || ncol(df) == 0 || NROW(df) == 0)
}
# min/max normalization (R->[0;1]), (all columns must be numerical)
minmax <- function(data, ...) {
.minmax = function(x) (x-min(x, ...))/(max(x, ...)-min(x, ...))
# find constant columns, replaces with O.5:
constant <- which(apply(data, 2, function(u) {min(u, ...)==max(u, ...)}))
if(is.vector(data)) {
res <- .minmax(data)
} else {
res <- apply(data, 2, .minmax)
}
res[, constant] <- 0.5
return(res)
}
# MAIN function
colstr = function(input, size.max=500, export=FALSE) {
data <- as.data.frame(input)
if (NCOL(data) == 1) {
data <- cbind(data, data)
message("warning: input data is a vector")
}
miror <- data # miror data.frame will contain a coulour coding for all cells
wholeNA <- which(sapply(miror, function(x) all(is.na(x))))
whole0 <- which(sapply(miror, function(x) all(x==0)))
numeric <- which(sapply(data, is.numeric))
character <- which(sapply(data, is.character))
factor <- which(sapply(data, is.factor))
# characters to code
miror[character] <- 12
# factor coding
miror[factor] <- 11
# min/max normalization, coerce it into 9 classes.
if (!is.empty(numeric)) {miror[numeric] <- minmax(miror[numeric], na.rm=T)}
miror[numeric] <- data.frame(lapply(miror[numeric], function(x) cut(x, breaks=9, labels=1:9))) # 9 classes numériques
miror <- data.frame(lapply(miror, as.numeric))
# Na coding
miror[is.na(data)] <- 10
miror[whole0] <- 13
# color palette vector
mypalette <- c(brewer.pal(n=9, name="Blues"), "red", "green", "purple", "grey")
colnames <- c(paste0((1:9)*10, "%"), "NA", "factor (lvls)", "character", "zero")
# subset if too large
couper <- nrow(miror) > size.max
if (couper) miror <- head(miror, size.max)
# plot
g <- ggplot(data=melt(as.matrix(unname(miror)))) +
geom_tile(aes(x=Var2, y=Var1, fill=factor(value, levels=1:13))) +
scale_fill_manual("legend", values=mypalette, labels=colnames, drop=FALSE) +
ggtitle(paste("graphical structure of", deparse(substitute(input)), paste(dim(input), collapse="X"), ifelse(couper, "(truncated)", ""))) +
xlab("columns of the dataframe") + ylab("rows of the dataframe") +
geom_point(data=data.frame(x=0, y=1:NROW(input)), aes(x,y), alpha=1-all(row.names(input)==seq(1, NROW(input)))) +
scale_y_reverse(limits=c(min(size.max, nrow(miror)), 0))
if (!is.empty(factor)) {
g <- g + geom_text(data=data.frame(x = factor,
y = round(runif(length(factor), 2, NROW(miror)-2)),
label = paste0("(", sapply(data[factor], function(x) length(levels(x))), ")")),
aes(x=x, y=y, label=label))
}
if (export) {png("colstr_output.png"); print(g); dev.off()}
return(g)
}
Puede probar el paquete visdat
( https://github.com/ropensci/visdat ), que muestra los valores de NA y los tipos de datos en la trama
install.packages("visdat")
library(visdat)
vis_dat(airquality)