ltc-code 0.2.26__tar.gz → 0.2.28__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.26 → ltc_code-0.2.28}/PKG-INFO +1 -1
- {ltc_code-0.2.26 → ltc_code-0.2.28}/pyproject.toml +1 -1
- {ltc_code-0.2.26 → ltc_code-0.2.28}/pyproject.toml.orig +1 -1
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/nsc/build_nsc_outcomes.py +111 -15
- ltc_code-0.2.28/src/ltc_code/plot_bars.py +84 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/README.md +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/aspire.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/check_cmo_apps.do +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/christel_house.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/democracy_prep.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/green_dot.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/helpers.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/ilt.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/kipp_nj.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/main.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/mappings.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/rocketship.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/yes_prep.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260630_census_disclosure/aspire.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260630_census_disclosure/christel_house.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260630_census_disclosure/democracy_prep.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260630_census_disclosure/green_dot.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260630_census_disclosure/ilt.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260630_census_disclosure/kipp.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260630_census_disclosure/kipp_nj.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260630_census_disclosure/rocketship.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260630_census_disclosure/yes_prep.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260706_ceprscripts/BALANCE.do +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260706_ceprscripts/FS.do +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260706_ceprscripts/ITT.do +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260706_ceprscripts/TOT.do +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260706_ceprscripts/apps_helpers.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260706_ceprscripts/harmony.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260706_ceprscripts/main.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260712_uncommon_scripts/main.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260712_uncommon_scripts/mappings.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260712_uncommon_scripts/uncommon.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/__init__.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/aspire.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/check_cmo_apps.do +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/christel_house.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/green_dot.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/helpers.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/june13.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/june2.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/june30.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/june5.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/june7.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/kipp_nj.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/kipp_tx.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/main.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/make_summary_stats_table.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/mappings.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/may27.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/nsc/__init__.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/nsc/dhs_stem/dhs_stem_cip_additions_2024.csv +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/nsc/dhs_stem/extract_dhs_stem_cips.R +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/nsc/dhs_stem/stemList2024.pdf +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/nsc/input/.gitkeep +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/nsc/naics.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/nsc/output/.gitkeep +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/nsc/raw/ipeds_data.dta +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/nsc/run_nsc_outcomes.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/polars_dates.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/rocketship.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/schema_mapping.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/school_name_xwalk/__init__.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/school_name_xwalk/all_schools_with_ccd.csv +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/school_name_xwalk/merge_school_ccd.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/signal_var_calcs.py +0 -0
- {ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/yes_prep.py +0 -0
|
@@ -1198,9 +1198,10 @@ for year in range(1, N_YEARS_OUT + 1):
|
|
|
1198
1198
|
[
|
|
1199
1199
|
(
|
|
1200
1200
|
pl.col("_overlaps")
|
|
1201
|
-
*
|
|
1202
|
-
|
|
1203
|
-
|
|
1201
|
+
* (
|
|
1202
|
+
pl.lit(1) if college_type == "any"
|
|
1203
|
+
else pl.col(f"college_{college_type}").fill_null(0).cast(pl.Int8)
|
|
1204
|
+
)
|
|
1204
1205
|
)
|
|
1205
1206
|
.max()
|
|
1206
1207
|
.alias(f"att_{college_type}_{label}")
|
|
@@ -1258,9 +1259,10 @@ for age in AGE_ATTENDANCE_RANGE:
|
|
|
1258
1259
|
[
|
|
1259
1260
|
(
|
|
1260
1261
|
pl.col("_overlaps")
|
|
1261
|
-
*
|
|
1262
|
-
|
|
1263
|
-
|
|
1262
|
+
* (
|
|
1263
|
+
pl.lit(1) if college_type == "any"
|
|
1264
|
+
else pl.col(f"college_{college_type}").fill_null(0).cast(pl.Int8)
|
|
1265
|
+
)
|
|
1264
1266
|
)
|
|
1265
1267
|
.max()
|
|
1266
1268
|
.alias(f"att_{college_type}_{age}")
|
|
@@ -1860,6 +1862,86 @@ nsc_outcomes = nsc_outcomes.with_columns(
|
|
|
1860
1862
|
)
|
|
1861
1863
|
|
|
1862
1864
|
|
|
1865
|
+
# Split the existing prediction by first institution, preserving missing rates.
|
|
1866
|
+
nsc_outcomes = nsc_outcomes.with_columns(
|
|
1867
|
+
pl.when(
|
|
1868
|
+
pl.col("adj_cmp_rate").is_not_null()
|
|
1869
|
+
& pl.col("college_years_firstinst").is_in([1, 2])
|
|
1870
|
+
)
|
|
1871
|
+
.then(0.0)
|
|
1872
|
+
.otherwise(pl.col("adj_cmp_rate"))
|
|
1873
|
+
.alias("adj_cmp_rate_4yr"),
|
|
1874
|
+
pl.when(
|
|
1875
|
+
pl.col("adj_cmp_rate").is_not_null()
|
|
1876
|
+
& (pl.col("college_years_firstinst") == 4)
|
|
1877
|
+
)
|
|
1878
|
+
.then(0.0)
|
|
1879
|
+
.otherwise(pl.col("adj_cmp_rate"))
|
|
1880
|
+
.alias("adj_cmp_rate_2yr"),
|
|
1881
|
+
)
|
|
1882
|
+
|
|
1883
|
+
# Separate the fully coarse prediction by first-institution sector.
|
|
1884
|
+
nsc_outcomes = nsc_outcomes.with_columns(
|
|
1885
|
+
pl.when(
|
|
1886
|
+
pl.col("adj_cmp_rate_coarse").is_not_null()
|
|
1887
|
+
& pl.col("college_years_firstinst").is_in([1, 2])
|
|
1888
|
+
)
|
|
1889
|
+
.then(0.0)
|
|
1890
|
+
.otherwise(pl.col("adj_cmp_rate_coarse"))
|
|
1891
|
+
.alias("adj_cmp_rate_coarse_4yr"),
|
|
1892
|
+
pl.when(
|
|
1893
|
+
pl.col("adj_cmp_rate_coarse").is_not_null()
|
|
1894
|
+
& (pl.col("college_years_firstinst") == 4)
|
|
1895
|
+
)
|
|
1896
|
+
.then(0.0)
|
|
1897
|
+
.otherwise(pl.col("adj_cmp_rate_coarse"))
|
|
1898
|
+
.alias("adj_cmp_rate_coarse_2yr"),
|
|
1899
|
+
)
|
|
1900
|
+
|
|
1901
|
+
# Give each IPEDS institution one tier, excluding missing crosswalk tiers.
|
|
1902
|
+
ipeds_tiers = college_ref.select("unitid", "tier").drop_nulls().unique()
|
|
1903
|
+
ipeds_tier_completion = ipeds_completion_with_sector.join(
|
|
1904
|
+
ipeds_tiers, on="unitid", how="left", validate="1:1"
|
|
1905
|
+
).filter(pl.col("college_sector") == "4yr")
|
|
1906
|
+
|
|
1907
|
+
# Coarsen one bucket at a time, always starting from the detailed prediction.
|
|
1908
|
+
tier_buckets = {"t12": [1, 2], "t34": [3, 4], "t58": [5, 6, 7, 8]}
|
|
1909
|
+
for label, tiers in tier_buckets.items():
|
|
1910
|
+
bucket_rate = (
|
|
1911
|
+
ipeds_tier_completion.filter(pl.col("tier").is_in(tiers))
|
|
1912
|
+
.select(
|
|
1913
|
+
pl.col("completers_150pct_ip").sum()
|
|
1914
|
+
/ pl.col("cohort_adj_150pct_ip").sum()
|
|
1915
|
+
)
|
|
1916
|
+
.item()
|
|
1917
|
+
)
|
|
1918
|
+
nsc_outcomes = nsc_outcomes.with_columns(
|
|
1919
|
+
pl.when(
|
|
1920
|
+
(pl.col("college_years_firstinst") == 4)
|
|
1921
|
+
& pl.col("tier_firstinst").is_in(tiers)
|
|
1922
|
+
& (pl.col("att_any_byY4") == 1)
|
|
1923
|
+
& pl.col("adj_cmp_rate_4yr").is_not_null()
|
|
1924
|
+
)
|
|
1925
|
+
.then(bucket_rate)
|
|
1926
|
+
.otherwise(pl.col("adj_cmp_rate_4yr"))
|
|
1927
|
+
.alias(f"adj_cmp_rate_4yr_coarse_{label}")
|
|
1928
|
+
)
|
|
1929
|
+
print(f"Four-year IPEDS-cohort-weighted completion rate, {label}: {bucket_rate}")
|
|
1930
|
+
|
|
1931
|
+
# Match the available 1098-T calendar years, including the missing 2015 year.
|
|
1932
|
+
tax_years = list(range(2011, 2015)) + list(range(2016, 2023))
|
|
1933
|
+
nsc_outcomes = nsc_outcomes.with_columns(
|
|
1934
|
+
[
|
|
1935
|
+
pl.when((pl.col("cohort_lottery") + age).is_in(tax_years))
|
|
1936
|
+
.then(pl.col(f"att_any_{age}"))
|
|
1937
|
+
.otherwise(None)
|
|
1938
|
+
.alias(f"att_any_1098_{age}")
|
|
1939
|
+
for age in AGE_ATTENDANCE_RANGE
|
|
1940
|
+
]
|
|
1941
|
+
|
|
1942
|
+
)
|
|
1943
|
+
|
|
1944
|
+
|
|
1863
1945
|
###########################################################
|
|
1864
1946
|
# Write final outcomes
|
|
1865
1947
|
###########################################################
|
|
@@ -1876,6 +1958,7 @@ outcome_columns = [
|
|
|
1876
1958
|
"att_elite_byY2", "att_elite_byY3", "att_elite_byY4", "att_elite_byY5", "att_elite_byY6",
|
|
1877
1959
|
|
|
1878
1960
|
*[f"att_any_{age}" for age in AGE_ATTENDANCE_RANGE],
|
|
1961
|
+
*[f"att_any_1098_{age}" for age in AGE_ATTENDANCE_RANGE],
|
|
1879
1962
|
*[f"att_4yr_{age}" for age in AGE_ATTENDANCE_RANGE],
|
|
1880
1963
|
*[f"att_2yr_{age}" for age in AGE_ATTENDANCE_RANGE],
|
|
1881
1964
|
|
|
@@ -1932,6 +2015,11 @@ keep_columns = [
|
|
|
1932
2015
|
"completion_rate_150pct_ip",
|
|
1933
2016
|
"cmp_rate",
|
|
1934
2017
|
"adj_cmp_rate",
|
|
2018
|
+
"adj_cmp_rate_2yr",
|
|
2019
|
+
"adj_cmp_rate_4yr",
|
|
2020
|
+
"adj_cmp_rate_coarse_2yr",
|
|
2021
|
+
"adj_cmp_rate_coarse_4yr",
|
|
2022
|
+
*[f"adj_cmp_rate_4yr_coarse_{label}" for label in tier_buckets],
|
|
1935
2023
|
"adj_cmp_rate_coarse",
|
|
1936
2024
|
"adj_cmp_rate_coarse_sample",
|
|
1937
2025
|
"adj_cmp_rate_coarsen_4yr",
|
|
@@ -2012,15 +2100,8 @@ coarse_audit = observable_y4.select(
|
|
|
2012
2100
|
|
|
2013
2101
|
if coarse_audit.item(0, "k_mean_coarse_missing") > 0:
|
|
2014
2102
|
raise ValueError("k_mean_coarse is unexpectedly missing for observable students.")
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
"adj_cmp_rate_coarse is unexpectedly missing for observable students."
|
|
2018
|
-
)
|
|
2019
|
-
if coarse_audit.item(0, "adj_cmp_rate_coarse_sample_missing") > 0:
|
|
2020
|
-
raise ValueError(
|
|
2021
|
-
"adj_cmp_rate_coarse_sample is unexpectedly missing for observable students."
|
|
2022
|
-
)
|
|
2023
|
-
|
|
2103
|
+
# Attendees without a classified first college can have missing coarse rates.
|
|
2104
|
+
# Report those counts below rather than treating them as a build failure.
|
|
2024
2105
|
print("Coarse outcome audit:")
|
|
2025
2106
|
print(coarse_audit)
|
|
2026
2107
|
|
|
@@ -2067,3 +2148,18 @@ print(
|
|
|
2067
2148
|
"sid_cepr"
|
|
2068
2149
|
)
|
|
2069
2150
|
)
|
|
2151
|
+
|
|
2152
|
+
# Nonmissing year-eight completion identifies students with the full Y8 window.
|
|
2153
|
+
year8_attendance_audit = (
|
|
2154
|
+
nsc_outcomes.filter(pl.col("cmp_BA_byY8").is_not_null())
|
|
2155
|
+
.select(
|
|
2156
|
+
pl.len().alias("N_year8_sample"),
|
|
2157
|
+
(pl.col("att_any_byY4") == 0).sum().alias("N_no_attendance_byY4"),
|
|
2158
|
+
(
|
|
2159
|
+
(pl.col("att_any_byY4") == 0)
|
|
2160
|
+
& (pl.col("cmp_BA_byY8") == 1)
|
|
2161
|
+
).sum().alias("N_no_attendance_byY4_BA_byY8"),
|
|
2162
|
+
)
|
|
2163
|
+
)
|
|
2164
|
+
print("Year-eight sample attendance and late BA completion check:")
|
|
2165
|
+
print(year8_attendance_audit)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# --- Import necessary packages ---
|
|
2
|
+
# Required libraries: polars (input DataFrame), pandas, plotnine, oi-tools.
|
|
3
|
+
# Install in your analysis project: uv add polars pandas plotnine oi-tools
|
|
4
|
+
from typing import Optional
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from oi_tools.figures import theme_oi
|
|
7
|
+
from plotnine import (
|
|
8
|
+
aes, annotate, coord_cartesian, geom_col, geom_errorbar, geom_text,
|
|
9
|
+
geom_vline, ggplot, labs, scale_x_continuous, theme,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def plot_bars(
|
|
14
|
+
df,
|
|
15
|
+
y_col: str,
|
|
16
|
+
plot_label: str,
|
|
17
|
+
which_control: str = "ccm",
|
|
18
|
+
scale: float = 1,
|
|
19
|
+
sample_col: Optional[str] = None,
|
|
20
|
+
):
|
|
21
|
+
"""Use the first row, or one pair per row when sample_col is provided.
|
|
22
|
+
|
|
23
|
+
df is a Polars DataFrame containing ccm (or which_control), coef, se,
|
|
24
|
+
and N_ppl. scale=1/1000 adds K; scale=100 adds %; otherwise no suffix.
|
|
25
|
+
y_col is the axis title; sample_col may label samples or outcomes.
|
|
26
|
+
The treated interval is control + coef +/- 1.96 * se, as before.
|
|
27
|
+
"""
|
|
28
|
+
suffix = "K" if scale == 1 / 1000 else "%" if scale == 100 else ""
|
|
29
|
+
n_samples = df.height if sample_col is not None else 1
|
|
30
|
+
frames, notes = [], []
|
|
31
|
+
|
|
32
|
+
for i in range(n_samples):
|
|
33
|
+
control = df.item(i, which_control) * scale
|
|
34
|
+
effect = df.item(i, "coef") * scale
|
|
35
|
+
se = df.item(i, "se") * abs(scale)
|
|
36
|
+
n_ppl = df.item(i, "N_ppl") / 1000
|
|
37
|
+
|
|
38
|
+
frames.append(pd.DataFrame({
|
|
39
|
+
"group": ["Control", "Treated"],
|
|
40
|
+
"x": [3 * i + 1, 3 * i + 2],
|
|
41
|
+
"value": [control, control + effect],
|
|
42
|
+
"ci_lo": [None, control + effect - 1.96 * se],
|
|
43
|
+
"ci_hi": [None, control + effect + 1.96 * se],
|
|
44
|
+
"label": [f"{control:.1f}{suffix}",
|
|
45
|
+
f"{control + effect:.1f}{suffix}"],
|
|
46
|
+
}))
|
|
47
|
+
sample = f"{df.item(i, sample_col)}\n" if sample_col is not None else ""
|
|
48
|
+
notes.append({
|
|
49
|
+
"x": 3 * i + 1.5,
|
|
50
|
+
"label": (f"{sample}Delta = {effect:.1f}{suffix} (se = {se:.1f}{suffix})"
|
|
51
|
+
f"\n(N_ppl = {n_ppl:.1f}K)"),
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
plot_data = pd.concat(frames, ignore_index=True)
|
|
55
|
+
treated = plot_data.iloc[1::2]
|
|
56
|
+
y_min = min(0.5 * plot_data["value"].min(), treated["ci_lo"].min(),
|
|
57
|
+
plot_data["value"].min())
|
|
58
|
+
top = max(plot_data["value"].max(), treated["ci_hi"].max())
|
|
59
|
+
span = max(top - y_min, 1e-6)
|
|
60
|
+
y_max = top + 0.35 * span
|
|
61
|
+
plot_data["label_y"] = plot_data[["value", "ci_hi"]].max(axis=1) + 0.025 * span
|
|
62
|
+
|
|
63
|
+
p = (
|
|
64
|
+
ggplot(plot_data, aes(x="x", y="value"))
|
|
65
|
+
+ theme_oi()
|
|
66
|
+
+ geom_col(width=0.5, fill="#F8766D")
|
|
67
|
+
+ geom_errorbar(
|
|
68
|
+
data=treated, mapping=aes(ymin="ci_lo", ymax="ci_hi"), width=0.15,
|
|
69
|
+
)
|
|
70
|
+
+ labs(title=plot_label, x="", y=y_col)
|
|
71
|
+
+ geom_text(aes(y="label_y", label="label"), va="bottom", size=10)
|
|
72
|
+
+ scale_x_continuous(breaks=plot_data["x"].tolist(),
|
|
73
|
+
labels=plot_data["group"].tolist())
|
|
74
|
+
+ coord_cartesian(ylim=(y_min, y_max))
|
|
75
|
+
+ theme(figure_size=(max(6, 3 * n_samples), 5.5))
|
|
76
|
+
)
|
|
77
|
+
for note in notes:
|
|
78
|
+
p += annotate("text", x=note["x"], y=top + 0.23 * span,
|
|
79
|
+
label=note["label"], size=10, fontweight="bold")
|
|
80
|
+
if n_samples > 1:
|
|
81
|
+
p += geom_vline(xintercept=[3 * i for i in range(1, n_samples)],
|
|
82
|
+
linetype="dashed", color="grey", size=0.5)
|
|
83
|
+
|
|
84
|
+
return p
|
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/aspire.py
RENAMED
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/check_cmo_apps.do
RENAMED
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/christel_house.py
RENAMED
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/democracy_prep.py
RENAMED
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/green_dot.py
RENAMED
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/kipp_nj.py
RENAMED
|
File without changes
|
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/mappings.py
RENAMED
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/rocketship.py
RENAMED
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260614_new_build_scripts_update/yes_prep.py
RENAMED
|
File without changes
|
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/20260630_census_disclosure/christel_house.py
RENAMED
|
File without changes
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/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
|
{ltc_code-0.2.26 → ltc_code-0.2.28}/src/ltc_code/nsc/dhs_stem/dhs_stem_cip_additions_2024.csv
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
|