studio programacion móviles libro google earth desarrollo curso crear como archivo aplicaciones r graph gnuplot flat-file rrdtool

programacion - ¿La forma más rápida y flexible de trazar más de 2 millones de filas de datos de archivos planos?



manual de programacion android pdf (3)

Aquí hay un código R para jugar con 8000000 números en 4 columnas de 2000000 filas:

> d=matrix(runif(8000000),ncol=4) > dim(d) [1] 2000000 4 > plot(d[1:1000,1]) > plot(d[1:1000,1],type=''l'') > plot(d[1:10000,1],type=''l'')

ahora comienza a ser un poco lento:

> plot(d[1:100000,1],type=''l'')

¿qué pasa con la correlación de dos columnas:

> cor(d[,1],d[,2]) [1] 0.001708502

- instante. ¿Transformada de Fourier?

> f=fft(d[,1])

también instantáneo. Sin embargo, no trates de trazarlo.

Vamos a trazar una versión reducida de una de las columnas:

> plot(d[seq(1,2000000,len=1000),1],type=''l'')

- instante.

Lo que realmente falta es una trama interactiva en la que puedas hacer zoom y recorrer todo el conjunto de datos.

Estoy recopilando algunos datos del sistema en un archivo plano, que tiene este formato:

YYYY-MM-DD-HH24:MI:SS DD1 DD2 DD3 DD4

Donde DD1-DD4 son cuatro elementos de datos. Un ejemplo del archivo es este:

2011-02-01-13:29:53 16 8 7 68 2011-02-01-13:29:58 13 8 6 110 2011-02-01-13:30:03 26 25 1 109 2011-02-01-13:30:08 13 12 1 31 2011-02-01-13:30:14 192 170 22 34 2011-02-01-13:30:19 16 16 0 10 2011-02-01-13:30:24 137 61 76 9 2011-02-01-13:30:29 452 167 286 42 2011-02-01-13:30:34 471 177 295 11 2011-02-01-13:30:39 502 192 309 10

El archivo tiene más de 2 millones de filas, con puntos de datos cada cinco segundos.

Necesito trazar estos datos para poder derivar el significado de ellos.

Lo que he intentado

Por el momento, probé gnuplot y rrdtool con una variedad de herramientas de Unix (awk, sed, etc.). Ambos funcionan, pero parecen requerir un gran recorte y recortar los datos cada vez que quiero verlos de otra manera. Mi intuición es que rrdtool es el camino correcto, pero en este momento estoy luchando para obtener los datos lo suficientemente rápido, en parte porque tengo que convertir mi marca de tiempo en época Unix. También tengo entendido que si decido que quiero una nueva granularidad de agregación, tengo que reconstruir el rrd (que tiene sentido para la recolección en tiempo real, pero no para cargas retrospectivas como esta). Estas cosas me hacen pensar que tal vez estoy usando la herramienta incorrecta.

La recolección de los datos en el archivo plano es fija; por ejemplo, no puedo canalizar la colección directamente en rrdtool.

Mi pregunta

Me gustaría la opinión de la gente sobre la mejor forma de hacer gráficos. Tengo estos requisitos:

  1. Debe ser lo más rápido posible para crear un gráfico (no solo renderizar, sino configurar para renderizar también)
  2. Debe ser lo más flexible posible. Necesito analizar los gráficos para determinar la mejor granularidad para los datos (5 segundos es probablemente demasiado granular).
  3. Debería ser capaz de agregar (MAX / AVG / etc) cuando sea necesario
  4. Debería ser archivos de datos repetibles y nuevos a medida que entren
  5. Lo ideal sería poder superponer DD1 vs DD2, o DD1 la semana pasada con DD1 esta semana
  6. Unix o Windows, no me importa. Prefiero * nix aunque :-)

¿Alguna sugerencia?


Aquí hay un ejemplo a lo largo de las líneas de los datos que tiene, como cargado en R, agregado, etc.

Primero, algunos datos ficticios para escribir en un archivo:

stime <- as.POSIXct("2011-01-01-00:00:00", format = "%Y-%d-%m-%H:%M:%S") ## dummy data dat <- data.frame(Timestamp = seq(from = stime, by = 5, length = 2000000), DD1 = sample(1:1000, replace = TRUE), DD2 = sample(1:1000, replace = TRUE), DD3 = sample(1:1000, replace = TRUE), DD4 = sample(1:1000, replace = TRUE)) ## write it out write.csv(dat, file = "timestamp_data.txt", row.names = FALSE)

Entonces podemos leer el tiempo en los 2 millones de filas. Para acelerar esto, le decimos a R las clases de las columnas en el archivo: "POSIXct" es una forma en R para almacenar el tipo de marcas de tiempo que tiene.

## read it in: system.time({ tsdat <- read.csv("timestamp_data.txt", header = TRUE, colClasses = c("POSIXct",rep("integer", 4))) })

