%let name=donald_trump_approval;

/* 
Set your current-working-directory (to read/write files), if you need to ...
%let rc=%sysfunc(dlgcdir('c:\someplace\public_html')); 
*/
filename odsout '.';

/*
Inspired by:
https://projects.fivethirtyeight.com/trump-approval-ratings/

Using data from:
https://github.com/fivethirtyeight/data/tree/master/trump-approval-ratings
https://projects.fivethirtyeight.com/trump-approval-data/approval_polllist.csv

License info:
https://github.com/fivethirtyeight/data/blob/master/LICENSE
(Creative Commons, commercial use, modification, etc)
*/

/* ran this proc once, then copied the generated code from the log file... */
/*
PROC IMPORT OUT=my_data DATAFILE="approval_polllist.csv" DBMS=CSV REPLACE;
GETNAMES=YES;
DATAROW=2; 
guessingrows=all;
RUN;
*/

filename csvurl url "https://projects.fivethirtyeight.com/trump-approval-data/approval_polllist.csv";
/*
filename csvurl "approval_polllist.csv";
*/

data my_data;
infile csvurl delimiter = ',' MISSOVER DSD lrecl=32767 firstobs=2;
/*
infile 'approval_polllist.csv' delimiter = ',' MISSOVER DSD lrecl=32767 firstobs=2;
*/
informat president $12. ;
informat subgroup $9. ;
informat modeldate mmddyy10. ;
informat startdate mmddyy10. ;
informat enddate mmddyy10. ;
informat pollster $52. ;
informat grade $2. ;
informat samplesize best32. ;
informat population $2. ;
informat weight best32. ;
informat influence best32. ;
informat approve best32. ;
informat disapprove best32. ;
informat adjusted_approve best32. ;
informat adjusted_disapprove best32. ;
informat multiversions $2. ;
informat tracking $2. ;
informat url $282. ;
informat poll_id best32. ;
informat question_id best32. ;
informat createddate mmddyy10. ;
informat timestamp $20. ;
format president $12. ;
format subgroup $9. ;
format modeldate date9. ;
format startdate date9. ;
format enddate date9. ;
format pollster $52. ;
format grade $2. ;
format samplesize best12. ;
format population $2. ;
format weight best12. ;
format influence best12. ;
format approve best12. ;
format disapprove best12. ;
format adjusted_approve best12. ;
format adjusted_disapprove best12. ;
format multiversions $2. ;
format tracking $2. ;
format url $282. ;
format poll_id best12. ;
format question_id best12. ;
format createddate date9. ;
format timestamp $20. ;
input
 president  $
 subgroup  $
 modeldate
 startdate
 enddate
 pollster  $
 grade  $
 samplesize
 population  $
 weight
 influence
 approve
 disapprove
 adjusted_approve
 adjusted_disapprove
 multiversions  $
 tracking  $
 url  $
 poll_id
 question_id
 createddate
 timestamp  $
;
run;

/*
Their data seems to have 'duplicate' entries for some polls,
with variations for 'All polls', 'Adults', 'Voters', etc.
*/
data my_data; set my_data (where=(subgroup='All polls') 
 drop = modeldate grade weight influence adjusted_approve adjusted_disapprove 
 multiversions tracking createddate timestamp);
run;

%let min=100;

proc sql noprint;
create table my_data as
select *, count(enddate) as count
from my_data
group by pollster
having count(enddate)>=&min
;
quit; run;

data my_data; set my_data;
format approve_pct percent7.0;
approve_pct=approve/100;
length my_html $300;
my_html=
 'title='||quote(
  trim(left(pollster))||'0d'x||
  trim(left(put(startdate,date9.)))||' - '||trim(left(put(enddate,date9.)))||'0d'x||
  trim(left(subgroup))||'0d'x||
  'Approval rating: '||trim(left(put(approve_pct,percent7.0)))||'0d'x||
  'Sample size: '||trim(left(put(samplesize,comma20.0))))||
 ' href='||quote(trim(left(url)));
run;

proc sort data=my_data out=my_data;
by pollster enddate;
run;

data my_data; set my_data;
by pollster;
if last.pollster then datelabel=trim(left(put(enddate,monname3.)))||' '||trim(left(put(enddate,day.)));
run;

data anno_milestones;
length position $1;
input date date9. position text $ 12-80;

length function $8 color $12 html $300;
color="dodgerblue";
xsys='2'; ysys='1'; hsys='3'; when='a';

