ltc-code 0.2.16__tar.gz → 0.2.18__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ltc_code-0.2.16 → ltc_code-0.2.18}/PKG-INFO +1 -1
- {ltc_code-0.2.16 → ltc_code-0.2.18}/pyproject.toml +1 -1
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/build_nsc_outcomes.py +167 -56
- ltc_code-0.2.18/src/ltc_code/nsc/raw/ipeds_data.dta +0 -0
- ltc_code-0.2.16/src/ltc_code/.DS_Store +0 -0
- ltc_code-0.2.16/src/ltc_code/nsc/.DS_Store +0 -0
- ltc_code-0.2.16/src/ltc_code/nsc/raw/.DS_Store +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/README.md +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/aspire.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/check_cmo_apps.do +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/christel_house.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/democracy_prep.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/green_dot.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/helpers.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/ilt.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/kipp_nj.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/main.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/mappings.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/rocketship.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/yes_prep.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260630_census_disclosure/aspire.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260630_census_disclosure/christel_house.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260630_census_disclosure/democracy_prep.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260630_census_disclosure/green_dot.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260630_census_disclosure/ilt.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260630_census_disclosure/kipp.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260630_census_disclosure/kipp_nj.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260630_census_disclosure/rocketship.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260630_census_disclosure/yes_prep.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260706_ceprscripts/BALANCE.do +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260706_ceprscripts/FS.do +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260706_ceprscripts/ITT.do +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260706_ceprscripts/TOT.do +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260706_ceprscripts/apps_helpers.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260706_ceprscripts/harmony.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260706_ceprscripts/main.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260712_uncommon_scripts/main.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260712_uncommon_scripts/mappings.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260712_uncommon_scripts/uncommon.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/__init__.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/aspire.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/check_cmo_apps.do +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/christel_house.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/green_dot.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/helpers.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/june13.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/june2.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/june30.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/june5.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/june7.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/kipp_nj.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/kipp_tx.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/main.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/mappings.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/may27.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/__init__.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/input/.gitkeep +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/naics.csv +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/naics.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/naics_raw.xlsx +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/output/.gitkeep +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/raw/CREDENTIAL_LEVEL_LOOKUP_TABLE.xlsx +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/raw/IPEDS_IC_2013.csv +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/raw/IPEDS_IC_manual.xlsx +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/raw/chetty/mrc_table11.dta +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/raw/chetty/mrc_table2.dta +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/raw/college_crosswalk.xls +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/raw/directory.dta +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/nsc/run_nsc_outcomes.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/polars_dates.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/rocketship.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/schema_mapping.py +0 -0
- {ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/yes_prep.py +0 -0
|
@@ -54,24 +54,24 @@ CHETTY_MRC_TABLE11 = next(
|
|
|
54
54
|
)
|
|
55
55
|
# Chetty OPE-to-super-OPE crosswalk used to attach tier to NSC schools.
|
|
56
56
|
|
|
57
|
+
IPEDS_DATA = RAW_NSC / "ipeds_data.dta"
|
|
58
|
+
# Institution-level IPEDS outcomes, including completion within 150% of normal time.
|
|
59
|
+
|
|
57
60
|
INPUT_NSC = PACKAGE_NSC / "input"
|
|
58
61
|
# Folder for secured Census inputs that are not packaged with the code.
|
|
59
62
|
|
|
63
|
+
OUTPUT_NSC = PACKAGE_NSC / "output"
|
|
64
|
+
# Folder for final student-level NSC outcomes.
|
|
65
|
+
|
|
60
66
|
APPS = INPUT_NSC / "apps.csv"
|
|
61
67
|
# Application/student records; source for unique sid_cepr/cohort_lottery.
|
|
62
68
|
|
|
63
|
-
NSC_RECORDS = INPUT_NSC / "nsc_records.csv"
|
|
64
|
-
# Long NSC enrollment and degree records.
|
|
65
|
-
|
|
66
69
|
INPUT_NSC_OLD = INPUT_NSC / "nsc_records_old.dta"
|
|
67
70
|
# Older NSC pull, kept so the build can append old and new NSC versions.
|
|
68
71
|
|
|
69
|
-
INPUT_NSC_NEW = INPUT_NSC / "nsc_records_new.
|
|
72
|
+
INPUT_NSC_NEW = INPUT_NSC / "nsc_records_new.csv"
|
|
70
73
|
# Newer NSC pull with studyid-based rows.
|
|
71
74
|
|
|
72
|
-
OUTPUT_NSC = PACKAGE_NSC / "output"
|
|
73
|
-
# Package-local output folder for NSC outcome files.
|
|
74
|
-
|
|
75
75
|
OUTCOMES = OUTPUT_NSC / "nsc_outcomes.parquet"
|
|
76
76
|
# Final student-level NSC outcomes file.
|
|
77
77
|
|
|
@@ -99,17 +99,13 @@ college_crosswalk = (
|
|
|
99
99
|
columns=["ID_IPEDS", "ID_OPE", "ID_FSC", "ID_FSC_long", "name"],
|
|
100
100
|
)
|
|
101
101
|
.with_columns(
|
|
102
|
-
pl.
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
.when(pl.col("ID_FSC").is_not_null())
|
|
108
|
-
.then(
|
|
109
|
-
pl.col("ID_FSC").cast(pl.String).str.strip_chars().str.replace(r"\.0$", "")
|
|
110
|
-
+ pl.lit("-00")
|
|
102
|
+
pl.coalesce(
|
|
103
|
+
[
|
|
104
|
+
pl.col("ID_FSC_long").cast(pl.String).str.strip_chars(),
|
|
105
|
+
pl.col("ID_FSC").cast(pl.String).str.strip_chars() + pl.lit("-00")
|
|
106
|
+
]
|
|
111
107
|
)
|
|
112
|
-
.
|
|
108
|
+
.str.replace(r"\.0$", "")
|
|
113
109
|
.alias("ID_FSC"),
|
|
114
110
|
pl.col("ID_IPEDS").cast(pl.Int64, strict=False).alias("unitid"),
|
|
115
111
|
pl.col("ID_OPE").cast(pl.Int64, strict=False),
|
|
@@ -231,24 +227,32 @@ directory = (
|
|
|
231
227
|
.select("unitid", "college_name_directory", "years_directory", "ownership_directory")
|
|
232
228
|
)
|
|
233
229
|
|
|
234
|
-
# Chetty
|
|
235
|
-
# to those
|
|
236
|
-
|
|
230
|
+
# Chetty college outcomes are keyed at super-OPE level. Table 11 maps school
|
|
231
|
+
# OPE IDs to those groups, which is the same route Sarah's Stata code uses.
|
|
232
|
+
chetty_college_outcomes = (
|
|
237
233
|
scan_readstat(
|
|
238
234
|
CHETTY_MRC_TABLE2,
|
|
239
235
|
missing_string_as_null=True,
|
|
240
236
|
value_labels_as_strings=False,
|
|
241
237
|
)
|
|
242
|
-
.select("super_opeid", "tier", "tier_name")
|
|
238
|
+
.select("super_opeid", "tier", "tier_name", "k_mean")
|
|
243
239
|
.collect()
|
|
244
240
|
.with_columns(
|
|
245
241
|
pl.col("super_opeid").cast(pl.Int64, strict=False),
|
|
246
242
|
pl.col("tier").cast(pl.Int8, strict=False),
|
|
243
|
+
pl.col("k_mean").cast(pl.Float64, strict=False),
|
|
247
244
|
)
|
|
248
245
|
.drop_nulls("super_opeid")
|
|
249
246
|
.unique("super_opeid", keep="first")
|
|
250
247
|
)
|
|
251
248
|
|
|
249
|
+
k_mean_neverattend = chetty_college_outcomes.filter(
|
|
250
|
+
pl.col("super_opeid") == -99
|
|
251
|
+
).item(0, "k_mean")
|
|
252
|
+
k_mean_insuffdata = chetty_college_outcomes.filter(
|
|
253
|
+
pl.col("super_opeid") == -1
|
|
254
|
+
).item(0, "k_mean")
|
|
255
|
+
|
|
252
256
|
chetty_ope_crosswalk = (
|
|
253
257
|
scan_readstat(
|
|
254
258
|
CHETTY_MRC_TABLE11,
|
|
@@ -265,10 +269,30 @@ chetty_ope_crosswalk = (
|
|
|
265
269
|
)
|
|
266
270
|
|
|
267
271
|
chetty_by_opeid = (
|
|
268
|
-
chetty_ope_crosswalk.join(
|
|
272
|
+
chetty_ope_crosswalk.join(
|
|
273
|
+
chetty_college_outcomes, on="super_opeid", how="left"
|
|
274
|
+
)
|
|
269
275
|
.unique("opeid", keep="first")
|
|
270
276
|
)
|
|
271
277
|
|
|
278
|
+
# IPEDS reports completion within 150% of normal time: six years at four-year
|
|
279
|
+
# colleges and three years at two-year colleges.
|
|
280
|
+
ipeds_completion = (
|
|
281
|
+
scan_readstat(
|
|
282
|
+
IPEDS_DATA,
|
|
283
|
+
missing_string_as_null=True,
|
|
284
|
+
value_labels_as_strings=False,
|
|
285
|
+
)
|
|
286
|
+
.select("unitid", "completion_rate_150pct_ip")
|
|
287
|
+
.collect()
|
|
288
|
+
.with_columns(
|
|
289
|
+
pl.col("unitid").cast(pl.Int64, strict=False),
|
|
290
|
+
pl.col("completion_rate_150pct_ip").cast(pl.Float64, strict=False),
|
|
291
|
+
)
|
|
292
|
+
.drop_nulls("unitid")
|
|
293
|
+
.unique("unitid", keep="first")
|
|
294
|
+
)
|
|
295
|
+
|
|
272
296
|
|
|
273
297
|
###########################################################
|
|
274
298
|
# Build college reference data
|
|
@@ -280,6 +304,7 @@ college_ref = (
|
|
|
280
304
|
.join(ipeds_manual, on="unitid", how="left")
|
|
281
305
|
.join(directory, on="unitid", how="left")
|
|
282
306
|
.join(chetty_by_opeid, on="opeid", how="left", validate="m:1")
|
|
307
|
+
.join(ipeds_completion, on="unitid", how="left", validate="m:1")
|
|
283
308
|
.with_columns(
|
|
284
309
|
pl.coalesce(
|
|
285
310
|
[
|
|
@@ -318,8 +343,6 @@ college_ref = (
|
|
|
318
343
|
"ID_FSC",
|
|
319
344
|
"unitid",
|
|
320
345
|
"ID_OPE",
|
|
321
|
-
"opeid",
|
|
322
|
-
"super_opeid",
|
|
323
346
|
"college_name",
|
|
324
347
|
"college_years",
|
|
325
348
|
"college_ownership",
|
|
@@ -327,9 +350,9 @@ college_ref = (
|
|
|
327
350
|
"college_4yr",
|
|
328
351
|
"college_2yr",
|
|
329
352
|
"tier",
|
|
330
|
-
"tier_name",
|
|
331
|
-
"superopeid_name",
|
|
332
353
|
"college_elite",
|
|
354
|
+
"k_mean",
|
|
355
|
+
"completion_rate_150pct_ip",
|
|
333
356
|
)
|
|
334
357
|
)
|
|
335
358
|
|
|
@@ -340,22 +363,25 @@ college_ref = (
|
|
|
340
363
|
|
|
341
364
|
# Start from unique students. cohort_lottery is the birth cohort; cohort_18 is
|
|
342
365
|
# the year the student turns 18 and anchors Sarah's Y1/Y2/... outcome windows.
|
|
343
|
-
|
|
344
|
-
apps_raw = scan_readstat(
|
|
345
|
-
APPS, missing_string_as_null=True, value_labels_as_strings=True
|
|
346
|
-
).collect()
|
|
347
|
-
else:
|
|
348
|
-
apps_raw = pl.read_csv(APPS)
|
|
366
|
+
|
|
349
367
|
|
|
350
368
|
apps = (
|
|
351
|
-
|
|
369
|
+
scan_readstat(
|
|
370
|
+
APPS, missing_string_as_null=True, value_labels_as_strings=True
|
|
371
|
+
)
|
|
372
|
+
.select("sid_cepr", "cohort_lottery")
|
|
352
373
|
.drop_nulls(["sid_cepr", "cohort_lottery"])
|
|
353
374
|
.with_columns(
|
|
354
375
|
pl.col("sid_cepr").cast(pl.Int64),
|
|
355
376
|
pl.col("cohort_lottery").cast(pl.Int64),
|
|
356
377
|
)
|
|
357
|
-
.
|
|
378
|
+
.filter(
|
|
379
|
+
pl.col("cohort_lottery").is_between(1990, 2005)
|
|
380
|
+
)
|
|
381
|
+
.sort("cohort_lottery")
|
|
382
|
+
.unique(["sid_cepr"])
|
|
358
383
|
.with_columns((pl.col("cohort_lottery") + 18).alias("cohort_18"))
|
|
384
|
+
.collect()
|
|
359
385
|
)
|
|
360
386
|
|
|
361
387
|
# These branch-code fixes mirror the Sarah code path that maps known bad FSC
|
|
@@ -441,7 +467,11 @@ fsc_branch_fixes = [
|
|
|
441
467
|
# The real NSC file uses raw NSC names; Sarah renames these before building
|
|
442
468
|
# outcomes. This block makes those same names explicit in Polars.
|
|
443
469
|
nsc_old = (
|
|
444
|
-
scan_readstat(INPUT_NSC_OLD, missing_string_as_null=True, value_labels_as_strings=True
|
|
470
|
+
scan_readstat(INPUT_NSC_OLD, missing_string_as_null=True, value_labels_as_strings=True, schema_overrides={
|
|
471
|
+
"searchdate": pl.String
|
|
472
|
+
}
|
|
473
|
+
)
|
|
474
|
+
.collect()
|
|
445
475
|
.with_columns(
|
|
446
476
|
pl.lit(2023).alias("NSCdatayear"),
|
|
447
477
|
|
|
@@ -450,11 +480,41 @@ nsc_old = (
|
|
|
450
480
|
.cast(pl.Int32)
|
|
451
481
|
.alias("searchbeginyear")
|
|
452
482
|
)
|
|
453
|
-
.collect()
|
|
454
483
|
)
|
|
455
484
|
|
|
456
485
|
nsc_new = (
|
|
457
|
-
|
|
486
|
+
pl.scan_csv(INPUT_NSC_NEW, infer_schema=False, null_values=[""], try_parse_dates=False, ignore_errors=False,)
|
|
487
|
+
.rename({
|
|
488
|
+
"Study ID": "studyid",
|
|
489
|
+
"Record Found Y/N": "recordfoundyn",
|
|
490
|
+
"College Code/Branch": "collegecodebranch",
|
|
491
|
+
"College Name": "collegename",
|
|
492
|
+
"College State": "collegestate",
|
|
493
|
+
"2-year / 4-year": "2year4year",
|
|
494
|
+
"Public / Private": "publicprivate",
|
|
495
|
+
"Enrollment Begin": "enrollmentbegin",
|
|
496
|
+
"Enrollment End": "enrollmentend",
|
|
497
|
+
"Enrollment Status": "enrollmentstatus",
|
|
498
|
+
"Class Level": "classlevel",
|
|
499
|
+
"Enrollment Major 1": "enrollmentmajor1",
|
|
500
|
+
"Enrollment CIP 1": "enrollmentcip1",
|
|
501
|
+
"Enrollment Major 2": "enrollmentmajor2",
|
|
502
|
+
"Enrollment CIP 2": "enrollmentcip2",
|
|
503
|
+
"Graduated?": "graduated",
|
|
504
|
+
"Graduation Date": "graduationdate",
|
|
505
|
+
"Degree Title": "degreetitle",
|
|
506
|
+
"Degree Major 1": "degreemajor1",
|
|
507
|
+
"Degree CIP 1": "degreecip1",
|
|
508
|
+
"Degree Major 2": "degreemajor2",
|
|
509
|
+
"Degree CIP 2": "degreecip2",
|
|
510
|
+
"Degree Major 3": "degreemajor3",
|
|
511
|
+
"Degree CIP 3": "degreecip3",
|
|
512
|
+
"Degree Major 4": "degreemajor4",
|
|
513
|
+
"Degree CIP 4": "degreecip4",
|
|
514
|
+
"College Sequence": "collegesequence",
|
|
515
|
+
"Student Age at start of term": "studentageatstartofterm",
|
|
516
|
+
|
|
517
|
+
})
|
|
458
518
|
.with_row_index("origsrt", offset=1)
|
|
459
519
|
.filter(pl.col("studyid").is_not_null())
|
|
460
520
|
.with_columns(
|
|
@@ -463,7 +523,7 @@ nsc_new = (
|
|
|
463
523
|
.explode("sid_cepr")
|
|
464
524
|
.filter(pl.col("sid_cepr") != "")
|
|
465
525
|
.with_columns(
|
|
466
|
-
pl.col("sid_cepr").cast(pl.Int64, strict=False)
|
|
526
|
+
pl.col("sid_cepr").cast(pl.String).str.replace_all("_", "").cast(pl.Int64, strict=False)
|
|
467
527
|
)
|
|
468
528
|
.filter(
|
|
469
529
|
pl.col("sid_cepr").is_not_null()
|
|
@@ -706,6 +766,8 @@ enroll_weeks = (
|
|
|
706
766
|
"college_2yr",
|
|
707
767
|
"tier",
|
|
708
768
|
"college_elite",
|
|
769
|
+
"k_mean",
|
|
770
|
+
"completion_rate_150pct_ip",
|
|
709
771
|
"term_start_date",
|
|
710
772
|
"term_end_date",
|
|
711
773
|
"week_start",
|
|
@@ -763,6 +825,8 @@ enroll = (
|
|
|
763
825
|
pl.col("college_2yr").max(),
|
|
764
826
|
pl.col("tier").drop_nulls().min(),
|
|
765
827
|
pl.col("college_elite").max(),
|
|
828
|
+
pl.col("k_mean").drop_nulls().first(),
|
|
829
|
+
pl.col("completion_rate_150pct_ip").drop_nulls().first(),
|
|
766
830
|
pl.col("_term_att").max(),
|
|
767
831
|
pl.col("week").min().alias("week_start"),
|
|
768
832
|
pl.col("week").max().alias("week_end"),
|
|
@@ -867,9 +931,20 @@ first_institution = (
|
|
|
867
931
|
.first()
|
|
868
932
|
.alias("college_name_firstinst"),
|
|
869
933
|
pl.col("college_years").first().alias("college_years_firstinst"),
|
|
934
|
+
pl.col("k_mean").first().alias("k_mean_firstinst"),
|
|
935
|
+
pl.col("completion_rate_150pct_ip")
|
|
936
|
+
.first()
|
|
937
|
+
.alias("completion_rate_150pct_firstinst"),
|
|
870
938
|
)
|
|
871
939
|
)
|
|
872
940
|
|
|
941
|
+
first_institution = first_institution.with_columns(
|
|
942
|
+
pl.col("k_mean_firstinst")
|
|
943
|
+
.fill_null(k_mean_insuffdata)
|
|
944
|
+
.alias("k_mean"),
|
|
945
|
+
pl.col("completion_rate_150pct_firstinst").alias("predicted_completion"),
|
|
946
|
+
)
|
|
947
|
+
|
|
873
948
|
enrollment_outcomes = enrollment_outcomes.join(
|
|
874
949
|
first_institution, on="sid_cepr", how="left"
|
|
875
950
|
)
|
|
@@ -920,6 +995,7 @@ degree_title = pl.col("_degree_title_clean").fill_null("")
|
|
|
920
995
|
degrees = (
|
|
921
996
|
nsc.filter(pl.col("graduated") == "Y")
|
|
922
997
|
.filter(pl.col("graduated_date").is_not_null())
|
|
998
|
+
.filter(pl.col("graduated_date") <= NSC_CUTOFF_DATE)
|
|
923
999
|
.with_columns(
|
|
924
1000
|
pl.col("degree_title")
|
|
925
1001
|
.cast(pl.String)
|
|
@@ -1198,6 +1274,13 @@ for year in range(1, N_YEARS_OUT + 1):
|
|
|
1198
1274
|
(pl.col("_by_end") * pl.col("_degree").is_in(["AA", "BA"]).cast(pl.Int8))
|
|
1199
1275
|
.max()
|
|
1200
1276
|
.alias(f"cmp_any_byY{year}"),
|
|
1277
|
+
(
|
|
1278
|
+
pl.col("_by_end")
|
|
1279
|
+
* pl.col("_degree").is_in(["AA", "BA"]).cast(pl.Int8)
|
|
1280
|
+
* pl.col("college_elite").fill_null(0).cast(pl.Int8)
|
|
1281
|
+
)
|
|
1282
|
+
.max()
|
|
1283
|
+
.alias(f"cmp_elite_byY{year}"),
|
|
1201
1284
|
)
|
|
1202
1285
|
)
|
|
1203
1286
|
|
|
@@ -1256,20 +1339,24 @@ degree_outcomes = degree_outcomes.join(degree_details, on="sid_cepr", how="left"
|
|
|
1256
1339
|
|
|
1257
1340
|
# Merge enrollment and degree outcomes back to the unique application universe.
|
|
1258
1341
|
nsc_outcomes = (
|
|
1259
|
-
apps.join(enrollment_outcomes, on="sid_cepr", how="left")
|
|
1260
|
-
.join(degree_outcomes, on="sid_cepr", how="left")
|
|
1342
|
+
apps.join(enrollment_outcomes, on="sid_cepr", how="left", validate="m:1")
|
|
1343
|
+
.join(degree_outcomes, on="sid_cepr", how="left", validate="m:1")
|
|
1344
|
+
.with_columns(
|
|
1345
|
+
pl.when(pl.col("ID_FSC_firstinst").is_null())
|
|
1346
|
+
.then(k_mean_neverattend)
|
|
1347
|
+
.otherwise(pl.col("k_mean"))
|
|
1348
|
+
.alias("k_mean"),
|
|
1349
|
+
pl.when(pl.col("ID_FSC_firstinst").is_null())
|
|
1350
|
+
.then(0.0)
|
|
1351
|
+
.otherwise(pl.col("predicted_completion"))
|
|
1352
|
+
.alias("predicted_completion"),
|
|
1353
|
+
)
|
|
1261
1354
|
)
|
|
1262
1355
|
|
|
1263
1356
|
for year in range(1, N_YEARS_OUT + 1):
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
(pl.col("cohort_18") + year).alias("_by_end_year"),
|
|
1268
|
-
).with_columns(
|
|
1269
|
-
pl.date(pl.col("_in_start_year"), 7, 1).alias("_in_start"),
|
|
1270
|
-
pl.date(pl.col("_by_start_year"), 7, 1).alias("_by_start"),
|
|
1271
|
-
pl.date(pl.col("_by_end_year"), 6, 30).alias("_by_end"),
|
|
1272
|
-
)
|
|
1357
|
+
in_start = pl.date(pl.col("cohort_18") + year - 1, 7, 1)
|
|
1358
|
+
by_start = pl.date(pl.col("cohort_18"), 7, 1)
|
|
1359
|
+
by_end = pl.date(pl.col("cohort_18") + year, 6, 30)
|
|
1273
1360
|
|
|
1274
1361
|
att_in_columns = [
|
|
1275
1362
|
column
|
|
@@ -1291,7 +1378,7 @@ for year in range(1, N_YEARS_OUT + 1):
|
|
|
1291
1378
|
|
|
1292
1379
|
nsc_outcomes = nsc_outcomes.with_columns(
|
|
1293
1380
|
[
|
|
1294
|
-
pl.when(
|
|
1381
|
+
pl.when(in_start > NSC_CUTOFF_DATE)
|
|
1295
1382
|
.then(None)
|
|
1296
1383
|
.when(pl.col(column).is_null())
|
|
1297
1384
|
.then(0)
|
|
@@ -1302,7 +1389,7 @@ for year in range(1, N_YEARS_OUT + 1):
|
|
|
1302
1389
|
]
|
|
1303
1390
|
+
|
|
1304
1391
|
[
|
|
1305
|
-
pl.when(
|
|
1392
|
+
pl.when(by_start > NSC_CUTOFF_DATE)
|
|
1306
1393
|
.then(None)
|
|
1307
1394
|
.when(pl.col(column).is_null())
|
|
1308
1395
|
.then(0)
|
|
@@ -1313,7 +1400,7 @@ for year in range(1, N_YEARS_OUT + 1):
|
|
|
1313
1400
|
]
|
|
1314
1401
|
+
|
|
1315
1402
|
[
|
|
1316
|
-
pl.when(
|
|
1403
|
+
pl.when(by_end > NSC_CUTOFF_DATE)
|
|
1317
1404
|
.then(None)
|
|
1318
1405
|
.when(pl.col(column).is_null())
|
|
1319
1406
|
.then(0)
|
|
@@ -1330,21 +1417,21 @@ for year in range(1, N_YEARS_OUT + 1):
|
|
|
1330
1417
|
###########################################################
|
|
1331
1418
|
|
|
1332
1419
|
outcome_columns = [
|
|
1333
|
-
"att_any_inY1", "att_any_inY2", "att_any_inY3", "att_any_inY4",
|
|
1334
|
-
"att_4yr_inY1", "att_4yr_inY2", "att_4yr_inY3", "att_4yr_inY4",
|
|
1420
|
+
"att_any_inY1", "att_any_inY2", "att_any_inY3", "att_any_inY4", "att_any_inY5", "att_any_inY6", "att_any_inY7", "att_any_inY8",
|
|
1421
|
+
"att_4yr_inY1", "att_4yr_inY2", "att_4yr_inY3", "att_4yr_inY4", "att_4yr_inY5", "att_4yr_inY6", "att_4yr_inY7", "att_4yr_inY8",
|
|
1335
1422
|
"att_2yr_inY1", "att_2yr_inY2", "att_2yr_inY3", "att_2yr_inY4",
|
|
1336
1423
|
"att_elite_inY1", "att_elite_inY2", "att_elite_inY3", "att_elite_inY4",
|
|
1337
1424
|
|
|
1338
1425
|
"att_any_byY2", "att_any_byY3", "att_any_byY4",
|
|
1339
1426
|
"att_4yr_byY2", "att_4yr_byY3", "att_4yr_byY4",
|
|
1340
1427
|
"att_2yr_byY2", "att_2yr_byY3", "att_2yr_byY4",
|
|
1341
|
-
"att_elite_byY2", "att_elite_byY3", "att_elite_byY4",
|
|
1428
|
+
"att_elite_byY2", "att_elite_byY3", "att_elite_byY4", "att_elite_byY5", "att_elite_byY6",
|
|
1342
1429
|
|
|
1343
1430
|
"cmp_any_byY4", "cmp_any_byY5", "cmp_any_byY6", "cmp_any_byY7", "cmp_any_byY8",
|
|
1344
1431
|
"cmp_AA_byY4", "cmp_AA_byY5", "cmp_AA_byY6", "cmp_AA_byY7", "cmp_AA_byY8",
|
|
1345
1432
|
"cmp_BA_byY4", "cmp_BA_byY5", "cmp_BA_byY6", "cmp_BA_byY7", "cmp_BA_byY8",
|
|
1346
1433
|
|
|
1347
|
-
|
|
1434
|
+
"cmp_elite_byY4", "cmp_elite_byY5", "cmp_elite_byY6", "cmp_elite_byY7", "cmp_elite_byY8",
|
|
1348
1435
|
]
|
|
1349
1436
|
|
|
1350
1437
|
nsc_outcomes = nsc_outcomes.with_columns(
|
|
@@ -1355,6 +1442,11 @@ nsc_outcomes = nsc_outcomes.with_columns(
|
|
|
1355
1442
|
|
|
1356
1443
|
keep_columns = [
|
|
1357
1444
|
"sid_cepr",
|
|
1445
|
+
"k_mean",
|
|
1446
|
+
"predicted_completion",
|
|
1447
|
+
"ID_FSC_firstinst",
|
|
1448
|
+
"college_name_firstinst",
|
|
1449
|
+
"completion_rate_150pct_firstinst",
|
|
1358
1450
|
] + outcome_columns
|
|
1359
1451
|
|
|
1360
1452
|
nsc_outcomes_final = nsc_outcomes.select(keep_columns)
|
|
@@ -1368,6 +1460,25 @@ nsc_outcomes.with_columns(
|
|
|
1368
1460
|
print(f"Wrote {OUTCOMES}")
|
|
1369
1461
|
print(f"Wrote {OUTCOMES.with_suffix('.csv')}")
|
|
1370
1462
|
print(f"Rows: {nsc_outcomes.height}, columns: {len(nsc_outcomes.columns)}")
|
|
1463
|
+
|
|
1464
|
+
first_college_coverage = (
|
|
1465
|
+
nsc_outcomes.filter(pl.col("ID_FSC_firstinst").is_not_null())
|
|
1466
|
+
.group_by("ID_FSC_firstinst")
|
|
1467
|
+
.agg(
|
|
1468
|
+
pl.col("k_mean_firstinst").is_not_null().any().alias("has_k_mean"),
|
|
1469
|
+
pl.col("completion_rate_150pct_firstinst")
|
|
1470
|
+
.is_not_null()
|
|
1471
|
+
.any()
|
|
1472
|
+
.alias("has_completion_rate"),
|
|
1473
|
+
)
|
|
1474
|
+
)
|
|
1475
|
+
print(
|
|
1476
|
+
"First-college coverage: "
|
|
1477
|
+
f"{first_college_coverage['has_k_mean'].sum()}/"
|
|
1478
|
+
f"{first_college_coverage.height} with college-specific k_mean; "
|
|
1479
|
+
f"{first_college_coverage['has_completion_rate'].sum()}/"
|
|
1480
|
+
f"{first_college_coverage.height} with IPEDS completion rate"
|
|
1481
|
+
)
|
|
1371
1482
|
print(
|
|
1372
1483
|
nsc_outcomes.select("sid_cepr", "cohort_lottery", "recovered_nsc_outcome").sort(
|
|
1373
1484
|
"sid_cepr"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/aspire.py
RENAMED
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/check_cmo_apps.do
RENAMED
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/christel_house.py
RENAMED
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/democracy_prep.py
RENAMED
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/green_dot.py
RENAMED
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/kipp_nj.py
RENAMED
|
File without changes
|
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/mappings.py
RENAMED
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/rocketship.py
RENAMED
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260614_new_build_scripts_update/yes_prep.py
RENAMED
|
File without changes
|
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260630_census_disclosure/christel_house.py
RENAMED
|
File without changes
|
{ltc_code-0.2.16 → ltc_code-0.2.18}/src/ltc_code/20260630_census_disclosure/democracy_prep.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|