zhoudanxie commited on
Commit
64cb2a0
·
1 Parent(s): 761e2b2

Add CRA filter

Browse files
Files changed (2) hide show
  1. app.py +27 -13
  2. modules/get_resolutions.py +53 -16
app.py CHANGED
@@ -15,7 +15,8 @@ from modules import (
15
  WINDOW_OPEN_DATE,
16
  GET_SIGNIFICANT,
17
  METADATA,
18
- AGENCIES,
 
19
  groupby_agency,
20
  groupby_date,
21
  add_week_info_to_data,
@@ -24,7 +25,7 @@ from modules import (
24
  plot_tf,
25
  plot_NA,
26
  plot_NA,
27
- merge_rd
28
  )
29
 
30
  from shiny import reactive
@@ -65,7 +66,7 @@ sidebar_logo = ui.HTML(
65
  FOOTER = f"""
66
  -----
67
 
68
- © 2024 [GW Regulatory Studies Center](https://go.gwu.edu/regstudies). See our page on the [Congressional Review Act](https://regulatorystudies.columbian.gwu.edu/congressional-review-act) for more information.
69
  """
70
 
71
 
@@ -94,6 +95,10 @@ with ui.sidebar(open={"desktop": "open", "mobile": "closed"}, fg="#033C5A"):
94
  ui.input_select("menu_significant", "Select rule significance", choices=["all", "3f1-significant", "other-significant"], selected="all", multiple=True, size=3)
95
  "Rule significance as defined in Executive Order 12866, as amended by Executive Order 14094."
96
 
 
 
 
 
97
  with ui.tooltip(placement="right", id="agency_tooltip"):
98
  ui.input_select("menu_agency", "Select agencies", choices=["all"] + AGENCIES, selected=["all"], multiple=True, size=6)
99
  "Select one or more parent-level agencies."
@@ -150,7 +155,7 @@ with ui.navset_card_underline(title=""):
150
  "other_significant",
151
  "CRA Target",
152
  "CRA Stage",
153
- "RD Ref & Date",
154
  ]
155
  return render.DataGrid(df.loc[:, [c for c in cols if c in df.columns]], width="100%")
156
 
@@ -199,7 +204,7 @@ with ui.navset_card_underline(title=""):
199
  "other_significant",
200
  "CRA Target",
201
  "CRA Stage",
202
- "RD Ref & Date",
203
  ]
204
  return render.DataTable(grouped.loc[:, [c for c in cols if c in grouped.columns]])
205
 
@@ -232,7 +237,7 @@ with ui.navset_card_underline(title=""):
232
  "other_significant",
233
  "CRA Target",
234
  "CRA Stage",
235
- "RD Ref & Date",
236
  ]
237
  return render.DataTable(grouped.loc[:, [c for c in cols if c in grouped.columns]])
238
 
@@ -265,11 +270,11 @@ with ui.accordion(open=False):
265
  "other_significant",
266
  "CRA Target",
267
  "CRA Stage",
268
- "RD Ref & Date",
269
  "RD Link"
270
  )
271
  ):
272
- filt_df = filtered_df().copy()
273
  filt_df.loc[:, "agencies"] = filt_df.loc[:, "agency_slugs"].apply(lambda x: "; ".join(x))
274
  filt_df.loc[:, "parent_agencies"] = filt_df.loc[:, "parent_slug"].apply(lambda x: "; ".join(x))
275
  filt_df.loc[:, "subagencies"] = filt_df.loc[:, "subagency_slug"].apply(lambda x: "; ".join(x))
@@ -283,10 +288,10 @@ with ui.accordion(open=False):
283
 
