# MA hedis hos frm

`medicare_silver.hedis_hos_frm` · Medicare Advantage, Part D, Medicaid · status live

One row per (contract, year). Health Outcomes Survey: Falls Risk Management. Two rates: (rate1) Talking with Doctor about Falling or Balance Problems, (rate2) Receiving Fall Risk Reduction Recommendation. ~600 rows per year.

**Grain.** One row per Medicare Advantage contract per report year. Verified: 3,207 rows = 3,207 distinct (contract_id, report_year) combinations. Each contract has exactly one row per year (max 1 plan_name and 1 source file per contract-year), covering 6 report years (2019, 2021-2025; 2020 absent because CMS suspended HEDIS reporting for measurement year 2020 during COVID).

**How to use it.** "SELECT contract_id, plan_name_raw, rate1, rate2 FROM medicare_silver.hedis_hos_frm WHERE report_year = 2025 ORDER BY rate2 DESC" answers: for the 2025 reporting year, which MA contracts have the highest share of members who received a fall-prevention recommendation (rate2) and discussed falls with their doctor (rate1) — a quality-benchmark ranking of plans on the HOS Falls Risk Management measure. To trend a single plan over time, drop the year filter and add 'WHERE contract_id = ' a specific contract and 'ORDER BY report_year'. Join to medicare_silver.hedis_general or Stars tables on (contract_id, report_year) to pull plan-type/enrollment/Star-rating context.

**Traps.**
- NOT a cost/price table despite living in a US-healthcare-COST catalog. 'rate1' and 'rate2' are patient-reported survey PERCENTAGES (0-100, fall-prevention process measures), not dollars, not negotiated rates. Its value to a cost catalog is indirect: it's a Star-Ratings quality input, and Stars drive MA plan quality-bonus payments — so it informs plan-quality/payment context, not procedure prices.
- The minimal grain is just (contract_id, report_year) = 3,207 rows. The profiler reported a 4-column key (adding plan_name_raw + effective_period_start + observed_period) but those three are redundant: observed_period/effective_period_start are collinear with report_year, and plan_name_raw is functionally determined within a contract-year. Don't add them to a join/dedup key.
- contract_id is NOT unique on its own (735 distinct vs 3,207 rows — same contract recurs each year) and plan_name_raw is unstable (one contract can carry up to 4 different printed names across years; many contracts share a parent name). Key on contract_id, never on plan_name_raw.
- Year 2020 is legitimately absent (CMS suspended HEDIS/HOS reporting for measurement year 2020 due to COVID) — do not treat the 2019->2021 gap as a missing load or pipeline error.
- Nulls carry meaning and rate2 is null far more than rate1 (443 vs 56, ~14% vs ~2%, rising in recent years) due to CMS small-denominator suppression. A row with rate1 present but rate2 null means the contract reported but the second indicator was suppressed — not zero, not missing data. rate2 is always >= rate1 when both present (0 inversions).
- No snapshot/version churn and no is_current column: cms_vintage_sequence, parse_revision, and asserted_at are all single-valued constants (1, 1, 2026-05-15) across every row, and there's exactly one source SHA per year. This is one clean historical load — no de-dup-to-latest step is needed, unlike point-in-time tables in this catalog.
- Sibling-table confusion: this is specifically the FRM (Falls Risk Management) HOS sheet. medicare_silver has parallel HOS tables hedis_hos_mui (Management of Urinary Incontinence, 3 rates, 2021+), hedis_hos_pao (Physical Activity, 2 rates), and hedis_hos_oto (one rate, 2019+2021 only) with the SAME (contract_id, report_year) grain and identical-looking rate1/rate2 columns — the rate columns mean DIFFERENT clinical things per table. Some scout docs label the siblings with '(?)' guesses; FRM's two indicators (talking-to-doctor / receiving-recommendation) are the confirmed meanings here per the parser config.

