Medicare Advantage, Part D, Medicaid

MA Star Ratings — measure dimension

medicare_silver.dim_stars_measures·live·silver·annual·Medicare Advantage Star Ratings
Rows
N/A
Columns
22
History
rating_year 2015 (measurement_period data windows reach back to MY2013) to rating_year 2026 (latest data window 'MY2024 Q1-Q3 (Q4 excluded)')
Card
yesgrain, traps, filters
Typed tools
4

What it is

  1. 1A definitional/reference dimension that catalogs every CMS Medicare Advantage & Part D Star Ratings measure for each annual rating-year cycle (RY2015-RY2026): the measure's slot ID, name, Part C/D, domain, scoring weight, scoring direction, value format, the data window that feeds it, and CMS methodology/provenance metadata.
  2. 2It is the lookup spine that gives meaning and weights to the per-plan measure scores in the Stars fact tables; it holds no plan-level performance values itself.

Grain

KeyGrain
measure_idrating_year
  1. 1One row per Star Ratings measure per rating year; minimal verified-unique key (measure_id, rating_year) = 538 distinct = 538 total rows.

How to read it

  1. 1To see how a measure's scoring weight evolved over time, group by the stable canonical_name: SELECT rating_year, weight FROM dim_stars_measures WHERE canonical_name='Care Coordination' ORDER BY rating_year — returns the weight trajectory 1.5 (2015-2020) → 2.0 (2021-2022) → 4.0 (2023-2025) → 2.0 (2026), revealing the RY2023 patient-experience weight-doubling and its RY2026 rollback.
  2. 2To enrich a per-plan Stars measure score, join the fact's (measure_id, rating_year) to this table for name/domain/weight/scoring-direction.

