2011-12-18 5 views
4

У меня есть большой (150 000x7) фрейм данных, который я намерен использовать для повторного тестирования и анализа в реальном времени финансового рынка. Данные представляют состояние транспортного средства с 5-минутными интервалами (, хотя отверстия существуют). Похоже, что это (но гораздо больше):R: Эффективно подмножество данных в зависимости от времени суток

 pTime  Time Price  M1  M2  M3  M4 
1 1212108300 20:45:00 1.5518 12.21849 -0.37125 4.50549 -31.00559 
2 1212108900 20:55:00 1.5516 11.75350 -0.81792 -1.53846 -32.12291 
3 1212109200 21:00:00 1.5512 10.75070 -1.47438 -8.24176 -34.35754 
4 1212109500 21:05:00 1.5514 10.23529 -1.06044 -8.46154 -33.24022 
5 1212109800 21:10:00 1.5514 9.74790 -1.02759 -10.21978 -33.24022 
6 1212110100 21:15:00 1.5513 9.31092 -1.17076 -11.97802 -33.79888 
7 1212110400 21:20:00 1.5512 8.84034 -1.28428 -13.62637 -34.35754 
8 1212110700 21:25:00 1.5509 8.07843 -1.63715 -18.24176 -36.03352 
9 1212111000 21:30:00 1.5509 7.39496 -1.49198 -20.65934 -36.03352 
10 1212111300 21:35:00 1.5512 7.65266 -1.03717 -18.57143 -34.35754 

Данные предварительно загружаются в R, но во время моего обратного теста мне нужно Подмножество его по двум критериям:

Первый критерий представляет собой чтобы избежать заглядывания в будущее. Окно должно быть таким, чтобы каждый новый 5-минутный интервал на заднем тесте сдвигал все окно в будущее на 5 минут. Эта часть я могу сделать так:

require(zoo) 
zooser <- zoo(x=tser$Close, order.by=as.POSIXct(tser$pTime, origin="1970-01-01")) 
window(zooser, start=A, end=B)  

Второго критерий является другого раздвижного окна, но один, который скользит через time of day и содержит только те записи, которые находятся в пределах N минут времени ввода в любой день ,

Пример: Если размер окна является 2 hours и время вход 12:00PM то окно должно содержать все строки с Time между 10:00AM и 2:00PM

Это та часть, которая у меня возникли проблемы, выяснить.

Редактировать: Мои данные имеют отверстия в нем, два последовательных ряда могут быть БОЛЕЕ 5 минут друг от друга. Данные выглядят так: enter image description here

Поскольку окно проходит через эти промежутки, количество точек внутри окон должно меняться.

Ниже мой код MySQL, который делает то, что я хочу сделать в R (ту же структуру таблицы):

SET @qTime = Time(FROM_UNIXTIME(SAMP_endTime)); 

SET @inc = -1; 
INSERT INTO MetIndListBuys (pTime,ArrayPos,M1,M2,M3,M4) 
SELECT pTime,@inc:[email protected]+1,M1,M2,M3,M4 
FROM mergebuys USE INDEX (`y`) WHERE pTime BETWEEN SAMP_startTime AND SAMP_endTime 
AND TIME_TO_SEC(TIMEDIFF(Time,@qTime))/3600 BETWEEN 0-HourSpan AND HourSpan 
; 
+0

Эти значения индекса нигде не приближаются к 12:00 PM, по крайней мере, в моем часовом поясе. –

+0

Да, вы правы ... Я просто случайно выбрал «12:00 PM». Плохой пример, я думаю. –

ответ

2

Скажите, что у вас есть целевое время t0 в том же масштабе, что и pTime: секунды с эпохи. Тогда t0 - pTime = (разница в числе дней с эпохи между двумя) + (разница в оставшихся секундах). Взятие t0 - pTime %% (количество секунд в день) оставит нас с разницей в секундах в арифметике часов (обернуто, если разница отрицательная). Это говорит о следующей функции:

SecondsPerDay <- 24 * 60 * 60 
within <- function(d, t0Sec, wMin) { 
    diff <- (d$pTime - t0Sec) %% SecondsPerDay 
    wSec <- 60 * wMin 
    return(d[diff < wSec | diff > (SecondsPerDay - wSec), ]) 
} 
+0

Я пытаюсь понять это решение, но я новичок в R - не могли бы вы объяснить, что происходит в инструкции 'return'? –

+0

Для вектора булевых x, d [x,] возвращает новый data.frame только с строками d, для которых x имеет TRUE. "|" является векторным оператором «OR» с i-й записью в его результате TRUE, если i-я запись хотя бы одного из аргументов была TRUE. Например, i-я запись в «diff (SecondsPerDay-wSec)» будет TRUE, если «diff [i] (SecondsPerDay-wSec)». (Поскольку wSec имеет длину один, что меньше длины diff, R будет «перерабатывать» то одно значение для каждого значения в diff при выполнении операции «<», то же самое для (SecondsPerDay - wSec).) Надеюсь, что это поможет , –

+0

И, в частности, diff> (SecondsPerDay - wSec) обрабатывает случаи, когда diff был фактически «отрицательным», но обернулся вокруг арифметики часов. –

2

1) Если DF является кадр данных показано в вопросе затем создать зоопарк объект из него, как вы это сделали, и разделите его на дни, давая zs. Затем lapply ваша функция f для каждого последующего набора w точек в каждом компоненте (т. Е. В каждый день). Например, если вы хотите применить свою функцию к 2 часам данных за раз, а ваши данные будут регулярно размещаться на 5-минутных данных, тогда w = 24 (так как в течение двух часов есть 24 пятиминутных периода). В таком случае f будет передавать 24 строки данных в виде матрицы каждый раз при ее вызове. Также align был установлен на "right" ниже, но альтернативно может быть установлен в align="center" и условие дает ix может быть изменен на двухсторонней и т.д. Более подробную информацию о rollapply См: ?rollapply

library(zoo) 
z <- zoo(DF[-2], as.POSIXct(DF[,1], origin = "1970-01-01")) 
w <- 3 # replace this with 24 to handle two hours at a time with five min data 
f <- function(x) { 
      tt <- x[, 1] 
      ix <- tt[w] - tt <= w * 5 * 60 # RHS converts w to seconds 
      x <- x[ix, -1] 
      sum(x) # replace sum with your function 
    } 
out <- rollapply(z, w, f, by.column = FALSE, align = "right") 

Использование кадра данных в вопрос, который мы получаем это:

> out 
$`2008-05-30` 
2008-05-30 02:00:00 2008-05-30 02:05:00 2008-05-30 02:10:00 2008-05-30 02:15:00 
      -66.04703   -83.92148   -95.93558   -100.24924 
2008-05-30 02:20:00 2008-05-30 02:25:00 2008-05-30 02:30:00 2008-05-30 02:35:00 
     -108.15038   -121.24519   -134.39873   -140.28436 

Кстати, не забудьте прочитать this post.

2) Это может быть сделано попеременно как следующие, где w и f, как указано выше:

n <- nrow(DF) 
m <- as.matrix(DF[-2]) 
sapply(w:n, function(i) { m <- m[seq(length = w, to = i), ]; f(m) }) 

Заменить sapply с lapply, если это необходимо. Также это может показаться короче первого решения, но оно не сильно отличается после добавления кода для определения f и w (которые появляются в первом, но не во втором).

Если в течение дня нет отверстий и только отверстия между днями, то эти решения могут быть упрощены.

+0

Спасибо за ваш ответ (и ссылку!) Проблема в том, что мои данные не имеют регулярного промежутка - в нем могут быть (и должны быть) отверстия. Прошу прощения за то, что я не понял этого. Я редактировал свой пост, чтобы представить это. –

+0

Являются ли отверстия только временами между днями или есть дыры в дни? На графике кажется, что отверстия находятся только между днями, и если это так, то код выше должен работать. –

+0

Также я изменил решение так, чтобы оно работало, даже если в течение дня есть отверстия. –

Смежные вопросы