#sas #proc-sql
#sas #proc-sql
Вопрос:
У меня есть следующие данные
Date value_idx
2002-01-31 .
2002-01-31 24.533
2002-01-31 26.50
2018-02-28 25.2124
2019-09-12 22.251
2019-01-31 24.214
2019-05-21 25.241
2019-05-21 .
2020-05-21 25.241
2020-05-21 23.232
Мне нужно было бы рассчитать среднее значение value_idx за последние 3 года и 7 лет.
Сначала я попытался рассчитать его следующим образом:
proc sql;
create table table1 as
select date, avg(value_idx) as avg_value_idx
from table
group by date;
quit;
Проблема в том, что я не знаю, как рассчитать среднее значение value_idx не за каждый месяц, а за последние два года. Поэтому я думаю, что я должен извлечь год, сгруппировать по нему, а затем вычислить среднее значение.
Я надеюсь, что кто-нибудь из вас сможет мне в этом помочь.
Комментарии:
1. Пожалуйста, объясните, что вы хотите более четко. Не могли бы вы предоставить результаты для опубликованных вами выборочных данных. Если вам просто нужно среднее значение за 7 лет до сегодняшнего дня, просто используйте предложение WHERE для фильтрации наблюдений с датой> = ’01JAN2013′ .
2. Мне нужно было бы рассмотреть среднее значение value_idx, вычисляющее его за последние два года (2019 и 2018).
3. Вам нужны только два значения для всего набора данных? Если да, то почему в вашем примере предпринята попытка включить переменную DATE в результирующий набор? Если нет, то сколько результатов вы хотите?
4. это должно быть всего одно значение, так как я должен взять среднее значение за 2018 и 2019 годы (последние два года), начиная с самого последнего года (который в наборе данных равен 2020).
5. Это возможно в
PROC SQL
, но я не рекомендую использовать это для подобных вещей — если у вас есть причина, которую вы должны использоватьPROC SQL
конкретно, измените сообщение, чтобы включить это.
Ответ №1:
Вы можете использовать CASE, чтобы решить, какие записи вносят вклад в какое СРЕДНЕЕ значение. Вам необходимо уточнить, что вы подразумеваете под последними 2 или последними 7 годами. Этот код найдет значение максимальной даты, а затем сравнит год этой даты с годом других дат.
select
mean(case when year(max_date)-year(date) < 2 then value_idx else . end) as mean_yr2
,mean(case when year(max_date)-year(date) < 7 then value_idx else . end) as mean_yr7
from have,(select max(date) as max_date from have)
;
Результаты
mean_yr2 mean_yr7
------------------
24.0358 24.2319
Ответ №2:
Лучший способ сделать что-то подобное в SAS — использовать собственные процедуры, поскольку у них много функций, связанных с группировкой.
В этом случае мы используем форматы с несколькими метками для управления группировкой. Я предполагаю, что вы имеете в виду «последние три года», как в календаре 2018/2019/2020 и «Последние семь лет», как в календаре 2014-2020. Предположительно, вы можете увидеть, как изменить это для других периодов времени — до тех пор, пока вы не пытаетесь установить период времени относительно каждой точки данных.
Мы создаем формат, в котором используется MULTILABEL
опция (которая позволяет распределять точки данных по нескольким категориям) и NOTSORTED
опция (позволяющая нам принудительно упорядочивать метки, в противном случае СЕМЬ раньше, чем ТРИ).
Затем мы используем его в PROC TABULATE, включив его с MLF
помощью (MultiLabel Format) и preloadfmt order=data
который снова сохраняет правильность упорядочения. При этом создается отчет только с двумя средними значениями.
data have;
informat date yymmdd10.;
input Date value_idx;
datalines;
2002-01-31 .
2002-01-31 24.533
2002-01-31 26.50
2017-02-28 25.2124
2017-09-12 22.251
2018-01-31 24.214
2018-05-21 25.241
2019-05-21 .
2020-05-21 25.241
2020-05-21 23.232
;;;;
run;
proc format;
value yeartabfmt (multilabel notsorted)
'01JAN2018'd-'31DEC2020'd = 'Last Three Years'
'01JAN2014'd-'31DEC2020'd = 'Last Seven Years'
other=' '
;
quit;
proc tabulate data=have;
class date/mlf preloadfmt order=data;
var value_idx;
format date yeartabfmt.;
tables date,value_idx*mean;
run;