2012-02-24 8 views
6

Por ejemplo, digamos que usted tiene ~ 10 años de datos de 1 min para el volumen del instrumento X de la siguiente manera (en formato xts) de 9:30 am a 4:30 pm:¿Cuál es el mejor método para agrupar las cifras de volumen intradía de una serie de precios de acciones usando XTS/ZOO, etc. en R?

Date.Time    Volume   
    2001-01-01 09:30:00  1200 
    2001-01-01 09:31:00  1110 
    2001-01-01 09:32:00  1303 

Durante todo el camino a través a:

2010-12-20 16:28:00  3200 
    2010-12-20 16:29:00  4210 
    2010-12-20 16:30:00  8303 

me gustaría:

  • obtener el volumen promedio en cada minuto durante toda la serie (es decir, el volumen promedio de los 10 años, a las 9:30, nueve y treinta y uno, 09:32 ... 16:28, 16:29, 16:30)

¿Cómo debería ir mejor sobre: ​​

  • agregación de los datos en segmentos de un minuto
  • Obtención de la media de esos cubos
  • ¿Volver a reconectar esos cubos "promedio" a una única serie temporal xts/zoo?

que he tenido un buen empuje alrededor con aggregate, sapply, period.apply funciones, etc, pero no se puede parecer a "bin" los datos correctamente.

Es bastante fácil resolver esto con un ciclo, pero muy lento. Prefiero evitar una solución programática y utilizar una función que aproveche la arquitectura C++ (es decir, la solución basada en xts)

¿Alguien puede ofrecer algún consejo/una solución?

Muchas gracias de antemano.

Respuesta

5

En primer lugar vamos a crear algunos datos de prueba:

library(xts) # also pulls in zoo 
library(timeDate) 
library(chron) # includes times class 

# test data 
x <- xts(1:3, timeDate(c("2001-01-01 09:30:00", "2001-01-01 09:31:00", 
    "2001-01-02 09:30:00"))) 

1) aggregate.zoo. Ahora trata de la conversión a times clase y la agregación usando este de una sola línea:

aggregate(as.zoo(x), times(format(time(x), "%H:%M:%S")), mean) 

1a) aggregate.zoo (variación). o esta variación que convierte la serie agregado más corto para times para evitar tener que hacerlo en la serie original ya:

ag <- aggregate(as.zoo(x), format(time(x), "%H:%M:%S"), mean) 
zoo(coredata(ag), times(time(ag))) 

2) tapply.Una alternativa sería tapply que es probable más rápido:

ta <- tapply(coredata(x), format(time(x), "%H:%M:%S"), mean) 
zoo(unname(ta), times(names(ta))) 

EDIT: simplificada (1) y se añadió (1a) y (2)

+0

Excelente. Esto es muy, muy bueno. –

+0

Gracias por publicar esta solución muy elegante. –

3

Aquí es una solución con ddply, pero se puede utilizar probablemente también sqldf, tapply, aggregate, by, etc.

# Sample data 
minutes <- 10 * 60 
days <- 250 * 10 
d <- seq.POSIXt( 
    ISOdatetime(2011,01,01,09,00,00, "UTC"), 
    by="1 min", length=minutes 
) 
d <- outer(d, (1:days) * 24*3600, `+`) 
d <- sort(d) 
library(xts) 
d <- xts(round(100*rlnorm(length(d))), d) 

# Aggregate 
library(plyr) 
d <- data.frame( 
    minute=format(index(d), "%H:%M"), 
    value=coredata(d) 
) 
d <- ddply( 
    d, "minute", 
    summarize, 
    value=mean(value, na.rm=TRUE) 
) 

# Convert to zoo or xts 
zoo(x=d$value, order.by=d$minute) # The index does not have to be a date or time 
xts(x=d$value, order.by=as.POSIXct(sprintf("2012-01-01 %s:00",d$minute), "%Y-%m-%d %H:%M:%S")) 
+0

Gracias por esto. Tenía 'sqldf' en mente, pero parecía ser un" truco "para lo que estaba tratando de lograr. Ahora a su código. Esto está funcionando bien hasta el uso de 'ddply' (es decir, he construido el marco de datos con minutos y valor (estructurado como chr y num respectivamente). Sin embargo, simplemente devuelve" NA "para el (medio) valor de la columna ¿Alguna idea? –

+0

Lo siento, debería decir que el código de su modelo funciona bien en todas partes. Sin embargo, no está trabajando en mis datos una llamada 'str()' a los datos de volumen devuelve: num [ 1: 976638, 1] 46 32 24 7 34 27 9 18 2 24 ... - attr (*, "dimnames") = Lista de 2 .. $: NULL .. $: chr "Volumen" /// y el 'índice' de mis datos: Clase formal 'timeDate' [paquete" fCalendar "] con 3 s lotes .. @ Data: POSIXct [1: 976638], formato: "2001-07-02 09:51:00" "2001-07-02 09:52:00" "2001-07-02 09:53: 00 "" 2001-07-02 09:54:00 "... .. @ formato: chr"% Y-% m-% d% H:% M:% S " –

+0

El error que se devuelve en mi adaptación es: En mean.default (valor, na.rm = TRUE): argumento no es numérico o lógico: return NA –

Cuestiones relacionadas