r plot charts google-visualization googlevis

Cómo dividir la marca de tiempo en R para Googlevis para que no se solapen



plot charts (1)

Entonces, los datos de marca de tiempo que estamos recopilando tienen 19 dígitos. La primera forma en que lo ejecutamos, obtenemos estas superposiciones que no deberían estar allí. Estaba tratando de ignorar el primer décimo dígito y probar el resto, pero me sale un error. ¿Cómo puedo mostrarlo de una manera que no se superpone, y también solo contiene la duración en minutos, segundos, milisegundos o más? porque todos estos experimentos ocurren casi en la misma hora y fecha, así que no quiero mostrar datos redundantes.

library(''googleVis'') dd <- read.csv("output_2015-08-05-17-07-12_gaze.txt", header = TRUE, sep = ",",colClasses = c(''character'',''character'')) dd <- within(dd, { end <- as.POSIXct(as.numeric(substr(rosbagTimestamp, 11, 14)) / 1e9, origin = ''1970-01-01'') start <- as.POSIXct(as.numeric(substr(rosbagTimestamp, 14, 19)) / 1e9, origin = ''1970-01-01'') rosbagTimestamp <- NULL }) ## sum the times by group dd1 <- aggregate(. ~ data, data = dd, sum) dd1 <- within(dd1, { start <- as.POSIXct(start, origin = ''1970-01-01'') end <- as.POSIXct(end, origin = ''1970-01-01'') }) plot(gvisTimeline(dd1, rowlabel = ''data'', barlabel = ''data'', start = ''start'', end = ''end'', options=list(width="600px", height="800px")))

También el que muestra la hora y se superpone es así:

dd <- read.csv("output_2015-08-05-17-07-12_gaze.txt", header = TRUE, sep = ",",colClasses = c(''character'',''character'')) dd <- within(dd, { end <- as.POSIXct(as.numeric(substr(rosbagTimestamp, 1, 10)) / 1e9, origin = ''1970-01-01'') start <- as.POSIXct(as.numeric(substr(rosbagTimestamp, 11, 19)) / 1e9, origin = ''1970-01-01'') rosbagTimestamp <- NULL }) ## sum the times by group dd1 <- aggregate(. ~ data, data = dd, sum) dd1 <- within(dd1, { start <- as.POSIXct(start, origin = ''1970-01-01'') end <- as.POSIXct(end, origin = ''1970-01-01'') }) plot(gvisTimeline(dd1, rowlabel = ''data'', barlabel = ''data'', start = ''start'', end = ''end'', options=list(width="600px", height="800px")))

Aquí está el enlace al conjunto de datos .


No estoy seguro de lo que quiere decir con "superposición". Los datos parecen consistir en un conjunto monótonamente creciente de marcas de tiempo, donde cada marca de tiempo está etiquetada con algún tipo de categoría (nombres de frutas, al menos en este ejemplo de datos). Las categorías no son completamente contiguas (aunque tienden a estar en tramos cortos), así que tal vez eso es a lo que te refieres cuando dices "superposición". Pero esa es solo la naturaleza de los datos; no hay forma de "dividir" las marcas de tiempo de tal manera que cambie su relación entre sí. Y no puede elegir ignorar algunos dígitos de la marca de tiempo; eso haría que los datos carezcan de significado.

Para aclarar, las marcas de tiempo son 19 dígitos que representan números en la base 10. Los números se refieren a nanosegundos transcurridos desde 1970-01-01 UTC. Esta es una forma común de representar las marcas de tiempo (junto con los segundos desde 1970-01-01 UTC, milisegundos desde 1970-01-01 UTC y los días desde 1970-01-01 UTC).

Por lo tanto, puede derivar POSIXct representaciones de las marcas de tiempo forzando al doble vía as.double() (también podría usar as.numeric() ), dividiendo por 1e9, y luego usando la función de coerción como as.POSIXct() con origin=''1970-01-01'' , que trata los valores dobles como segundos desde 1970-01-01 UTC. (Parece que estás haciendo algo parecido a eso en tu código, pero no funciona debido a los problemas mencionados anteriormente).

Ahora, realmente pierde un poco de precisión al hacer esto, porque el significado del tipo doble omnipresente tiene 53 dígitos binarios (52 codificados explícitamente en los bits del valor y 1 implícito (un 1 bit adelantado); vea .Machine$double.digits ), que resulta en alrededor de 15 bases de 10 dígitos. Eso no es suficiente para conservar los 19 dígitos base 10 en las marcas de tiempo entrantes. Pero como probablemente no te importan los microsegundos y nanosegundos, podemos ignorar eso aquí.

Recomiendo data.table para todo el trabajo de tabla, ya que es más elegante, potente y eficiente que el tipo base R data.frame. A continuación, le mostramos cómo puede ingresar y procesar los datos usando data.table:

