Created by: SmirkyGraphs. Code: Github. Source: RI Legislature Site.
Held for Further Study: Where Bills Go to Die¶
Bills in Rhode Island face a big hurdle, making it out of committee and not being "Held for Further Study". Once a bill is introduced and sent to committee, the first vote it recieves is whether or not it should be "Held for Further Study". A bill held for further study is indefinitely postpone, however can be considered again by the committee. Despite the naming, no study actually takes place, and if reintroduced, no study is prestended.
This notebook will take a look at how many bills end up "held for further study" and which chamber they were started in from 2007-2019.
In [1]:
import pandas as pd
import numpy as np
In [2]:
df = pd.read_csv('./data/clean/bill_actions.csv')
# removes resolutions
df = df[~df['bill_id'].str.contains('R')]
# remove duplicate (created when splitting action_type)
df = df.drop_duplicates(subset=(['action', 'lookup_id']))
# adding action_num increments of bill
df['action_num'] = df.groupby('lookup_id').cumcount()
In [3]:
# total bills introduced
total_bills = df['lookup_id'].nunique()
# total bills ever "held for further study"
held_for_study = df[df['type'] == 'held for further study']['lookup_id'].unique().tolist()
# total bills that never left "held for further study"
last_action = df.groupby('lookup_id')['type'].agg('last').reset_index()
last_action = last_action[last_action['type'] == 'held for further study']
died_in_study = last_action['lookup_id'].unique().tolist()
# final calcs
total_held_for_study = int(round(len(held_for_study)/total_bills, 2) * 100)
total_died_held = int(round(len(died_in_study)/len(held_for_study), 2) * 100)
print(f'total held for study: {total_held_for_study}% ({len(held_for_study)})')
print(f'total died held for study: {total_died_held}% ({len(died_in_study)})')
Bills Held & Died for Further Study by Year (Percents Compared to Total Bills)¶
In [4]:
df.loc[df['lookup_id'].isin(died_in_study), 'ended_held_for_study'] = True
df.loc[df['lookup_id'].isin(held_for_study), 'ever_held_for_study'] = True
held = df.drop_duplicates('lookup_id')
held = held.groupby('session')['lookup_id', 'ever_held_for_study', 'ended_held_for_study'].count()
held['percent_ever_held'] = (round(held['ever_held_for_study']/held['lookup_id'], 2)*100).astype(int).astype(str) + '%'
held['percent_ended_held'] = (round(held['ended_held_for_study']/held['lookup_id'], 2)*100).astype(int).astype(str) + '%'
held['x'] = (round(held['ended_held_for_study']/held['ever_held_for_study'], 2)*100).astype(int).astype(str) + '%'
held.columns = ['count_total', 'count_ever_held', 'count_died_held',
'(% total)_ever_held', '(% total)_died_held', '(% held)_died_held']
cols = ['count_total','count_ever_held','(% total)_ever_held','count_died_held','(% total)_died_held', '(% held)_died_held']
held = held.reindex(columns=cols)
held
Out[4]:
Bills Held & Died for Further Study by Year (Seperated by Chamber)¶
In [5]:
chamber = df.drop_duplicates('lookup_id').copy()
chamber.loc[chamber['bill_id'].str.contains('H'), 'chamber_origin'] = 'house'
chamber.loc[chamber['bill_id'].str.contains('S'), 'chamber_origin'] = 'senate'
held = chamber.groupby(['chamber_origin', 'session'])['lookup_id', 'ever_held_for_study', 'ended_held_for_study'].count()
held['percent_ever_held'] = (round(held['ever_held_for_study']/held['lookup_id'], 2)*100).astype(int).astype(str) + '%'
held['percent_ended_held'] = (round(held['ended_held_for_study']/held['lookup_id'], 2)*100).astype(int).astype(str) + '%'
held['x'] = (round(held['ended_held_for_study']/held['ever_held_for_study'], 2)*100).astype(int).astype(str) + '%'
held.columns = ['count_total', 'count_ever_held', 'count_died_held',
'(% total)_ever_held', '(% total)_died_held', '(% held)_died_held']
cols = ['count_total','count_ever_held','(% total)_ever_held','count_died_held','(% total)_died_held', '(% held)_died_held']
held = held.reindex(columns=cols)
held
Out[5]:
Making Extract of Bills Held for Study¶
In [6]:
df = pd.read_csv('./data/clean/bill_actions.csv')
# removes resolutions
df = df[~df['bill_id'].str.contains('R')]
# remove duplicate (created when splitting action_type)
df = df.drop_duplicates(subset=(['action', 'lookup_id']))
# adding action_num increments of bill
df['action_num'] = df.groupby('lookup_id').cumcount()
In [7]:
# creating dataset for held for study tableau sheet
df.loc[df['lookup_id'].isin(died_in_study), 'ended_held_for_study'] = True
df.loc[df['lookup_id'].isin(held_for_study), 'ever_held_for_study'] = True
df = df.fillna(False)
committee = df.groupby('lookup_id')['action'].agg(['first']).reset_index()
committee['first'] = committee['first'].apply(lambda x: x.split(', ')[-1])
committee = committee.rename(columns={'first':'committee'})
df = df.merge(committee, on='lookup_id')
In [8]:
df.to_csv('./data/clean/held_for_study.csv', index=False)