¿Qué es un método eficaz para la separación y la agregación de intervalos de filas con sellos de tiempo en una trama de datos?

StackOverflow https://stackoverflow.com/questions/2441136

  •  19-09-2019
  •  | 
  •  

Pregunta

A partir de una trama de datos con filas con sellos de tiempo (resultados strptime), ¿cuál es el mejor método para la agregación de estadísticas para intervalos?

Intervalos podrían ser una hora, un día, etc.

Hay la función aggregate, pero eso no ayuda con la asignación de cada fila para un intervalo. Estoy pensando en añadir una columna a la trama de datos que denota intervalo y el uso que con aggregate, pero si hay una mejor solución que sería muy bueno escuchar a él.

Gracias por cualquier punteros!


Ejemplo de datos

cinco filas con marcas de tiempo divididos en intervalos de 15 minutos a partir de 03:00.

Intervalo 1

  • "2010-01-13 03:02:38 UTC"
  • "2010-01-13 03:08:14 UTC"
  • "2010-01-13 03:14:52 UTC"

Intervalo 2

  • "2010-01-13 03:20:42 UTC"
  • "2010-01-13 03:22:19 UTC"

Conclusión

Uso de un paquete de serie de tiempo tal como xts debe ser la solución; Sin embargo yo no tenía éxito con ellos y aliento hasta el uso cut. Como I actualmente sólo necesita para trazar histogramas, con filas agrupadas por intervalo, esto era suficiente.

cut se utiliza le gusta por lo que:

interv <- function(x, start, period, num.intervals) {
  return(cut(x, as.POSIXlt(start)+0:num.intervals*period))
}
¿Fue útil?

Solución

Las funciones estándar para dividir vectores son cut y findInterval:

v <- as.POSIXct(c(
  "2010-01-13 03:02:38 UTC",
  "2010-01-13 03:08:14 UTC",
  "2010-01-13 03:14:52 UTC",
  "2010-01-13 03:20:42 UTC",
  "2010-01-13 03:22:19 UTC"
))

# Your function return list:
interv(v, as.POSIXlt("2010-01-13 03:00:00 UTC"), 900)
# [[1]]
# [1] "2010-01-13 03:00:00"
# [[2]]
# [1] "2010-01-13 03:00:00"
# [[3]]
# [1] "2010-01-13 03:00:00"
# [[4]]
# [1] "2010-01-13 03:15:00 CET"
# [[5]]
# [1] "2010-01-13 03:15:00 CET"

# cut returns factor, you must provide proper breaks:
cut(v, as.POSIXlt("2010-01-13 03:00:00 UTC")+0:2*900)
# [1] 2010-01-13 03:00:00 2010-01-13 03:00:00 2010-01-13 03:00:00
# [4] 2010-01-13 03:15:00 2010-01-13 03:15:00
# Levels: 2010-01-13 03:00:00 2010-01-13 03:15:00

# findInterval returns vector of interval id (breaks like in cut)
findInterval(v, as.POSIXlt("2010-01-13 03:00:00 UTC")+0:2*900)
# [1] 1 1 1 2 2

Para el registro: cut tiene un método para el tipo POSIXt, pero por desgracia no hay manera de proporcionar argumento start, el efecto es:

cut(v,"15 min")
# [1] 2010-01-13 03:02:00 2010-01-13 03:02:00 2010-01-13 03:02:00
# [4] 2010-01-13 03:17:00 2010-01-13 03:17:00
# Levels: 2010-01-13 03:02:00 2010-01-13 03:17:00

Como se puede ver se inicia en 3:02:00. Se podría meterse con etiquetas de factor de potencia (convertir etiquetas en cuando, redondo de alguna manera y convertir de nuevo a carácter).

Otros consejos

Utilizar un series temporales paquete. El paquete XTS tiene funciones específicamente diseñado para hacer eso. O mirar las funciones de agregación y rollapply en el paquete zoológico.

El libro electrónico rmetrics tiene una discusión útil, incluyendo una comparación de rendimiento de los distintos paquetes: https://www.rmetrics.org/files/freepdf/TimeSeriesFAQ.pdf

Editar : Mira mi respuesta a esta pregunta . Básicamente lo que necesita para truncar cada marca de tiempo en un intervalo de tiempo específico y luego hacer la agregación utilizando esas nuevas marcas de tiempo truncados como su vector agrupación.

Esta es una pregunta interesante; con la proliferación de los diversos paquetes y métodos de series de tiempo, no debe ser un enfoque para binning series de tiempo irregular que no sea por la fuerza bruta que la OP sugiere. Esta es una manera de "alto nivel" para obtener los intervalos que luego se pueden utilizar para aggregate et al, usando una versión de cut definido para objetos chron.

require(chron)
require(timeSeries)

my.times <- "
2010-01-13 03:02:38 UTC
2010-01-13 03:08:14 UTC
2010-01-13 03:14:52 UTC
2010-01-13 03:20:42 UTC
2010-01-13 03:22:19 UTC
"

time.df <- read.delim(textConnection(my.times),header=FALSE,sep="\n",strip.white=FALSE)
time.seq <- seq(trunc(timeDate(time.df[1,1]),units="hours"),by=15*60,length=nrow(time.df))
intervals <- as.numeric(cut(as.chron(as.character(time.df$V1)),breaks=as.chron(as.character(time.seq))))

obtener

intervals  
[1] 1 1 1 2 2

que ahora se puede añadir a la trama de datos y agregados.

Las acrobacias coersion anteriores (de carácter a carácter a TimeDate de Chron) es un poco desafortunado, por lo que si hay soluciones más limpias para hurgar en la basura de datos de tiempo irregulares utilizando XTS o cualquiera de los otros paquetes de series de tiempo, me gustaría oír hablar ellos también! ..

También tengo curiosidad de saber cuál sería el método más eficiente para hurgar en la basura grande de alta frecuencia de series de tiempo irregulares, por ejemplo, la creación de barras de volumen 1 minuto sobre datos de garrapatas de una población muy líquido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top