## prepare data library(data.table); dd <- as.data.table(read.csv(''~/Desktop/gazedata.csv.txt'',header=T,sep='','',colClasses=c(''character'',''character''))); dd[,`:=`(dt=as.POSIXct(as.double(rosbagTimestamp)/1e9,origin=''1970-01-01''),rosbagTimestamp=NULL)]; dd2 <- dd[,.(start=min(dt),end=max(dt)),data][order(data)]; dd2; ## data start end ## 1: 0 2015-08-05 18:07:14 2015-08-05 18:10:49 ## 2: apple 2015-08-05 18:08:13 2015-08-05 18:10:48 ## 3: avocado 2015-08-05 18:07:13 2015-08-05 18:10:01 ## 4: banana 2015-08-05 18:07:16 2015-08-05 18:10:48 ## 5: blueberry 2015-08-05 18:07:14 2015-08-05 18:10:42 ## 6: kiwi 2015-08-05 18:07:27 2015-08-05 18:10:41 ## 7: mango 2015-08-05 18:07:17 2015-08-05 18:10:40 ## 8: orange 2015-08-05 18:07:27 2015-08-05 18:10:30 ## 9: papaya 2015-08-05 18:07:12 2015-08-05 18:09:16 ## 10: peach 2015-08-05 18:08:15 2015-08-05 18:10:45 ## 11: pear 2015-08-05 18:07:20 2015-08-05 18:07:48 ## 12: strawberry 2015-08-05 18:07:14 2015-08-05 18:10:20 ## 13: watermelon 2015-08-05 18:07:30 2015-08-05 18:09:29

Ahora, con respecto al trazado, es posible que no desee seguir esta ruta, pero dado que los datos con los que está trabajando son datos primitivos (es decir, marcas de tiempo POSIXct y cadenas de caracteres), puede trazarlo usted mismo utilizando funciones gráficas de base R. Generalmente prefiero esto en lugar de utilizar una función de trazado de gvisTimeline() como gvisTimeline() , ya que permite un mayor control sobre los elementos de trazado. Pero también requiere un amplio conocimiento del marco de gráficos base y generalmente requerirá más esfuerzo y cuidado al escribir el código de trazado.

Aquí hay una demostración de cómo producir una trama que se parece a tu captura de pantalla:

## helper functions trunc <- function(x,...) UseMethod(''trunc''); trunc.default <- function(x,...) base::trunc(x,...); trunc.POSIXt <- function(x,unit=''sec'',num=1) { u <- sub(perl=T,''(?<=.)s$'','''',unit); base::trunc.POSIXt(x,u) - as.integer(format(x,c(sec=''%S'',second=''%S'',min=''%M'',minute=''%M'',hour=''%H'',day=''%d'')[u]))%%num*unname(c(sec=1,second=1,min=60,minute=60,hour=3600,day=86400)[u]); }; ceiling <- function(x,...) UseMethod(''ceiling''); ceiling.default <- function(x,...) base::ceiling(x); ceiling.POSIXt <- function(x,unit=''sec'',num=1) { u <- sub(perl=T,''(?<=.)s$'','''',unit); trunc.POSIXt(x-.Machine$double.base^(as.integer(log2(as.double(x)))-.Machine$double.digits+1L),unit,num) + num*unname(c(sec=1,second=1,min=60,minute=60,hour=3600,day=86400)[u]); }; ## define plot parameters xtick.first <- trunc(min(dd2$start),''hour''); xtick.last <- ceiling(max(dd2$end),''hour''); xtick <- seq(xtick.first,xtick.last,''10 min''); xtick.range <- as.double(difftime(xtick.last,xtick.first,unit=''secs'')); xmin <- xtick.first - xtick.range*20/100; xmax <- xtick.last + xtick.range*5/100; xlim <- c(xmin,xmax); ydiv <- 0:nrow(dd2); ytick <- nrow(dd2):1-0.5; ymin <- ydiv[1]; ymax <- ydiv[length(ydiv)]; ylim <- c(ymin,ymax); line.grey <- ''grey''; bg.grey <- ''#dddddd''; bg.white <- ''white''; ## plot par(xaxs=''i'',yaxs=''i'',mar=c(5,1,1,1)); plot(NA,xlim=xlim,ylim=ylim,axes=F,ann=F); rect(xmin,(ymax-1):ymin,xmax,ymax:(ymin+1),col=c(bg.white,bg.grey),border=NA); with(expand.grid(y=ytick,x=xtick),segments(x,y+0.5,x,y-0.5,col=rep(c(line.grey,bg.white),len=length(ytick)))); abline(h=ydiv,lwd=2,col=line.grey); abline(v=xlim,lwd=2,col=line.grey); barheight <- 0.75; with(dd2,rect(start,ytick-barheight/2,end,ytick+barheight/2,col=rainbow(nrow(dd2)),border=NA)); xtick.ishour <- c(T,format(xtick[-1],''%M'')==''00''); text(xtick,0,pos=1,ifelse(xtick.ishour,format(xtick,''%H:%M''),format(xtick,'':%M'')),font=ifelse(xtick.ishour,2,1),xpd=NA); text(xtick.first,ytick,pos=2,dd2[,data]); text(dd2[,end],ytick,pos=4,dd2[,data]);