The Supreme Court of the United States is the highest court in the federal justiciary of the USA. One of its powers is that of judicial review, the ability to invalidate a statute for violating the constitution. Keith Whittington of Princeton University has created the Judicial Review of Congress Database which contains a comprehensive list of cases where the court has decided the validity of a federal law. In this edition of Free Data Friday, we will be looking at this data to see if we can identify any trends in the courts tendency to overrule Congress and to see if the court is taking longer to reach a decision than it did in previous years.
The data is available for download as an Excel file and was uploaded to SAS OnDemand for Academics in that same format.
I used the XLSX libname engine to read the data and then a simple data step to create a “real” SAS data set keeping only a few of the many variables in the Excel workbook. In addition I recoded the data in the effect variable to create just two values – Upheld and Struck Down.
libname xl xlsx "/home/chris52brooks/SCCases/judicial_review_of_congress_database_1789-2018.xlsx";
data cases;
set xl.sheet1(keep=year effect "time to decision"n);
if find(effect,"struck down") then effect="Struck Down";
else effect="Upheld";
run;
This is what the first few rows of the abbreviated file look like
Firstly, I used Proc Freq to create a count of the total number of each case outcome type for each year in the database. One point to note is that I used the Sparse option to ensure a row for each outcome for every year, inserting zeros if there were no outcomes of that type in the year.
proc freq data=cases;
tables year*effect / noprint sparse out=freqcount;
run;
This gives me a file looking like this
In order to display the results, I decided to use Proc Template to create a reusable template which I could use for both analyses that I was interested in doing. This poses an issue in that different variables and chart titles will need to be used. This is resolved by using what are called Dynamics - these are essentially parameters which can be passed into the template by Proc SGRender. They must be declared in the Proc Template code and the resulting template variables can then be used in the rest of the procedure. Here I have created Dynamics called etitle2 (to represent the second level of graph title), yvar and ylabel (for the variable and label to be used on the graphs Y axis).
proc template;
define statgraph scourtgraph;
dynamic etitle2 yvar ylabel;
begingraph;
entrytitle "The Supreme Court v Congress";
entryfootnote halign=left "Data From: The Judicial Review of Congress Database";
entrytitle etitle2;
layout overlay /xaxisopts=(griddisplay=on) yaxisopts=(griddisplay=on label=ylabel);
seriesplot x=year y=yvar / group=effect name='serplot';
discretelegend 'serplot' /title='Result' location=outside;
endlayout;
endgraph;
end;
run;
Having created my template I then used Proc SGRender with the Dynamic statement to assign values to the variables in the template.
proc sgrender data=freqcount template=scourtgraph;
dynamic yvar='count' etitle2='No. of Cases Upheld v Those Overruled' ylabel='No of Cases';
run;
We can see from the resulting graph that there was a sharp increase in the number of these cases referred to the court during the 20th century, falling off again during the early years of the current century. However, this increase in referrals does not seem to mean that the court was significantly more likely to overturn congress. On the contrary the number of such instances rises only slightly while the number of cases where the statute was upheld increased significantly. However, there are signs in recent years of a move back towards a situation which is more 50/50 in terms of overruled and upheld cases. It will be interesting to see if this situation persists.
Moving to my second analyses it has been said that “Justice delayed is justice denied” and so I wanted to see if the court has become slower in its deliberations over time. I used a simple piece of Proc SQL to create a data set showing the yearly average of time to completion for all cases concluded in that year.
proc sql;
create table length
as select distinct(year),
avg("time to decision"n) as des_time
from cases
group by year
order by year asc;
quit;
I then used Proc SGRender with the same template I used earlier but this time passing different values in forn the dynamics.
proc sgrender data=length template=scourtgraph;
dynamic yvar='des_time' etitle2='Time to Reach a Decision' ylabel='No of Days';
label des_time='Time to Reach a Decision';
run;
We can see here that the court has reduced the amount of time it takes to reach a decision from the mid-nineteenth century onwards. There was a significant spike in 2017 but examining the data reveals this was due to a couple of extremely long cases and may be regarded as something of an outlier.
There are many other interesting variables in the database with numerous avenues for exploration. Why not download the data and check it out in SAS OnDemand for Academics?
Keith E. Whittington, The Judicial Review of Congress Database (May 2019) (available at https://scholar.princeton.edu/kewhitt/judicial-review-congress-database)
Did you find something else interesting in this data? Share in the comments. I’m glad to answer any questions.
Hit the orange button below to see all the Free Data Friday articles.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning and boost your career prospects.