284
  ui.markdown(
285
  f"""
286
- The [Congressional Review Act](https://uscode.house.gov/view.xhtml?req=granuleid%3AUSC-prelim-title5-chapter8&saved=%7CKHRpdGxlOjUgc2VjdGlvbjo4MDEgZWRpdGlvbjpwcmVsaW0pIE9SIChncmFudWxlaWQ6VVNDLXByZWxpbS10aXRsZTUtc2VjdGlvbjgwMSk%3D%7CdHJlZXNvcnQ%3D%7C%7C0%7Cfalse%7Cprelim&edition=prelim) (CRA) lookback window refers to the period starting [60 working days](https://crsreports.congress.gov/product/pdf/R/R46690#page=8) (either session days in the Senate or legislative days in the House of Representatives) before the current session of Congress adjourns and ending the day the subsequent session of Congress first convenes.
 
287
  Rules that are published in the Federal Register and submitted to Congress after the lookback day are made available for review in the subsequent session of Congress.
288
  The current lookback date is [August 16, 2024](https://www.congress.gov/congressional-record/volume-171/issue-18/house-section/article/H398-8).
289
- This dashboard allows users to explore how different lookback window dates would affect the set of rules available for congressional review.
290
 
291
  "Section 3(f)(1) significant" rules are regulations that meet the criteria in Section 3(f)(1) of [Executive Order 12866](https://www.archives.gov/files/federal-register/executive-orders/pdf/12866.pdf), as amended by [Executive Order 14094](https://www.govinfo.gov/content/pkg/FR-2023-04-11/pdf/2023-07760.pdf), referring to those with an estimated annual effect on the economy of $200 million or more.
292
  "Other significant" rules are regulations that meet the other criteria in Section 3(f) of Executive Order 12866, as amended by Executive Order 14094, such as those creating inconsistency with other agencies' actions, altering certain budgetary impacts, or raising legal or policy issues pertaining to the president's priorities.
@@ -309,7 +314,7 @@ def filtered_df(agency_column: str = "parent_slug"):
309
  filt_df = DF
310
 
311
  # merge with RD data
312
- filt_df=merge_rd(filt_df)
313
 
314
  # filter dates
315
  try:
@@ -322,7 +327,16 @@ def filtered_df(agency_column: str = "parent_slug"):
322
  if (input.menu_agency() is not None) and ("all" not in input.menu_agency()):
323
  bool_agency = [True if sum(selected in agency for selected in input.menu_agency()) > 0 else False for agency in filt_df[agency_column]]
324
  filt_df = filt_df.loc[bool_agency]
325
-
 
 
 
 
 
 
 
 
 
326
  # return filtered dataframe
327
  return filt_df
328
 
@@ -392,7 +406,7 @@ def grouped_df_week():
392
 
393
  @reactive.calc
394
  def grouped_df_agency():
395
- filt_df = filter_significance()
396
  grouped = groupby_agency(filt_df, metadata=METADATA, significant=GET_SIGNIFICANT)
397
  return grouped
398
 
 
15
  WINDOW_OPEN_DATE,
16
  GET_SIGNIFICANT,
17
  METADATA,
18
+ AGENCIES,
19
+ CRA_LAST_UPDATED,
20
  groupby_agency,
21
  groupby_date,
22
  add_week_info_to_data,
 
25
  plot_tf,
26
  plot_NA,
27
  plot_NA,
28
+ get_rd
29
  )
30
 
31
  from shiny import reactive
 
66
  FOOTER = f"""
67
  -----
68
 
69
+ © {date.today().year} [GW Regulatory Studies Center](https://go.gwu.edu/regstudies). See our page on the [Congressional Review Act](https://regulatorystudies.columbian.gwu.edu/congressional-review-act) for more information.
70
  """
71
 
72
 
 
95
  ui.input_select("menu_significant", "Select rule significance", choices=["all", "3f1-significant", "other-significant"], selected="all", multiple=True, size=3)
96
  "Rule significance as defined in Executive Order 12866, as amended by Executive Order 14094."
97
 
98
+ with ui.tooltip(placement="right", id="cra_tooltip"):
99
+ ui.input_select("menu_cra_target", "Select CRA target status", choices=["all", "CRA targeted", "Not CRA targeted"], selected="all", multiple=True, size=3)
100
+ f"Whether a rule has been targeted in a joint resolution (RD) for congressional disapproval (data last updated {CRA_LAST_UPDATED})."
101
+
102
  with ui.tooltip(placement="right", id="agency_tooltip"):
103
  ui.input_select("menu_agency", "Select agencies", choices=["all"] + AGENCIES, selected=["all"], multiple=True, size=6)
104
  "Select one or more parent-level agencies."
 
155
  "other_significant",
156
  "CRA Target",
157
  "CRA Stage",
158
+ "RD No. & Date",
159
  ]
160
  return render.DataGrid(df.loc[:, [c for c in cols if c in df.columns]], width="100%")
161
 
 
204
  "other_significant",
205
  "CRA Target",
206
  "CRA Stage",
207
+ "RD No. & Date",
208
  ]
209
  return render.DataTable(grouped.loc[:, [c for c in cols if c in grouped.columns]])
210
 
 
237
  "other_significant",
238
  "CRA Target",
239
  "CRA Stage",
240
+ "RD No. & Date",
241
  ]
242
  return render.DataTable(grouped.loc[:, [c for c in cols if c in grouped.columns]])
243
 
 
270
  "other_significant",
271
  "CRA Target",
272
  "CRA Stage",
273
+ "RD No. & Date",
274
  "RD Link"
275
  )
276
  ):
277
+ filt_df = filter_significance().copy()
278
  filt_df.loc[:, "agencies"] = filt_df.loc[:, "agency_slugs"].apply(lambda x: "; ".join(x))
279
  filt_df.loc[:, "parent_agencies"] = filt_df.loc[:, "parent_slug"].apply(lambda x: "; ".join(x))
280
  filt_df.loc[:, "subagencies"] = filt_df.loc[:, "subagency_slug"].apply(lambda x: "; ".join(x))
 
288
 
289
  ui.markdown(
290
  f"""
291
+ This dashboard allows users to explore how different [Congressional Review Act](https://uscode.house.gov/view.xhtml?req=granuleid%3AUSC-prelim-title5-chapter8&saved=%7CKHRpdGxlOjUgc2VjdGlvbjo4MDEgZWRpdGlvbjpwcmVsaW0pIE9SIChncmFudWxlaWQ6VVNDLXByZWxpbS10aXRsZTUtc2VjdGlvbjgwMSk%3D%7CdHJlZXNvcnQ%3D%7C%7C0%7Cfalse%7Cprelim&edition=prelim) (CRA) lookback window dates would affect the set of rules available for congressional review and tracks resolutions for disapproval targeting the rules published within this window.
292
+ The “lookback window” refers to the period starting [60 working days](https://crsreports.congress.gov/product/pdf/R/R46690#page=8) (either session days in the Senate or legislative days in the House of Representatives) before the current session of Congress adjourns and ending the day the subsequent session of Congress first convenes.
293
  Rules that are published in the Federal Register and submitted to Congress after the lookback day are made available for review in the subsequent session of Congress.
294
  The current lookback date is [August 16, 2024](https://www.congress.gov/congressional-record/volume-171/issue-18/house-section/article/H398-8).
 
295
 
296
  "Section 3(f)(1) significant" rules are regulations that meet the criteria in Section 3(f)(1) of [Executive Order 12866](https://www.archives.gov/files/federal-register/executive-orders/pdf/12866.pdf), as amended by [Executive Order 14094](https://www.govinfo.gov/content/pkg/FR-2023-04-11/pdf/2023-07760.pdf), referring to those with an estimated annual effect on the economy of $200 million or more.
297
  "Other significant" rules are regulations that meet the other criteria in Section 3(f) of Executive Order 12866, as amended by Executive Order 14094, such as those creating inconsistency with other agencies' actions, altering certain budgetary impacts, or raising legal or policy issues pertaining to the president's priorities.
 
314
  filt_df = DF
315
 
316
  # merge with RD data
317
+ filt_df = get_rd(filt_df)
318
 
319
  # filter dates
320
  try:
 
327
  if (input.menu_agency() is not None) and ("all" not in input.menu_agency()):
328
  bool_agency = [True if sum(selected in agency for selected in input.menu_agency()) > 0 else False for agency in filt_df[agency_column]]
329
  filt_df = filt_df.loc[bool_agency]
330
+
331
+ # filter CRA target status
332
+ bool_cra = []
333
+ if (input.menu_cra_target() is not None) and ("all" not in input.menu_cra_target()):
334
+ if "CRA targeted" in input.menu_cra_target():
335
+ bool_cra.append((filt_df["CRA Target"] == 1).to_numpy())
336
+ if "Not CRA targeted" in input.menu_cra_target():
337
+ bool_cra.append((filt_df["CRA Target"] == 0).to_numpy())
338
+ filt_df = filt_df.loc[array(bool_cra).any(axis=0)]
339
+
340
  # return filtered dataframe
341
  return filt_df
342
 
 
406
 
407
  @reactive.calc
408
  def grouped_df_agency():
409
+ filt_df=filter_significance()
410
  grouped = groupby_agency(filt_df, metadata=METADATA, significant=GET_SIGNIFICANT)
411
  return grouped
412
 
modules/get_resolutions.py CHANGED
@@ -1,13 +1,15 @@
1
  import pandas as pd
 
 
2
 
3
- # Define RD stages
4
- rd_stages={0:'Introduced',
5
- 1:'Passed one chamber',
6
- 2:'Passed two chambers',
7
- 3:'Became law',
8
- 4:'Vetoed by president'}
9
 
10
- # Function to read and clean CRA RD data set
11
  def read_cra_data(file_path):
12
 
13
  # Import CRA data set
@@ -16,6 +18,9 @@ def read_cra_data(file_path):
16
  # Refine dataframe
17
  df_rd=df_rd[['rd','introdate','rd_link','ridentifier','rin','introducedbin','chamberpass_atleast1','chamberpass_2','becamelawbin','vetobin']]
18
 
 
 
 
19
  # Define RD status variable
20
  df_rd['rd_status']=df_rd[['chamberpass_atleast1','chamberpass_2','becamelawbin','vetobin']].sum(axis=1)
21
 
@@ -30,27 +35,59 @@ def read_cra_data(file_path):
30
 
31
  # Rename columns
32
  df_rd.rename(columns={'ridentifier':'citation','introducedbin':'CRA Target',
33
- 'rd_status':'CRA Stage','rd_date': 'RD Ref & Date','rd_link':'RD Link'},inplace=True)
34
 
35
  # Replace RD stage values
36
  df_rd['CRA Stage'] = df_rd['CRA Stage'].replace(rd_stages)
37
 
38
- return df_rd
 
 
 
 
 
 
 
 
39
 
40
- #%% Merge with FR data set
41
- def merge_rd(df_fr):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  # Read CRA data set
43
  cra_file_path='congress_data\cra_data.csv'
44
- df_rd=read_cra_data(cra_file_path)
45
- # print(df_rd.head())
46
 
47
  # Merge
48
  df_merged=df_fr.merge(df_rd,on='citation',how='left')
49
 
50
- # Fill in null
51
  df_merged['CRA Target']=df_merged['CRA Target'].fillna(0)
52
 
53
  return df_merged
54
 
55
- #%%
56
- # merge_rd()
 
 
 
 
 
 
 
 
 
 
 
1
  import pandas as pd
2
+ import subprocess
3
+ import datetime
4
 
5
+ #%% Define RD stages
6
+ rd_stages={0:'RD Introduced',
7
+ 1:'RD Passed One Chamber',
8
+ 2:'RD Passed Two Chambers',
9
+ 3:'RD Became Law',
10
+ 4:'RD Vetoed by President'}
11
 
12
+ #%% Function to read and clean CRA RD dataset
13
  def read_cra_data(file_path):
14
 
15
  # Import CRA data set
 
18
  # Refine dataframe
19
  df_rd=df_rd[['rd','introdate','rd_link','ridentifier','rin','introducedbin','chamberpass_atleast1','chamberpass_2','becamelawbin','vetobin']]
20
 
21
+ # Get the latest RD intro date
22
+ last_rd_date=max(df_rd['introdate'].astype('datetime64[ns]'))
23
+
24
  # Define RD status variable
25
  df_rd['rd_status']=df_rd[['chamberpass_atleast1','chamberpass_2','becamelawbin','vetobin']].sum(axis=1)
26
 
 
35
 
36
  # Rename columns
37
  df_rd.rename(columns={'ridentifier':'citation','introducedbin':'CRA Target',
38
+ 'rd_status':'CRA Stage','rd_date': 'RD No. & Date','rd_link':'RD Link'},inplace=True)
39
 
40
  # Replace RD stage values
41
  df_rd['CRA Stage'] = df_rd['CRA Stage'].replace(rd_stages)
42
 
43
+ return df_rd, last_rd_date
44
+
45
+ #%% Function to get last modified date of a file
46
+ def get_last_modified_date(file_path):
47
+ """
48
+ Retrieves the last modified date of a file in Git.
49
+
50
+ Args:
51
+ file_path (str): The path to the file.
52
 
53
+ Returns:
54
+ datetime: A datetime object representing the last modified date, or None if an error occurs.
55
+ """
56
+ try:
57
+ # Execute git log command to get the latest commit information for the file
58
+ result = subprocess.run(['git', 'log', '-n', '1', '--pretty=format:%at', '--', file_path], capture_output=True, text=True, check=True)
59
+ timestamp = int(result.stdout.strip())
60
+ return datetime.datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d")
61
+ except subprocess.CalledProcessError as e:
62
+ print(f"Error: {e}")
63
+ return None
64
+ except ValueError:
65
+ print(f"Error: Could not parse timestamp from git log output.")
66
+ return None
67
+
68
+ #%% Function to merge RD data with FR data
69
+ def get_rd(df_fr):
70
  # Read CRA data set
71
  cra_file_path='congress_data\cra_data.csv'
72
+ df_rd,_=read_cra_data(cra_file_path)
 
73
 
74
  # Merge
75
  df_merged=df_fr.merge(df_rd,on='citation',how='left')
76
 
77
+ # Fill null
78
  df_merged['CRA Target']=df_merged['CRA Target'].fillna(0)
79
 
80
  return df_merged
81
 
82
+ #%% Function to get last modified date of the RD dataset
83
+ def get_cra_updated_date(cra_file_path='congress_data\cra_data.csv'):
84
+ cra_last_updated = get_last_modified_date(cra_file_path)
85
+
86
+ if cra_last_updated:
87
+ return cra_last_updated
88
+ else:
89
+ _,last_rd_date=read_cra_data(cra_file_path)
90
+ return last_rd_date.strftime("%Y-%m-%d")
91
+
92
+ #%% Create objects to import in app
93
+ CRA_LAST_UPDATED=get_cra_updated_date()