when='b'; /* want the reflines behind the legend */
function='move'; x=date; y=100; output;
function='draw'; x=date; y=0; size=.001; line=33; output;

when='a';
html='title='||quote(trim(left(put(date,date9.)))||': '||trim(left(text)));
x=date-3; y=100;
function='label'; size=2.0; angle=90;
text=trim(left(text))||'a0a0'x;
output;

datalines;
20jan2017 a Trump sworn into office
27jan2017 d First travel ban executive order
07apr2017 a Placed Gorsuch on Supreme Court
13apr2017 d MOAB bombs dropped on ISIS targets
01jun2017 a Withdrew from Paris Climate Agreement
08aug2017 a 'Fire and Fury' threat to North Korea
23aug2017 a Veterans Appeal / Improv / Modern Act
05sep2017 a Ending DACA
22sep2017 a Trump condemns NFL player protests
17dec2017 a Recognized Jerusalem as capital of Israel
22dec2017 4 Repealed Obamacare individual mandate
01jan2018 d Tax cuts for 2018      
30jan2018 a First state-of-union address
11apr2018 a Bill to shut down sex-trafficking websites
30apr2018 a Black unemployment hit record low 6.6%
01may2018 d Unemployment below 4%
12jun2018 a Peace agreement with North Korea
21jul2018 a Threatens Iran "the likes of which few..."
30sep2018 a Replaced NAFTA with USMCA
06oct2018 d Placed Kavanaugh on Supreme Court
22dec2018 a Government shutdown started
25jan2019 a Government shutdown ended
24mar2019 a No Russian collusion
20jun2019 a Announces 2020 campaign in Orlando
30jun2019 d Trump walks into North Korea
03sep2019 a Trump funds the wall
18sep2019 d Whistleblower / Russia phone call
13nov2019 a Impeachment hearings start
18dec2019 a House votes impeachment
03jan2020 a Trump bombs Soleimani
05feb2020 a Impeachment acquittal
14mar2020 a Coronavirus hits US  
28may2020 a Race protests/riots
24jul2020 a New Big Pharma drug price rules
29sep2020 a 3rd nomination for Nobel Peace Prize
03nov2020 a Election
06jan2021 a Republican Protests in DC
;
run;


goptions device=png;
goptions xpixels=1500;

ODS LISTING CLOSE;
ODS HTML path=odsout body="&name..htm"
 (title="Donald Trump Approval Rating") 
 style=sasweb;

goptions gunit=pct htitle=4 htext=2.5 ftitle="albany amt" ftext="albany amt";
goptions ctext=gray33;

axis1 label=none order=(0 to 1.00 by .25) major=none minor=none 
 c=graydd value=(c=gray33) offset=(0,0);

axis2 label=none order=('01jan2017'd to '01jan2022'd by year) minor=none
 c=graydd value=(c=gray33) offset=(0,4);

symbol1 value=circle height=2.0 interpol=join color=hotpink
 pointlabel=(font='albany amt' height=1.8 color=gray55 
  position=middle justify=right "#datelabel");

options nobyline;
title1 ls=1.5 "Donald Trump's Approval Rating";
title2 ls=0.8 "Data source: #byval(pollster) (#byval(count) polls)";

ods html anchor="#byval(pollster)";
proc gplot data=my_data anno=anno_milestones;
format enddate year4.;
by pollster count;
plot approve_pct*enddate / 
 vaxis=axis1 haxis=axis2 
 vref=(0 .25 .50 .75 1) cvref=(graydd graydd gray55 graydd graydd)
 html=my_html
 des='' name="&name._#byval(pollster)";
run;


goptions reset=symbol;
symbol1 value=circle height=2.0 interpol=none repeat=100;

legend1 label=none position=(bottom left inside) mode=protect cframe=white across=1 repeat=1;

title2 ls=0.8 "Pollsters with at least &min polls during this time period";
ods html anchor='all';
proc gplot data=my_data;
format enddate year4.;
plot approve_pct*enddate=pollster / anno=anno_milestones
 vaxis=axis1 haxis=axis2 
 legend=legend1
 vref=(0 .25 .50 .75 1) cvref=(graydd graydd gray55 graydd graydd)
 html=my_html
 des='' name="&name";
run;

/*
proc print data=anno_milestones;
run;
proc print data=my_data (obs=100);
run;
proc print data=my_data;
run;
proc print data=my_data (where=(pollster='YouGov'));
run;
*/

quit;
ODS HTML CLOSE;
ODS LISTING;