que toma unos 13 segundos para leer y formatear en unix interno en mi modesta computadora portátil.

user system elapsed 13.698 5.827 19.643

La agregación se puede hacer de muchas maneras, una está usando aggregate() . Digamos agregado a la media / promedio de la hora:

## Generate some indexes that we''ll use the aggregate over tsdat <- transform(tsdat, hours = factor(strftime(tsdat$Timestamp, format = "%H")), jday = factor(strftime(tsdat$Timestamp, format = "%j"))) ## compute the mean of the 4 variables for each minute out <- aggregate(cbind(Timestamp, DD1, DD2, DD3, DD4) ~ hours + jday, data = tsdat, FUN = mean) ## convert average Timestamp to a POSIX time out <- transform(out, Timestamp = as.POSIXct(Timestamp, origin = ISOdatetime(1970,1,1,0,0,0)))

Eso (la creación de la línea) lleva ~ 16 segundos en mi computadora portátil, y da el siguiente resultado:

> head(out) hours jday Timestamp DD1 DD2 DD3 DD4 1 00 001 2010-12-31 23:29:57 500.2125 491.4333 510.7181 500.4833 2 01 001 2011-01-01 00:29:57 516.0472 506.1264 519.0931 494.2847 3 02 001 2011-01-01 01:29:57 507.5653 499.4972 498.9653 509.1389 4 03 001 2011-01-01 02:29:57 520.4111 500.8708 514.1514 491.0236 5 04 001 2011-01-01 03:29:57 498.3222 500.9139 513.3194 502.6514 6 05 001 2011-01-01 04:29:57 515.5792 497.1194 510.2431 496.8056

El trazado simple se puede lograr usando la función plot() :

plot(DD1 ~ Timestamp, data = out, type = "l")

Podemos superponer más variables a través, por ejemplo:

ylim <- with(out, range(DD1, DD2)) plot(DD1 ~ Timestamp, data = out, type = "l", ylim = ylim) lines(DD2 ~ Timestamp, data = out, type = "l", col = "red")

o a través de múltiples paneles:

layout(1:2) plot(DD1 ~ Timestamp, data = out, type = "l", col = "blue") plot(DD2 ~ Timestamp, data = out, type = "l", col = "red") layout(1)

Todo esto se ha hecho con la funcionalidad de base R. Otros han demostrado cómo los paquetes complementarios pueden facilitar el trabajo con las fechas.


Esta es una muy buena pregunta. Me alegra ver a algunas personas con R que pesan. También creo que R es la herramienta adecuada para el trabajo, aunque es mi martillo principal, así que todo me parece un clavo.

Hay un puñado de conceptos de R necesarios para abordar este desafío. Según lo veo, necesitas lo siguiente (referencias en parens):

  1. Importar datos a R. ( R Import Export Guide )
  2. Obtenga los datos en una estructura de serie de tiempo apropiada. ( XTS Vignette PDF )
  3. Un poco de trama. ( Introducción rápida a los gráficos )

Aquí está el código de ejemplo usando puntos de 2 mm. Si lo notas, no ilustraré el trazado de todos los puntos de 2 mm. Es lento y no tan informativo. Pero esto debería darte algunas ideas para comenzar. ¡Siéntete libre de volver con preguntas más específicas si decides saltar por el agujero del conejo R!

require( xts ) require( lubridate ) ## set up some example data dataLength <- 2e6 startTime <- ymd_hms("2011-02-01-13-29-53") fistFullOfSeconds <- 1:dataLength date <- startTime + fistFullOfSeconds DD1 <- rnorm( dataLength ) DD2 <- DD1 + rnorm(dataLength, 0, .1 ) DD3 <- rnorm( dataLength, 10, 2) DD4 <- rnorm( dataLength ) myXts <- xts(matrix( c( DD1, DD2, DD3, DD4 ), ncol=4 ), date) ## now all the data are in the myXts object so let''s do some ## summarizing and visualization ## grabbing just a single day from the data ## converted to data.frame to illustrate default data frame plotting oneDay <- data.frame( myXts["2011-02-02"] ) plot( oneDay )

La relación entre DD1 y DD2 salta un poco

boxplot( oneDay )

Boxplot es el pie carta de gráficos estadísticos. La trama que amas odiar. Bien podría vincular esto mientras estamos aquí.

## look at the max value of each variable every minute par(mfrow=c(4,1)) ## partitions the graph window ep <- endpoints(myXts,''minutes'') plot(period.apply(myXts[,1],INDEX=ep,FUN=max)) plot(period.apply(myXts[,2],INDEX=ep,FUN=max)) plot(period.apply(myXts[,3],INDEX=ep,FUN=max)) plot(period.apply(myXts[,4],INDEX=ep,FUN=max))

Incluso con una resolución de un minuto, no estoy seguro de que esto sea informativo. Debería ser un subconjunto