| column | type | meaning |
|---|---|---|
| contract_id | string | CMS Medicare Advantage contract number, the natural key. 735 distinct. Format = 1 letter + 4 digits: 'H' = HMO/local-PPO/MA-EGHP (~92%), 'R' = regional PPO (~8%). No 'S' (standalone PDP) contracts — correct, since HOS is a medical-survey measure with no drug-only plans. Joins to other medicare_silver HEDIS tables (hedis_general, hedis_measures, hedis_service_area) and to Stars contract data on contract_id + report_year. |
| plan_name_raw | string | Sponsoring organization / plan name exactly as printed in the CMS file (e.g. 'BLUE CROSS AND BLUE SHIELD OF ALABAMA', 'WELLCARE OF MISSISSIPPI, INC.'). 635 distinct, uppercase, un-normalized ('_raw'). NOT a grain key and NOT stable: a single contract_id can show up to 4 different names across years (rebrands/legal-name changes), and many distinct contracts share the same parent-org name. Always key on contract_id, treat plan_name_raw as a display label. |
| rate1 | double | HOS Falls Risk Management measure, indicator 1: percent of survey-eligible members who reported TALKING WITH THEIR DOCTOR about a fall or balance/walking problem. A 0-100 percentage (verified 0 out of bounds; observed range ~12.4-56.7, mean ~26%). Nullable: 56 rows null (small-sample/suppressed by CMS). This is a patient-reported quality rate, not a price. |
| rate2 | double | HOS Falls Risk Management measure, indicator 2: percent of members who reported RECEIVING A RECOMMENDATION / fall-prevention intervention from their provider. 0-100 percentage (verified in bounds; range ~27-92, mean ~56%). Always >= rate1 (2,764 of 2,764 non-null-pair rows; 0 inversions). Heavily nullable — 443 rows null (14%), increasing in recent years (e.g. 131 null in 2023) due to CMS small-denominator suppression. A null rate2 with a present rate1 is meaningful: the contract reported but the second indicator was suppressed. |
| report_year | int | HEDIS reporting year (the year the PUF labels the data). int. 6 values: 2019, 2021, 2022, 2023, 2024, 2025. 2020 is genuinely missing (COVID HEDIS suspension), not a load gap. Part of the grain. Row counts grow over time (417 in 2019 -> 609 in 2025) as MA enrollment/contract count grows. |
| observed_period | date | Jan 1 of report_year (date). Audit/temporal-anchor column stamped by the loader, perfectly collinear with report_year — adds no grain. e.g. report_year 2024 -> 2024-01-01. |
| asserted_at | date | Ingest/load date — when Vlada parsed and wrote the row. Constant 2026-05-15 across ALL 3,207 rows (single bulk historical load). Provenance only; does NOT vary by report_year and is not a snapshot/version axis here. |
| effective_period_start | date | Jan 1 of report_year (date). Loader-stamped period bound; collinear with report_year. The profiler's temporal column. |
| effective_period_end | date | Dec 31 of report_year (date). Loader-stamped period bound; collinear with report_year (e.g. 2024 -> 2024-12-31). |
| cms_vintage_sequence | int | Intended version axis for re-released CMS files. Constant = 1 for every row — only one CMS vintage of each year has been ingested, so this never disambiguates rows today. Reserved for future restatements. |
| parse_revision | int | Vlada parser revision number. Constant = 1 for every row. Provenance/lineage; no current distinguishing value. |
| parser_artifact_hash | string | SHA-256 of the parser code artifact that produced the row (lineage). 6 distinct values — one per report_year's parse run (same parser, per-run artifact). Not a data field. |
| source_url | string | CMS download URL of the source ZIP, one per year. e.g. https://www.cms.gov/files/zip/ma-hedis-pufs-2024.zip (2019 uses the differently-named hedis-ma-puf-2019.zip). 6 distinct, perfectly 1:1 with report_year. Provenance. |
| sha256_content_hash | string | SHA-256 of the source file content (the HEDIS PUF ZIP/sheet). 6 distinct — exactly one per report_year, confirming a single source file backs each year. Use for source-integrity / dedup verification, not as a row key. |

Tools that read it: get_hos

Query it: `query_substrate` with `SELECT ... FROM medicare_silver.hedis_hos_frm WHERE ... LIMIT 100`; read `describe_data_source("medicare_silver.hedis_hos_frm")` first.
