#r #merge
#r #объединить
Вопрос:
У меня есть два набора данных.
Набор данных X выглядит следующим образом. Он содержит 30-минутные интервалы торгового дня некоторого фондового индекса, который открывается в 9:30 утра и закрывается в 15:00 вечера для DJ, но в 16:00 вечера для DX. Таким образом, время закрытия может варьироваться в зависимости от тикера.
Date Ticker end_time start_time
1997-10-06 DJ 10:00 09:30
1997-10-06 DJ 10:30 10:00
1997-10-06 DJ 11:00 10:30
1997-10-06 DJ 11:30 11:00
1997-10-08 DJ 09:30 15:00
1997-10-08 DJ 10:00 09:30
1997-10-06 DX 10:00 09:30
1997-10-06 DX 10:30 10:00
1997-10-06 DX 11:00 10:30
1997-10-06 DX 11:30 11:00
1997-10-07 DX 14:30 14:00
1997-10-07 DX 15:00 14:30
1997-10-07 DX 15:30 15:00
1997-10-07 DX 16:00 15:30
1997-10-08 DX 09:30 16:00
1997-10-08 DX 10:00 09:30
Набор данных Y выглядит следующим образом:
Date Time Event
1997-10-06 09:30 Event1
1997-10-06 10:30 Event2
1997-10-07 22:00 Event3
1997-10-08 09:00 Event4
1997-10-08 09:30 Event5
1997-10-08 09:30 Event6
Моя цель — связать события в Y с X в зависимости от того, происходит ли дата-время события в интервале времени начала / окончания. Мой ожидаемый результат — это что-то (набор данных Z):
Date Ticker end_time start_time Event
1997-10-06 DJ 10:00 09:30 Event1
1997-10-06 DJ 10:30 10:00 NA
1997-10-06 DJ 11:00 10:30 Event2
1997-10-06 DJ 11:30 11:00 NA
1997-10-08 DJ 09:30 15:00 Event3,Event4
1997-10-08 DJ 10:00 09:30 Event5,Event6
1997-10-06 DX 10:00 09:30 Event1
1997-10-06 DX 10:30 10:00 NA
1997-10-06 DX 11:00 10:30 Event2
1997-10-06 DX 11:30 11:00 NA
1997-10-07 DX 14:30 14:00 NA
1997-10-07 DX 15:00 14:30 NA
1997-10-07 DX 15:30 15:00 NA
1997-10-07 DX 16:00 15:30 NA
1997-10-08 DX 09:30 16:00 Event3, Event4
1997-10-08 DX 10:00 09:30 Event5,Event6
Таким образом, между интервалом может произойти несколько событий. Возможно ли сохранить их в столбце «Событие». Также возможно, что событие происходит после закрытия рынка, которое должно быть сохранено в первом интервале, который происходит после события. Как я могу получить этот ожидаемый результат? Я уже некоторое время думаю, но понятия не имею, с чего начать.
Редактировать: X содержит 400 Тыс. 30-минутных интервалов. Y содержит 40 тыс. событий.
Ответ №1:
Существует множество способов решения проблемы, вот только одно предложение.
Я использую эти наборы данных:
x <- read.table(text = "Date,Ticker,end_time,start_time
06/10/1997,DJ,10:00,09:30
06/10/1997,DJ,10:30,10:00
06/10/1997,DJ,11:00,10:30
06/10/1997,DJ,11:30,11:00
08/10/1997,DJ,09:30,15:00
08/10/1997,DJ,10:00,09:30
06/10/1997,DX,10:00,09:30
06/10/1997,DX,10:30,10:00
06/10/1997,DX,11:00,10:30
06/10/1997,DX,11:30,11:00
07/10/1997,DX,14:30,14:00
07/10/1997,DX,15:00,14:30
07/10/1997,DX,15:30,15:00
07/10/1997,DX,16:00,15:30
08/10/1997,DX,09:30,16:00
08/10/1997,DX,10:00,09:30
08/10/1997,DX,10:00,09:30", sep =",", header = TRUE, stringsAsFactors =
FALSE)
y <- read.table(text = "Date,Time,Event
06/10/1997,09:30,Event1
06/10/1997,10:30,Event2
07/10/1997,22:00,Event3
08/10/1997,09:00,Event4
08/10/1997,09:30,Event5
08/10/1997,09:30,Event6
", sep =",", header = TRUE, stringsAsFactors = FALSE)
Я бы начал с объединения и форматирования дат и времени, чтобы их можно было использовать в функциях для проверки, произошло ли событие в этом окне. Предполагая, что у вас есть два фрейма данных с именами x и y в структуре, описанной выше:
y$date_time <- strptime(paste(y$Time,y$Date),format="%H:%M %d/%m/%Y")
x$start_time_date <- strptime(paste(x$start_time,x$Date),format="%H:%M %d/%m/%Y")
x$end_time_date <- strptime(paste(x$end_time,x$Date),format="%H:%M %d/%m/%Y")
Если у вас есть контроль над набором данных по мере его компиляции, то, возможно, было бы проще записать даты начала и окончания таким образом, так как для периодов, которые пересекают дату, выполнение этого таким образом приведет к появлению даты начала, которые находятся после даты окончания. Мы можем редактировать их, просто используя вместо этого дату из предыдущей записи во фрейме данных, предполагая, что она всегда будет в хронологическом порядке и не будет пропущенных периодов. Это немного взлом!:
#check which entries cross over a date
overnight_idx <- which(x$end_time_date < x$start_time_date)
#replace start date with that of preceding entry in the data frame
x[overnight_idx, 'start_time_date'] <-
as.POSIXct(paste(x[overnight_idx, 'start_time'],
x[overnight_idx - 1, 'Date']),format="%H:%M %d/%m/%Y",
origin = "1970-01-01")
Теперь мы можем написать функцию, которая для заданной строки в фрейме данных x будет извлекать любые события, которые произошли, перечисленные в y, а затем выполнить небольшое форматирование, чтобы получить его в формате, который вы описали.
checkEvent <- function(x_row){
y2 <- y[y$date_time>=x_row['start_time_date'] amp;
y$date_time<x_row['end_time_date'], 'Event']
if(length(y2)==0){
y2 <- NA
} else if(length(y2)>1){
y2 <- paste(y2,collapse = ' ')
}
return(y2)
}
Тогда мы можем просто применить это к x
x$Event <- apply(x,1,checkEvent)
что приведет к следующему (игнорируя столбцы, которые мы создали выше, чтобы они помещались на экране):
> x[,c('Date','Ticker','end_time','start_time','Event')]
Date Ticker end_time start_time Event
1 06/10/1997 DJ 10:00 09:30 Event1
2 06/10/1997 DJ 10:30 10:00 <NA>
3 06/10/1997 DJ 11:00 10:30 Event2
4 06/10/1997 DJ 11:30 11:00 <NA>
5 08/10/1997 DJ 09:30 15:00 Event3 Event4
6 08/10/1997 DJ 10:00 09:30 Event5 Event6
7 06/10/1997 DX 10:00 09:30 Event1
8 06/10/1997 DX 10:30 10:00 <NA>
9 06/10/1997 DX 11:00 10:30 Event2
10 06/10/1997 DX 11:30 11:00 <NA>
11 07/10/1997 DX 14:30 14:00 <NA>
12 07/10/1997 DX 15:00 14:30 <NA>
13 07/10/1997 DX 15:30 15:00 <NA>
14 07/10/1997 DX 16:00 15:30 <NA>
15 08/10/1997 DX 09:30 16:00 Event3 Event4
16 08/10/1997 DX 10:00 09:30 Event5 Event6
17 08/10/1997 DX 10:00 09:30 Event5 Event6
Комментарии:
1. Привет, Сэм, в последнем столбце я получаю список. Итак, для первой строки <df[,1] [1 x 1]> вместо Event1 и во второй строке я получаю <df[,1] [0 x 1]> вместо NA . Вы знаете, как я могу это решить?
2. Я предполагаю, что ваш фрейм данных структурирован неправильно — я отредактировал ответ, чтобы предоставить пригодные для использования фреймы данных с теми же данными