/* SAS program to accompany the article "Ranking US presidents" by Rick Wicklin, published 02JUL2018 on The DO Loop blog: https://blogs.sas.com/content/iml/2018/07/02/ranking-us-presidents.html This program uses SAS procedures to visualize the data from the 2018 Presidential Greatness Survey, which was created and administered by B. Rottinghaus and J. Vaughn. Their report is at https://sps.boisestate.edu/politicalscience/files/2018/02/Greatness.pdf For an alternative visualization, see https://cognitivefeedbackloop.com/all-the-u-s-presidents-ranked-by-greatness-b5f6a0b6dc3e */ proc format; value $PartyFmt "D" = "Democratic" "R" = "Republican" Other = "Other"; run; data PresGreatOrder; length Name $15; format Party $PartyFmt.; input Name $15. Party $2. RepRating DemRating IndepRating ConservRating LiberalRating ModerateRating; PresNum = _N_; /* examine differences between Democratic and Republican experts */ minParty = min(RepRating, DemRating, IndepRating); maxParty = max(RepRating, DemRating, IndepRating); gapParty = RepRating - DemRating; gpMin = min(0, gapParty); gpMax = max(0, gapParty); /* examine differences between Liberal and Conservative experts */ minIdeo = min(ConservRating, LiberalRating, ModerateRating); maxIdeo = max(ConservRating, LiberalRating, ModerateRating); gapIdeo = ConservRating - LiberalRating; gIMin = min(0, gapIdeo); gIMax = max(0, gapIdeo); datalines; Washington U 94.33 92.74 91.49 94.11 92.48 91.73 J. Adams F 57.14 64.21 64.11 61.64 64.08 62.35 Jefferson DR 69.71 82.11 78.88 74.92 81.48 77.95 Madison DR 52.29 67.29 64.56 60.50 66.77 61.65 Monroe DR 56.05 62.24 59.95 61.67 60.87 59.72 J.Q. Adams DR 48.62 52.85 51.55 51.54 52.62 50.39 Jackson D 64.24 62.17 61.14 63.00 60.66 65.19 VanBuren D 38.25 44.27 47.14 44.77 43.43 45.97 W.H. Harrison W 18.53 19.23 18.79 20.12 18.29 20.21 Tyler W 33.35 30.52 32.45 34.33 30.72 31.03 Polk D 60.30 51.83 55.68 60.46 49.84 59.54 Taylor W 33.60 31.21 37.27 37.64 30.76 36.14 Fillmore W 29.05 26.37 29.76 31.69 26.79 27.00 Pierce D 18.95 23.63 24.55 21.69 23.59 23.60 Buchanan D 14.32 15.88 13.73 13.44 15.48 15.17 Lincoln R 93.57 95.87 94.00 92.54 96.09 94.28 A. Johnson NU 20.90 26.58 23.41 21.35 25.06 27.26 Grant R 49.25 53.32 53.62 48.86 53.82 53.69 Hayes R 44.05 39.12 44.93 46.61 39.31 42.77 Garfield R 35.95 33.93 42.46 41.12 34.62 38.38 Arthur R 36.20 38.52 44.11 45.93 38.86 37.67 Cleveland D 54.80 48.86 53.53 56.22 47.28 56.26 B. Harrison R 38.85 36.07 40.12 39.44 35.82 40.63 McKinley R 64.40 50.45 61.27 68.11 48.60 62.51 T. Roosevelt R 77.14 83.33 79.49 75.54 82.89 82.14 Taft R 59.85 48.13 56.05 60.75 48.69 53.26 Wilson D 61.10 71.55 61.60 55.31 71.11 66.83 Harding R 32.15 23.28 25.95 31.93 24.48 21.92 Coolidge R 52.45 36.02 49.69 61.43 35.63 43.44 Hoover R 40.71 29.47 37.22 41.71 29.13 36.81 F.D. Roosevelt D 82.71 93.76 82.62 78.57 93.51 86.05 Truman D 66.81 77.62 74.07 70.43 77.20 73.65 Eisenhower R 67.95 74.15 76.60 72.54 73.15 77.32 Kennedy D 49.57 66.66 57.80 49.93 66.30 59.51 L.B. Johnson D 55.67 75.12 62.91 56.15 74.92 63.89 Nixon R 41.67 36.77 35.89 45.81 35.70 34.57 Ford R 49.19 46.21 48.58 52.25 44.19 51.27 Carter D 38.71 48.21 41.35 34.35 47.34 46.76 Reagan R 75.95 65.00 74.69 79.21 64.10 74.49 G.H.W. Bush R 62.90 59.03 63.76 67.04 57.97 63.57 Clinton D 58.57 66.47 62.28 59.85 65.42 64.41 G.W. Bush R 52.24 36.79 42.31 52.86 35.37 43.70 Obama D 57.33 78.10 62.98 54.96 78.27 64.57 Trump R 24.53 7.60 16.49 25.19 7.92 13.43 ; data PresGreatRank; length Name $15; input Name $15. MeanRating; Rank = _N_; datalines; Lincoln 95.03 Washington 92.59 F.D. Roosevelt 89.09 T. Roosevelt 81.39 Jefferson 79.54 Truman 75.15 Eisenhower 74.03 Obama 71.13 Reagan 69.24 L.B. Johnson 69.06 Wilson 67.40 Madison 64.48 Clinton 64.25 J. Adams 63.24 Jackson 62.16 Kennedy 61.86 G.H.W. Bush 60.90 Monroe 60.74 McKinley 55.49 Polk 54.09 Grant 52.88 Taft 51.96 J.Q. Adams 51.90 Cleveland 51.01 Ford 47.28 Carter 45.04 VanBuren 44.27 Coolidge 42.23 Hayes 41.50 G.W. Bush 40.42 Arthur 39.90 B. Harrison 37.63 Nixon 37.18 Garfield 36.64 Taylor 33.34 Hoover 33.27 Tyler 31.46 Fillmore 27.71 Harding 25.26 A. Johnson 24.91 Pierce 23.25 W.H. Harrison 19.02 Buchanan 15.09 Trump 12.34 ; proc sort data=PresGreatOrder; by Name; run; proc sort data=PresGreatRank; by Name; run; data PresGreat; merge PresGreatOrder PresGreatRank; by Name; run; proc sort data=PresGreat; by Rank; run; /* use a data attribute map to associate colors with political parties regardless of how the data are sorted. See https://blogs.sas.com/content/iml/2012/10/17/specify-the-colors-of-groups-in-sas-statistical-graphics.html https://blogs.sas.com/content/graphicallyspeaking/2013/04/02/attribute-maps-1/ https://blogs.sas.com/content/graphicallyspeaking/2014/10/19/consistent-group-colors-by-value/ */ data Attrs; length Value $20 LineColor $20; retain ID "PartyAttr" LinePattern "solid" LineThickness 4; input Value $ LineColor $; datalines; Democratic Blue Republican Red Other Gray ; /* This call to PROC SGPLOT uses multiple statements, group processing, and sytle attributes though the DATTRMAP= option. To understand how these various options interact, see https://blogs.sas.com/content/iml/2018/06/13/attrpriority-cycleattrs-styleattrs-ods-graphics.html */ %macro opt(c); filledoutlinedmarkers markerattrs=(symbol=CircleFilled) markerfillattrs=(color=&c) %mend; footnote justify=left "Data from Rottinghaus and Vaughn (2018) Presidential Greatness Survey"; footnote2 justify=left "https://sps.boisestate.edu/politicalscience/files/2018/02/Greatness.pdf"; ods graphics / height=800px width=640 attrpriority=color; title "Ranking of Presidential Greatness"; title2 "By Party Affiliation of Respondent"; proc sgplot data=PresGreat nocycleattrs noautolegend DATTRMAP=Attrs; highlow y=Name low=minParty high=maxParty / group=Party AttrID=PartyAttr name="pres" transparency=0.5; scatter y=Name x=RepRating / name="rep" legendlabel="Republican" %opt(Red); scatter y=Name x=DemRating / name="dem" legendlabel="Democratic" %opt(Blue); scatter y=Name x=IndepRating / name="other" legendlabel="Other" %opt(Gray); scatter y=Name x=MeanRating / name="mean" legendlabel="Overall" markerattrs=(symbol=x color=black size=10px); yaxis reverse discreteorder=data display=(nolabel) labelattrs=(size=6pt) fitpolicy=none colorbands=even colorbandsattrs=(color=gray transparency=0.9) offsetmin=0.011 offsetmax=0.011; /* half of 1/k, where k=number of catgories */ xaxis label="Greatness Ranking (1-100)" min=1 max=100 offsetmin=0 offsetmax=0 grid; keylegend "pres" / title="Party of President" location=inside position=SE across=1 opaque; keylegend "mean" "rep" "other" "dem" / title="Average Ranking" location=inside position=E across=1 opaque; run; title2 "By Political Ideology of Respondent"; proc sgplot data=PresGreat nocycleattrs noautolegend DATTRMAP=Attrs; highlow y=Name low=minIdeo high=maxIdeo / group=Party AttrID=PartyAttr name="pres" transparency=0.5; scatter y=Name x=ConservRating / name="con" legendlabel="Conservative" %opt(Red); scatter y=Name x=LiberalRating / name="lib" legendlabel="Liberal" %opt(Blue); scatter y=Name x=ModerateRating / name="mod" legendlabel="Moderate" %opt(Gray); scatter y=Name x=MeanRating / name="mean" legendlabel="Overall" markerattrs=(symbol=x color=black size=10px); yaxis reverse discreteorder=data display=(nolabel) labelattrs=(size=6pt) fitpolicy=none colorbands=even colorbandsattrs=(color=gray transparency=0.9) offsetmin=0.011 offsetmax=0.011; /* half of 1/k, where k=number of catgories */ xaxis label="Greatness Ranking (1-100)" min=1 max=100 offsetmin=0 offsetmax=0 grid; keylegend "pres" / title="Party of President" location=inside position=SE across=1 opaque; keylegend "mean" "con" "mod" "lib" / title="Average Ranking" location=inside position=E across=1 opaque; run; /* create graph that shows the difference between the mean score of conservative and liberal experts for each president */ proc sort data=PresGreat out=P; by PresNum; run; title "Ideological Bias"; title2 "Difference Between Average Conservative and Liberal Scores"; proc sgplot data=P nocycleattrs noautolegend DATTRMAP=Attrs; highlow y=Name low=gImin high=gIMax / group=Party AttrID=PartyAttr; refline 0 / axis=x; xaxis label="Difference Between Average Scores"; yaxis reverse discreteorder=data display=(nolabel) labelattrs=(size=6pt) fitpolicy=none colorbands=even colorbandsattrs=(color=gray transparency=0.9) offsetmin=0.011 offsetmax=0.011; /* half of 1/k, where k=number of catgories */ run; title;footnote;