options symbolgen ; %macro download(measure=); options validvarname=any; filename csse "time_series_covid19_&measure._global.csv"; proc http url="https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_&measure._global.csv" method="GET" out=csse; run; proc import datafile=csse out=work._temp1 dbms=csv replace; getnames=yes; guessingrows=all; run; proc sort data=WORK._temp1 out=work._temp2; by 'Country/Region'n 'Province/State'n; run; data _temp3; set _temp2; drop lat long; rename 'Country/Region'n=country 'Province/State'n=state; run; ods select none; ods output Summary=_temp4; proc means data=work._temp3 sum nway; class country; var _numeric_; run; ods select default; data _temp5 (drop=nobs); set _temp4; run; proc transpose data=_temp5 out=_temp6 (drop=_label_ rename=(_name_=chardate COL1=&measure)); by country; run; data work._temp7 (drop=chardate); format date date9.; set _temp6; chardate=scan(chardate,1,'_'); date=input(chardate, mmddyy8.); run; proc sort data=_temp7 out=work.csse_&measure; by country date; run; %mend; %download(measure=confirmed); %download(measure=deaths); proc datasets lib=work nolist; delete _temp1 - _temp7; quit; /* Compute new confirmed cases for each day */ data work.confirmed (drop=previous_confirmed); set work.csse_confirmed; by country; retain previous_confirmed; if first.country then confirmed_new_cases=confirmed; if not first.country then confirmed_new_cases=confirmed - previous_confirmed; previous_confirmed=confirmed; run; /* merge data for confirmed and deaths */ proc sort data=work.confirmed out=work._temp1; by country date; run; proc sort data=work.csse_deaths out=work.deaths; by country date; run; data confirmed_deaths; merge _temp1 deaths; by country date; run; /* Compute new death cases for each day */ data work.confirmed_deaths (drop=previous_deaths); set work.confirmed_deaths; by country; retain previous_deaths; if first.country then deaths_new_cases=deaths; if not first.country then deaths_new_cases=deaths - previous_deaths; previous_deaths=deaths; run; /* find top countries by death cases and save the list in a macro variable */ proc sql outobs=5 noprint; create table work._temp1 as select sum(deaths) as total, country from work.csse_deaths where country ne '' group by country order by total desc; quit; proc sql noprint; create table work._temp2 as select distinct country as country from work._temp1; quit; data _temp2; set _temp2; countrylist="'" || strip(country) || "'"; run; proc sql noprint; select distinct countrylist into :country separated by ',' from work._temp2; quit; %put ==== Top Countries Based on Total Deaths : &country ==== ; proc datasets lib=work nolist; delete _temp1 - _temp7; quit; /* plot for some countries */ %let country='Italy','United Kingdom','US'; proc sort data=work.confirmed_deaths out=sorted; by country; run; /* calculate the 5 day rolling average for new cases */ proc expand DATA=sorted OUT=rollingavg; convert confirmed_new_cases=confirmed_mean7 / METHOD=none TRANSFORMOUT=(MOVAVE 7); convert deaths_new_cases=deaths_mean7 / METHOD=none TRANSFORMOUT=(MOVAVE 7); by country; run; /* create the block variable */ data rollingavg; set rollingavg; format blockdate monyy.; blockdate=date; run; proc sort data=rollingavg; by date; run; ods listing style=HTMLBlue; /* plot standalone plot of rolling averages for selected countries */ ods graphics / width=700px height=400px; title j=l "COVID-19: 7-day Rolling Average of New Confirmed Cases against Time"; footnote1 j=l "Data Source: Johns Hopkins COVID-19 Data Repository [04MAY2020]"; footnote2 j=l "Created using PROC SGPLOT"; proc sgplot data=work.rollingavg subpixel; series x=date y=confirmed_mean7 / lineattrs=(thickness=2px pattern=solid) group=country curvelabel ; where country in (&country); xaxis grid type=time display=(nolabel); yaxis grid label="Confirmed new cases"; run; title j=l "COVID-19: 7-day Rolling Average of New Death Cases against Time"; footnote1 j=l "Data Source: Johns Hopkins COVID-19 Data Repository [04MAY2020]"; footnote2 j=l "Created using PROC SGPLOT"; proc sgplot data=work.rollingavg subpixel; series x=date y=deaths_mean7 / lineattrs=(thickness=2px pattern=solid) group=country curvelabel ; where country in (&country); xaxis grid type=time display=(nolabel); yaxis grid label="Deaths new cases"; run; /* plot the comparative graph for selected countries */ ods graphics / width=700px height=800px; title j=l "COVID-19: 7-day Rolling Average of New Confirmed Cases against Time"; footnote1 j=l "Data Source: Johns Hopkins COVID-19 Data Repository [04MAY2020]"; footnote2 j=l "Created using PROC SGPANEL"; proc sgpanel data=work.rollingavg noautolegend; format blockdate monyy.; panelby country / novarname columns=1 onepanel uniscale=column noheaderborder noborder headerattrs=(weight=bold); block x=date block=blockdate / filltype=alternate nooutline valuehalign=right nolabel novalues transparency=0.3 valuefitpolicy=truncate valuehalign=left; vbarparm category=date response=confirmed_new_cases / outlineattrs=(color=white) fillattrs=(color=orange) colorresponse=deaths_new_cases colormodel=(lightyellow orange lightred red) name="bar"; series x=date y=confirmed_mean7 / lineattrs=(color=black thickness=2px pattern=solid) arrowheadshape=barbed name="series" legendlabel="7-day rolling average"; gradlegend "bar" / position=bottom title="Deaths new cases"; keylegend "series"; where country in (&country); colaxis type=time display=(nolabel); rowaxis label="Confirmed new cases"; run; title; footnote;