O que é um método eficiente para particionar e agregar intervalos de linhas timestamped em um quadro de dados?
Pergunta
A partir de um quadro de dados com linhas timestamped (resultados strptime), o que é o melhor método para agregar estatísticas para intervalos?
Intervalos poderia ser uma hora, um dia, etc
Há a função aggregate
, mas isso não ajudar com a atribuição de cada linha para um intervalo. Estou pensando em adicionar uma coluna para o quadro de dados que denota intervalo e usando isso com aggregate
, mas se há uma solução melhor seria ótimo para ouvi-lo.
Obrigado por qualquer ponteiros!
Exemplo de Dados
Cinco linhas com marcas de tempo dividido em 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"
Conclusão
Usando um pacote de séries temporais, como xts
deve ser a solução; porém eu não teve sucesso usá-los e fôlego até usando cut
. Como eu atualmente só precisa histogramas enredo, com linhas agrupadas por intervalo, este foi o suficiente.
cut
é usado gostou:
interv <- function(x, start, period, num.intervals) {
return(cut(x, as.POSIXlt(start)+0:num.intervals*period))
}
Solução
As funções padrão para vetores de divisão são cut
e 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 o registro: cut
tem um método para o tipo POSIXt
, mas infelizmente não há nenhuma maneira de fornecer argumento start
, o efeito é:
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 você vê o seu inicio em 3:02:00. Você poderia mexer com etiquetas de factor de saída (etiquetas converter-se ao tempo, rodada de alguma forma e converter de volta para personagem).
Outras dicas
Use a pacote de séries temporais. O pacote XTS tem funções projetado especificamente para fazer isso. Ou olhar para as funções agregadas e rollapply no pacote zoológico.
O ebook rmetrics tem uma discussão útil, incluindo uma comparação dos vários pacotes de desempenho: https://www.rmetrics.org/files/freepdf/TimeSeriesFAQ.pdf
Editar : Olhe para minha resposta a esta pergunta . Basicamente, você precisa truncar cada timestamp em um intervalo específico e, em seguida, fazer a agregação usando esses novos timestamps truncados como seu vetor de agrupamento.
Esta é uma pergunta interessante; com a proliferação dos vários pacotes de séries temporais e métodos, deve haver uma abordagem para binning série temporal irregular e não pela força bruta que o OP sugere. Aqui está uma maneira "de alto nível" para obter os intervalos que você pode usar para aggregate
et al, usando uma versão do 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))))
Você começa
intervals
[1] 1 1 1 2 2
que agora você pode anexar ao quadro de dados e agregados.
As acrobacias coersion acima (de personagem para TimeDate a personagem para chron) é um pouco infeliz, por isso, se há soluções mais limpas para binning dados tempo irregulares usando XTS ou qualquer um dos outros pacotes TimeSeries, eu adoraria ouvir sobre -los também! ..
Também estou curioso para saber o que seria a abordagem mais eficiente para binning série temporal irregular larga de alta frequência, por exemplo, a criação de barras de volume de 1 minuto em dados de carrapatos para um estoque muito líquido.