varias superponer studio lineas graficos graficas filas contar r plot large-data-volumes

studio - superponer graficas en r



Trazado de conjuntos de datos muy grandes en R (7)

¿Cómo puedo trazar un conjunto de datos muy grande en R?

Me gustaría utilizar un diagrama de caja, violín o similar. Todos los datos no pueden caber en la memoria. ¿Puedo leer incrementalmente y calcular los resúmenes necesarios para hacer estos gráficos? ¿Si es así, cómo?


El problema es que no puede cargar todos los datos en la memoria. Entonces podría hacer un muestreo de los datos, como lo indicó anteriormente @Marek. En conjuntos de datos tan grandes, obtienes esencialmente los mismos resultados, incluso si solo tomas el 1% de los datos. Para la trama de violín, esto le dará una estimación decente de la densidad. El cálculo progresivo de los cuantiles es imposible, pero esto debería dar una aproximación muy decente. Es esencialmente lo mismo que el "método aleatorio" descrito en el enlace @aix dio.

Si no puede subconjuntar la fecha fuera de R, puede hacerlo usando conexiones en combinación con sample() . La siguiente función es la que uso para muestrear los datos de un marco de datos en formato de texto cuando se está haciendo demasiado grande. Si juegas un poco con la conexión, puedes convertirla fácilmente en una conexión de socket u otra para leerla desde un servidor, una base de datos, lo que sea. Solo asegúrate de abrir la conexión en el modo correcto.

Bien, tome un archivo .csv simple, luego la siguiente función muestrea una fracción p de los datos:

sample.df <- function(f,n=10000,split=",",p=0.1){ con <- file(f,open="rt",) on.exit(close(con,type="rt")) y <- data.frame() #read header x <- character(0) while(length(x)==0){ x <- strsplit(readLines(con,n=1),split)[[1]] } Names <- x #read and process data repeat{ x <- tryCatch(read.table(con,nrows=n,sep=split),error = function(e) NULL ) if(is.null(x)) {break} names(x) <- Names nn <- nrow(x) id <- sample(1:nn,round(nn*p)) y <- rbind(y,x[id,]) } rownames(y) <- NULL return(y) }

Un ejemplo del uso:

#Make a file Df <- data.frame( X1=1:10000, X2=1:10000, X3=rep(letters[1:10],1000) ) write.csv(Df,file="test.txt",row.names=F,quote=F) # n is number of lines to be read at once, p is the fraction to sample DF2 <- sample.df("test.txt",n=1000,p=0.2) str(DF2) #clean up unlink("test.txt")


Este es un problema interesante.

Los diagramas de caja requieren cuantiles. Calcular cuantiles en conjuntos de datos muy grandes es complicado.

La solución más simple que puede o no funcionar en su caso es reducir la resolución de los datos primero y generar gráficos de la muestra. En otras palabras, lea un montón de registros a la vez y conserve un subconjunto de ellos en la memoria (eligiendo de forma determinista o aleatoria). Al final, genere gráficos en función de los datos que se han conservado en la memoria. De nuevo, si esto es viable o no depende en gran medida de las propiedades de sus datos.

Alternativamente, existen algoritmos que pueden calcular de manera económica y aproximada los cuantiles de manera "en línea", lo que significa que se presentan con una observación a la vez, y cada observación se muestra exactamente una vez. Si bien tengo cierta experiencia limitada con dichos algoritmos, no he visto ninguna implementación de R fácilmente disponible.

El siguiente documento presenta una breve descripción general de algunos algoritmos relevantes: Quantiles on Streams .


Podría hacer trazados a partir de muestras manejables de sus datos. Por ejemplo, si usa solo el 10% de las filas elegidas al azar, el diagrama de caja en esta muestra no debe diferir del diagrama de caja de todos los datos.

Si sus datos están en alguna base de datos allí, puede crear una bandera aleatoria (ya que sé que casi todos los motores de bases de datos tienen algún tipo de generador de números aleatorios).

Lo segundo es qué tan grande es su conjunto de datos? Para boxplot necesita dos columnas: variable de valor y variable de grupo. Este ejemplo:

N <- 1e6 x <- rnorm(N) b <- sapply(1:100, function(i) paste(sample(letters,40,TRUE),collapse="")) g <- factor(sample(b,N,TRUE)) boxplot(x~g)

necesita 100MB de RAM Si N=1e7 entonces usa <1GB de RAM (que aún es manejable para la máquina moderna).



También debería consultar los paquetes RSQLite, SQLiteDF, RODBC y biglm. Para grandes conjuntos de datos puede ser útil almacenar los datos en una base de datos y extraer solo fragmentos en R. Las bases de datos también pueden ordenarlo y luego calcular los cuantiles en los datos ordenados es mucho más simple (entonces simplemente use los cuantiles para hacer los gráficos) .

También existe el paquete hexbin (bioconductor) para hacer equivalentes de diagramas de dispersión con conjuntos de datos muy grandes (probablemente todavía desee utilizar una muestra de los datos, pero funcione con una muestra grande).


Todo lo que necesita para un diagrama de caja son los cuantiles, los extremos "bigote" y los valores atípicos (si se muestran), que son todos fácilmente calculados previamente. Eche un vistazo a la función boxplot.stats .


Como complemento de mi comentario a la respuesta de Dmitri , una función para calcular cuantiles utilizando ff big-data handling package:

ffquantile<-function(ffv,qs=c(0,0.25,0.5,0.75,1),...){ stopifnot(all(qs<=1 & qs>=0)) ffsort(ffv,...)->ffvs j<-(qs*(length(ffv)-1))+1 jf<-floor(j);ceiling(j)->jc rowSums(matrix(ffvs[c(jf,jc)],length(qs),2))/2 }

Este es un algoritmo exacto, por lo que utiliza la clasificación, por lo que puede llevar mucho tiempo.