#sas #sas-macro #datastep
#sas #sas-макрос #datastep
Вопрос:
Я хотел бы сравнить наблюдения за ценами в скользящем временном окне в 10 минут.
Допустим, у меня есть следующая таблица с ценами (крайний левый столбец) на продукты и временем, в которое они были проданы:
data have;
input @1 PRICE 1. @6 PRODUCT $3. @12 DATE_TIME anydtdtm15.;
format date_time datetime17.;
datalines;
1 POW JAN-01-17 13:00
2 POW JAN-01-17 13:04
1 POW JAN-01-17 13:06
2 POW JAN-01-17 13:15
3 POW JAN-01-17 13:20
5 POW JAN-01-17 13:29
1 GAS JAN-01-17 13:05
2 GAS JAN-01-17 13:10
1 GAS JAN-01-17 13:39
;;;;
run;
Что мне нужно, так это фрагмент кода, который позволит мне сравнивать цены в 10-минутном окне. Например: наблюдение за POW в 13:00 имеет цену 1, и это наблюдение за ценой следует сравнить со всеми другими наблюдениями за ценами до 15: 10, которые относятся к тому же продукту. Если в этом временном окне есть совпадение по цене, соответствующие строки должны быть отображены в таблице.
Это снова нужно сделать для наблюдения в 13: 04 и цены 2, которую затем следует сравнить с наблюдениями до 13: 14 и так далее..
Можно ли это сделать?
Комментарии:
1. Конечно, это можно сделать, но что вы пробовали? Вы получали ошибки, комбинаторные сбои или отсутствующие данные? Почему 10-минутное окно, начинающееся в 13:00, заканчивается в 15: 10?
2. Извините, имел в виду 13:10. Что ж, прямо сейчас я работаю над добавлением 10 минут к дате-времени для каждой строки, а затем объединяю таблицу саму по цене и продукту. Кажется, пока вроде как работает. Хотя выглядит немного неуклюже.
3. Это фактически решило проблему. Мне потребовалось некоторое время, чтобы добраться туда, но я думаю, что теперь я понял это.
Ответ №1:
Было ли ваше решение SQL рефлексивным (или самостоятельным) объединением?
В этом примере self left join строки объединены по продукту и цене, чтобы обеспечить соблюдение одних и тех же критериев поиска цен. Объединение дополнительно ужесточается за счет ограничения временных рамок, в течение которых одни и те же цены принимаются за совпадение. левое соединение используется в случае, если нет будущего с той же ценой.
data have;
input @1 PRICE 1. @6 PRODUCT $3. @12 DATE_TIME anydtdtm15.;
format date_time datetime17.;
datalines;
1 POW JAN-01-17 13:00
2 POW JAN-01-17 13:04
1 POW JAN-01-17 13:06
2 POW JAN-01-17 13:15
3 POW JAN-01-17 13:20
5 POW JAN-01-17 13:29
1 GAS JAN-01-17 13:05
2 GAS JAN-01-17 13:10
1 GAS JAN-01-17 13:39
1 GAS JAN-01-17 13:42
1 GAS JAN-01-17 13:44
1 GAS JAN-01-17 13:52
;;;;
run;
proc sql;
create table want as
select self.*
, twin.date_time as same_priced_future_date_time
, twin.date_time - self.date_time as delta format=time8.
from have as self
left join have as twin
on self.product = twin.product
and self.price = twin.price
and self.date_time < twin.date_time
and twin.date_time - self.date_time <= '00:10:00't
order by self.product, self.date_time, twin.date_time
;
Существуют другие способы, использующие шаг ДАННЫХ; будь то слияние / задержка, циклы DOW или хэширование
Комментарии:
1. Извините, я не уверен, что означает SQL reflexive. Что я сделал, так это создал новую переменную datetime, которая является исходной datetime плюс 10 минут, а затем объединил набор данных сам по себе в proc sql, где одним из условий для объединения было выражение between (datetime и datetime плюс 10). Это дало мне то сопряжение, которое мне было нужно.
2. присоедините набор данных к самому себе — это рефлексивно :). То же самое
have as self left join have as twin
в примере выше.