Как построить простой линейный сюжет в SAS
Мои данные структурированы следующим образом (это только примерные данные, поскольку исходные данные являются секретными)
id | crime | location | crimedate
------------------------------
1 | Theft | public | 2019-01-04
1 | Theft | public | 2019-02-06
1 | Theft | public | 2019-02-20
1 | Theft | private | 2019-03-10
1 | Theft | private | 2019-03-21
1 | Theft | public | 2019-03-01
1 | Theft | private | 2019-03-14
1 | Theft | public | 2019-06-15
1 | Murder | private | 2019-01-04
1 | Murder | private | 2019-10-20
1 | Murder | private | 2019-11-18
1 | Murder | private | 2019-01-01
1 | Assault | private | 2019-03-19
1 | Assault | private | 2019-01-21
1 | Assault | public | 2019-04-11
1 | Assault | public | 2019-01-10
… | … | … | …
Моя цель - создать линейный сюжет (сюжет временного ряда), показывающий, как за три года изменились цифры трех преступлений. Поэтому на оси X я хотел бы показать месяцы (1-12), а на оси Y количество преступлений в каждом месяце. Там должно быть две строки (по одной для каждого места).
Я начал с этого кода:
DATA new;
SET old;
month=month(datepart(crimedate));
RUN;
PROC sgplot DATA=new;
series x=month y=no_of_crimes / group=location;
run;
Но я понятия не имею, как я могу агрегировать количество преступлений в месяц. Может ли кто-нибудь дать мне подсказку? Я искал в Интернете решение, но обычно в примерах просто используются данные, которые уже агрегированы.
3 ответа
Процедуры SG будут агрегировать значения оси Y для VBAR
или же HBAR
заявление. Та же самая совокупная информация, отображаемая в SERIES
утверждение должно быть из априорного вычисления агрегата, легко сделать с Proc SUMMARY
,
Кроме того, чтобы отобразить счетчики для каждого преступления в отдельном визуальном элементе, вы бы хотели BY CRIME
заявление или Proc SGPANEL
с участием PANELBY crime
,
Значение даты и времени преступления не нужно преобразовывать в значение даты, вы можете использовать соответствующие datetime
формат в процедурах, и они будут автоматически объединяться на основе отформатированного значения.
Пример с некоторыми данными смоделированного преступления:
data have;
do precinct = 1 to 10;
do date = '01jan2018'd to '31dec2018'd;
do seq = 1 to 20*ranuni(123);
length crime $10 location $8;
crime = scan('theft,assault,robbery,dnd', ceil(4*ranuni(123)));
location = scan ('public,private', ceil(2*ranuni(123)));
crime_dt = dhms(date,0,0,floor('24:00't*ranuni(123)));
output;
end;
end;
end;
drop date;
format crime_dt datetime19.;
run;
* shorter graphs for SO answer;
ods graphics / height=300px;
proc sgplot data=have;
title "VBAR all crimes combined by location";
vbar crime_dt
/ group=location
groupdisplay=cluster
;
format crime_dt dtmonyy7.;
run;
proc sgpanel data=have;
title "VBAR crime * location";
panelby crime;
vbar crime_dt
/ group=location
groupdisplay=cluster
;
format crime_dt dtmonyy7.;
run;
proc summary data=have noprint;
class crime_dt crime location;
format crime_dt dtmonyy7.;
output out=freqs;
run;
proc sgplot data=freqs;
title "SERIES all crimes,summary _FREQ_ * location";
where _type_ = 5;
series x=crime_dt y=_freq_ / group=location;
xaxis type=discrete;
run;
proc sgpanel data=freqs;
title "SERIES all crimes,summary _FREQ_ * crime * location";
where _type_ = 7;
panelby crime;
series x=crime_dt y=_freq_ / group=location;
rowaxis min=0;
colaxis type=discrete;
run;
Если вы хотите сгруппировать по местоположению без определения по типу преступления:
proc sql noprint;
create table new as
select id,location
, month(crimedate) as month,count(crime) as crime_n
from old
group by id,location,CALCULATED month;
quit;
proc sgplot data=new;
series x=month y=crime_n /group=location;
run;
Результат:
Чтобы показать разные серии по типу преступления, вы можете использовать sgpanel
:
proc sql noprint;
create table new as
select id,crime,location, month(crimedate) as month,count(crime) as crime_n
from old
group by id,crime,location,CALCULATED month;
quit;
proc sgpanel DATA=new;
panelby location;
series x=month y=crime_n /group=crime;
run;
Результат:
Еще один вариант выполнения этих данных:
proc sql noprint;
create table new as
select id,crime,location, month(crimedate) as month,count(crime) as crime_n
from old
group by id,crime,location,CALCULATED month;
quit;
proc sgpanel DATA=new;
panelby crime;
series x=month y=crime_n /group=location GROUPDISPLAY=cluster;
run;
Результат:
Конечно, вы можете указать эти графики, как вы хотите.
Чтобы, возможно, ответить на вопрос более прямо, VLINE
или же HLINE
графики будут обобщать данные для вас, аналогично proc freq
а потом proc sgplot
с участием series
,
Используя тестовые данные Ричарда, вы увидите, что это в точности совпадает с графиком, который дает его PROC FREQ -> SERIES:
data have;
do precinct = 1 to 10;
do date = '01jan2018'd to '31dec2018'd;
do seq = 1 to 20*ranuni(123);
length crime $10 location $8;
crime = scan('theft,assault,robbery,dnd', ceil(4*ranuni(123)));
location = scan ('public,private', ceil(2*ranuni(123)));
crime_dt = dhms(date,0,0,floor('24:00't*ranuni(123)));
output;
end;
end;
end;
drop date;
format crime_dt datetime19.;
run;
proc sgplot data=have;
vline crime_dt/group=location groupdisplay=cluster;
format crime_dt dtmonyy7.;
run;