Traps

  1. 1measure_id is NOT a stable measure identity — it is a per-rating-year slot code CMS renumbers every cycle. A single ID like C25 maps to 6-8 different measure concepts across RY2015-2026. To track ONE measure over time, group/join on canonical_name (always present) or cmit_number (RY2024+ only), never on measure_id alone. Any join to a per-plan Stars fact MUST include rating_year.
  2. 2The grain is (measure_id, rating_year) = 538 distinct = 538 rows. None of the profiler's candidate-key columns (cmit_number, dual_numbered_with, recompute_gap_id, weight_override_puerto_rico_only) are part of the key — most are mostly-null annotations. measure_id alone has only 49 distinct values; do not treat it as a primary key.
  3. 3weight is rating-year-specific and changes substantially over time for the same concept (e.g. Care Coordination 1.5→2.0→4.0→2.0). The RY2023-2025 era (methodology_version 'ry2023_v1_weight_doubling') quadruples patient-experience/CAHPS weights. Never assume a single weight per measure — always read it at the target rating_year.
  4. 4Several columns are declared-but-effectively-empty or constant and carry no signal today: is_retired is FALSE for all 538 rows (measure availability is shown by which rows EXIST per year, not this flag); tech_notes_pdf_sha256 is NULL for all rows; methodology_source is the same hand-authored string for all rows; is_current is TRUE for all rows (single snapshot, no dedup filter needed yet).
  5. 5Null is meaningful on the annotation columns: cmit_number is NULL for RY2015-2023 (CMIT IDs only exist from RY2024); dual_numbered_with NULL = not a C/D dual-counted measure; recompute_gap_id NULL = recomputable (non-null ⟺ the 24 composite rows); weight_override_puerto_rico_only NULL = use normal weight, 0.0 = measure excluded from Puerto Rico ratings (only the 3 med-adherence measures).
  6. 6This is a DEFINITION table, not a performance table — it holds zero plan/contract-level scores or rates. It is the dictionary that gives weights and meaning to the actual MA Star Ratings measure-value fact tables. measurement_period is free-text (69 variant formats: MY####, CY####, multi-year HOS spans, CAHPS survey windows) and lags rating_year by ~2 years; it is the history/time column but is NOT part of the grain key. primary_data_source has spelling variants (PDE_MPF vs PDE-MPF vs PDE/MPF) — normalize before aggregating.

Columns (22)

ColumnTypeMeaning
measure_idstringCMS per-rating-year measure slot code: 'C'+2 digits for Part C/health-plan measures, 'D'+2 digits for Part D/drug-plan measures (e.g. C07, D12). 49 distinct values, 379 C-rows / 159 D-rows. CRITICAL: this is a per-year POSITION code that CMS renumbers each cycle, NOT a stable measure identity — e.g. 'C25' is Customer Service in RY2015, Care Coordination in RY2016-17, ... Complaints about the Health Plan in RY2024-25, Rating of Health Care Quality in RY2026. Join to a fact table only within the same rating_year. Never null.
measure_namestringHuman-readable measure name as published for that rating year (e.g. 'Adult BMI Assessment', 'Medication Adherence for Cholesterol (Statins)'). Wording can drift year to year. Never null. In observed rows identical to canonical_name.
part_typestringMedicare program part the measure belongs to: 'C' (Medicare Advantage / health-plan measures, 379 rows) or 'D' (prescription-drug-plan measures, 159 rows). Matches the measure_id prefix. Never null.
domainstringStar Ratings domain grouping the measure rolls into. Part C domains: HD1-HD5 (e.g. HD1 staying healthy, HD2 managing chronic conditions - the largest at 167 rows, HD3 member experience, HD4 complaints/leaving, HD5 customer service). Part D domains: DD1-DD4. 9 distinct values, never null.
weightfloatCMS scoring weight applied to the measure when computing the overall Star Rating, for THAT rating year. Float values 1.0 (process, 220 rows), 1.5 (patient-experience/CAHPS legacy, 110), 2.0 (outcome/intermediate-outcome, 50), 3.0 (50/PDE adherence + patient experience post-2021, 86), 4.0 (patient-experience peak in the RY2023-2025 weight-doubling era, 48), 5.0 (the improvement composites, 24). Weight changes YEAR TO YEAR for the same concept — e.g. Care Coordination ran 1.5 (RY2015-2020) → 2.0 (RY2021-2022) → 4.0 (RY2023-2025) → 2.0 (RY2026). Never null.
is_inverse_scoredbooleanBoolean: TRUE when LOWER raw values are better (75 rows) so the score must be inverted. TRUE for complaints, members-choosing-to-leave, appeals auto-forward, all-cause readmissions, high-risk-medication, and the diabetes-control measures. FALSE (463 rows) for normal higher-is-better measures. Never null.
format_typestringNumeric format of the underlying measure value: PERCENTAGE (424, the bulk), DECIMAL (48, e.g. rates/ratios), INTEGER (42, e.g. counts/per-1000 call-center metrics), NO_NUMERIC (24). NO_NUMERIC rows are exactly the two improvement composites (Health Plan / Drug Plan Quality Improvement) which are derived, not a raw measured number. Never null.
measurement_periodstringFree-text data-collection window that FEEDS this rating year (the data lags the rating year, typically by ~2 years). 69 distinct values, format varies by data source: HEDIS measurement years 'MY2019'/'MY2014', calendar years 'CY2019', multi-year HOS spans 'MY2017-MY2019', CAHPS survey windows 'CAHPS Feb-May 2018', and 'MY2024 Q1-Q3 (Q4 excluded)'. This is the table's time column for history span but it is NOT the grain key. Never null.
is_retiredbooleanBoolean intended to flag retired measures — but in this table it is FALSE for ALL 538 rows. Measure availability per cycle is expressed by which (measure_id, rating_year) rows EXIST, not by this flag. Effectively dead/always-false today.
is_new_this_yearbooleanBoolean: TRUE (15 rows) when the measure was newly introduced in that rating_year (e.g. Breast Cancer Screening new in RY2016, MPF Price Accuracy new in RY2022, Transitions of Care new in RY2024). FALSE otherwise. Never null.
rating_yearintInteger Star Ratings cycle year this measure definition applies to. Range 2015-2026 (12 years). Counts per year: 40-48 measures (2015=46 ... 2022/2023=40 the trough ... 2026=45). Half of the grain key; the table's logical partition. Never null.
methodology_versionstringVersioned tag of the methodology that produced this year's row, one per rating_year (e.g. 'ry2018_v1', 'ry2021_v1_covid_HH' for the COVID hold-harmless year, 'ry2023_v1_weight_doubling', 'ry2024_v2_post_scan_elevance_restated', 'ry2025_v2_post_uhc_centene_recalc'). Encodes notable policy events per cycle. Never null.
methodology_sourcestringProvenance of how the row was authored — UNIFORM 'hand_authored_from_kb_15_section_g' for all 538 rows. Signals this dimension was hand-curated from a CMS Technical Notes knowledge-base section, not auto-ingested from a CMS file.
tech_notes_pdf_sha256stringIntended SHA-256 provenance hash linking the row to the source CMS Technical Notes PDF. NULL for all 538 rows — declared provenance column, not yet populated.
is_currentbooleanBoolean current-snapshot flag. TRUE for all 538 rows — there is exactly one (non-superseded) snapshot loaded, so no is_current filter is needed today. Present to support future SCD/restatement snapshots.
cmit_numberstringCMS Measure Inventory Tool (CMIT) stable measure ID (e.g. '00093-02-C-PARTC' for Breast Cancer Screening). Populated ONLY for RY2024-2026 (127 rows); NULL for RY2015-2023 (411 rows) because CMS only began publishing CMIT IDs in recent cycles. Where present it is a durable cross-year identity, but it is sparse so cannot be the grain key. 43 distinct non-null values.
canonical_namestringThe STABLE cross-year concept name for the measure (e.g. 'Breast Cancer Screening' stays constant across RY2016-2026 even when its measure_id changes). This is the column to use to track one measure's weight/scoring over time, NOT measure_id. Never null.
primary_data_sourcestringUpstream CMS data system the measure is computed from. Top values: HEDIS (162), CAHPS member-survey (108), PDE prescription-drug-event (42), CTM complaints-tracking (24), 'Star Ratings (composite)' (24, the improvement measures), IRE/Maximus appeals (24), HOS health-outcomes-survey (24), MBDSS, Call Center monitoring, etc. ~33 distinct strings with mild spelling variants (e.g. 'PDE_MPF' vs 'PDE-MPF' vs 'PDE/MPF') — normalize before grouping. Never null.
dual_numbered_withstringCross-reference to the paired measure_id when a single CMS concept is counted under BOTH Part C and Part D in the same year (e.g. Complaints/ Members-Choosing-to-Leave). 48 rows non-null (490 null). The pointed-to ID is itself year-specific — e.g. C29 dual_numbered_with D03 in RY2015 but D04 in RY2019 — so resolve it within the same rating_year. NULL = not dual-numbered.
is_compositebooleanBoolean: TRUE (24 rows) for the two derived improvement composite measures (Health Plan Quality Improvement, Drug Plan Quality Improvement) across the 12 years. These are computed from year-over-year change in other measures, not measured directly (they are exactly the NO_NUMERIC, weight-5.0, recompute_gap-tagged rows). FALSE (514) otherwise. Never null.
recompute_gap_idstringSlug naming a known recompute limitation, e.g. 'stars_c25_composite_unrecomputable'. Non-null for exactly the 24 composite rows (perfectly correlated with is_composite) and NULL for the other 514. Flags that the measure cannot be reproduced from primitive substrate (it depends on prior-year ratings). NULL = recomputable.
weight_override_puerto_rico_onlyfloatFloat weight override that applies ONLY to Puerto Rico contracts. Set to 0.0 for 36 rows = exactly the three medication-adherence measures (Cholesterol/Statins, Hypertension/RAS, Diabetes) × 12 years, meaning those measures are dropped (weighted 0) from PR ratings. NULL (502 rows) means no PR-specific override — use the normal weight. Null carries meaning: 'no override'.

Query it

describe_data_source(source_fqn="medicare_silver.dim_stars_measures")     # the card, live
query_substrate(sql="SELECT * FROM medicare_silver.dim_stars_measures WHERE measure_id = '<value>' AND rating_year = '<value>' LIMIT 100")
ItemValue
Typed tools that read itget_star_decomposition, get_stars, get_stars_cutpoints, get_stars_rollup
Identity keymeasure_id
Joinhow_to_join(source_fqn="medicare_silver.dim_stars_measures")
Raw doorAthena (read-only via query_substrate): medicare_silver.dim_stars_measures (filter is_current = true)
NoteGrain-governed (medicare_ma_stars); seed methodology_seed.yaml.

This page as markdown: /docs-md/data/medicare_silver_dim_stars_measures.md · every page in one file: /llms-full.txt