CMS-1500 / 837P Professional Claim Fields
The paper form (CMS-1500, maintained by NUCC) and its electronic equivalent (837P transaction) that physicians and other non-institutional suppliers use to bill Medicare, Medicaid, and commercial payers; each claim carries up to 12 header-level diagnosis codes and one or more service lines, each with a diagnosis pointer that links the procedure to the applicable subset of header diagnoses — the foundational structure that determines what diagnosis is "attached to" a procedure in any professional claims analysis.
In plain language
The CMS-1500 form (also called the 837P in its electronic version) is the billing record that doctors and other outpatient providers send to insurance companies for every office visit, lab test, or procedure they perform. Each form lists up to 12 diagnoses for the entire visit, then has separate line entries for each procedure — and each procedure line contains a pointer telling the payer which of those 12 diagnoses explains why that specific service was done. Researchers use these records to count outpatient visits, identify conditions, and track which provider saw a patient, but must be careful because many databases drop the pointer field, leaving the diagnosis-to-procedure link ambiguous.
The CMS-1500 / 837P professional claim
is the billing instrument used by physicians, nurse practitioners, physician assistants, therapists, laboratories, and most other non-institutional healthcare suppliers (collectively, "Part B suppliers" in Medicare terminology). It is distinct from the UB-04 / 837I institutional claim, which hospitals use for inpatient admissions and outpatient facility services. Understanding the structure of the professional claim — particularly the relationship between header-level diagnoses and the line-level diagnosis pointer — is foundational to any study built on outpatient or professional claims data, because it determines what diagnostic information can be attributed to a specific procedure or encounter.
Paper form and electronic transaction
The CMS-1500 is the paper form maintained by the National Uniform Claim Committee (NUCC). Its electronic equivalent is the HIPAA-mandated 837P (Professional) ASC X12 transaction, which all payers must accept for electronic claims. Research databases derived from Medicare carrier files, commercial professional claims, or Medicaid professional claims are all downstream representations of 837P data. The field names and box numbers in the CMS-1500 form map directly to 837P loop/segment identifiers, and most research data dictionaries use the CMS-1500 box numbers as the conceptual reference.
Claim anatomy: header and service lines
A professional claim has two structural layers:
Header (boxes 1–23 and 25–33): Contains patient and insurance information, the provider identifiers (billing provider NPI in box 33; referring/ordering provider NPI in box 17), the date of the encounter if it spans multiple lines, and — most critically for diagnosis ascertainment — Item 21: the diagnosis code list (up to 12 ICD-10-CM codes, labeled A through L). These 12 codes are a claim-level list; there is no "principal diagnosis" concept on professional claims. The first-listed code (position A) is colloquially treated as the "primary" reason for the visit, but that designation is a billing convention and not a clinically adjudicated principal diagnosis. This matters substantially for phenotype algorithms: the ambiguity around which of the 12 header codes is the "main" reason for the visit is a well-known limitation of professional claims that motivates cautious dx-ascertainment strategies.
Service lines (box 24, columns A–J): Each claim can have multiple service lines — typically one per CPT/HCPCS procedure billed on that claim. The key fields in box 24 are: - 24A: Service date(s) — from/through dates for the procedure; professional claims typically have identical from/through dates for most outpatient services. - 24B: Place of service (POS) — a two-digit CMS code indicating the physical setting where the service was rendered (e.g., 11 = Office, 21 = Inpatient Hospital, 22 = On Campus Outpatient Hospital, 23 = Emergency Room, 31 = Skilled Nursing Facility). POS is the primary setting variable on professional claims and is how analysts distinguish an office visit from a hospital-based outpatient visit for the same CPT code. - 24D: Procedure code (CPT or HCPCS Level II) plus up to four two-character modifiers that refine the procedure (e.g., modifier -25 for a significant, separately identifiable E/M service; modifier -26 for professional component of a diagnostic service). - 24E (Diagnosis Pointer): One to four letters (A–L) referencing the header diagnoses that apply to this specific service line. This is the ONLY line-level diagnosis linkage in the professional claim. To know what diagnosis a CPT code was billed for, an analyst must look up which of the up to 12 header codes the pointer references. - 24G: Units — the quantity of services rendered (e.g., number of units of a drug administered, number of minutes for time-based services). - 24J: Rendering provider NPI — the individual clinician who actually performed the service. This is distinct from the billing provider NPI in box 33, which is often the practice group or facility billing entity. In individual provider attribution studies, rendering NPI is the correct identifier.
The diagnosis pointer — the central construct for RWE
The diagnosis pointer in 24E is arguably the most important and most misunderstood field for researchers. It links the procedure to 1–4 of the 12 header diagnosis codes. Without resolving the pointer, an analyst cannot determine which diagnosis was "the reason for" a given procedure. Example: a claim with 6 header diagnoses including diabetes (E11.9), hypertension (I10), and chronic kidney disease (N18.3) might have three service lines — an E/M visit (CPT 99213) pointing to all three, a nephrology consultation (CPT 99244) pointing to only N18.3, and a hemoglobin A1c test (CPT 83036) pointing only to E11.9. Without the pointer, attributing the lab to diabetes requires inference; with the pointer, it is explicit.
Critical limitation in research databases: dropped pointers
Many commercial research databases and some Medicare data products do not carry the diagnosis pointer at the line level in their standard extracts. When pointers are absent, analysts face a fundamental ambiguity: which of the up to 12 header diagnoses should be attributed to a given CPT line? The conservative and most common response is to use all header diagnoses at the claim level — treating every diagnosis on the claim as relevant to every procedure — which inflates the apparent diagnostic burden and can produce false-positive phenotype hits. This is why most professional claims phenotype algorithms default to claim-level (not line-level) diagnosis ascertainment as the conservative approach, even when pointer data are theoretically available. Analysts should document whether pointer data are available and used in their database, as it is a material methodological distinction.
Provider identifiers and the attribution trilemma
A professional claim carries at minimum three provider NPI fields: rendering (box 24J), billing/group (box 33), and referring (box 17). For provider-level RWE studies — evaluating practice variation, quality of care, or specialty-specific outcomes — the choice of NPI drives the entire attribution: rendering NPI gives the individual clinician who delivered the service; billing NPI gives the practice or group; referring NPI traces who ordered the visit. Using billing NPI in place of rendering NPI conflates individual variation with group-level variation. In large multispecialty practices or hospital-based outpatient settings, the billing entity's NPI may represent hundreds of providers, making practice-level attribution nonsensical for individual-level studies. This rendering vs billing NPI distinction is the most common provider-attribution error in professional claims research.
Charges, allowed amounts, and adjudication fields
The claim carries the submitted charge (box 24F per line and box 28 for total), but research-relevant costs are the payer-allowed amount and the patient paid amount, which appear in adjudication fields in the data extract (not on the CMS-1500 form itself — the form goes to the payer, not back to the provider as an ERA). In Medicare FFS carrier data, the allowed amount reflects the Medicare fee schedule amount; in commercial claims, it reflects the contracted rate. The difference between submitted charge and allowed amount (the "contractual adjustment") is invisible to the provider in many commercial databases and should not be confused with a denial.
Other notable fields
Box 23 carries the prior authorization number when required. The CLIA number in box 23 (for laboratory services) identifies the performing lab for diagnostic test claims. Box 20 ("outside lab") indicates whether laboratory work was referred out, which matters for distinguishing in-house lab from reference-lab claims in utilization studies.
Institutional versus professional claim: why the distinction matters for RWE
A patient hospitalized for a procedure will generate both an institutional claim (UB-04/837I from the hospital) and one or more professional claims (CMS-1500/837P from the attending physician, surgeon, anesthesiologist, radiologist, etc.). Counting both would double-count the visit. Most cohort-construction logic uses the institutional claim to identify the hospitalization and uses professional claims to identify outpatient events; merging them without de-duplication produces inflated counts. The structural difference — UB-04 has a principal diagnosis and a revenue code per line; CMS-1500 has a diagnosis list plus a pointer per line — means that the same ICD-10 code can appear on both claim types with different positional meaning.
RWE significance: professional claims carry most outpatient diagnosis volume
In US administrative claims databases, the large majority of outpatient diagnoses are recorded on professional claims, not institutional. Common phenotype algorithms follow the "2 OP codes" convention (at least 2 outpatient professional claims with the relevant ICD code on different dates), relying entirely on the claim-level header diagnoses. The accuracy of any outpatient phenotype, the correct count of E/M visits, the site-of-care determination (from POS), and the attribution of care to a specific provider (via rendering NPI) all depend on correct interpretation of the CMS-1500 / 837P structure described here.
Pros, cons, and trade-offs
- vs. UB-04 / 837I institutional claims: Professional claims cover more encounter types (every outpatient visit, procedure, lab, imaging, and Part B drug administration) and are therefore the dominant source of outpatient diagnosis and utilization data. Institutional claims have a true principal diagnosis (adjudicated by the facility under the Uniform Billing guidelines) and revenue codes that give service-type granularity, but they cover only facility events. For any outpatient-dominant phenotype (e.g., "2 OP diagnoses ≥30 days apart"), the professional claim is the operative data source. Prefer professional claims for outpatient encounter and diagnosis ascertainment; prefer institutional claims for inpatient event identification and principal-diagnosis-based phenotypes. - vs. EHR encounter data: The professional claim's POS and CPT codes provide setting and procedure with high consistency across providers because billing accuracy is financially incentivized. EHR data has richer clinical detail (labs, vitals, problem list) but is visit-driven, provider-specific, and lacks a standardized procedure taxonomy across systems. Prefer professional claims for procedure/utilization counting across a defined population; prefer EHR for severity, lab-based phenotypes, or when clinical detail is required. - Diagnosis pointer availability: When pointer data are present in the research extract, line-level diagnosis attribution is more precise and reduces false-positive procedure-diagnosis pairings. When pointer data are absent (common in commercial databases), claim-level attribution is the only option and introduces diagnosis–procedure misattribution that can inflate comorbidity burden and confound phenotype specificity. This is a database-specific limitation that analysts must document. - Rendering vs. billing NPI trade-off: Rendering NPI gives individual-level attribution but may be missing or filled with group NPIs in some older claims or in certain billing practices. Billing NPI is more consistently populated but conflates individual and group. For provider-level studies, validate rendering NPI completeness in the target database before committing to an attribution strategy.
When to use
Use professional claim fields as the primary data source when: (1) Identifying outpatient encounters, ambulatory E/M visits, or outpatient procedures; (2) Ascertaining diagnoses using "2 OP" or "1 OP" conventions for a phenotype algorithm; (3) Determining site of care (POS code) for outpatient services; (4) Counting procedure-level units (e.g., number of infusions, number of imaging studies); (5) Attributing care to an individual rendering provider for physician-level analyses; (6) Identifying Part B drug administrations via HCPCS J-codes on professional claims; (7) Any study where the dominant utilization is ambulatory rather than inpatient.
When NOT to use — and when professional claims are actively misleading or dangerous
- As the sole source for inpatient events. A hospitalization generates professional claims from multiple providers, but the encounter itself is defined by the institutional claim. Using professional claims to count inpatient stays risks counting multiple clinicians' claims as separate admissions, severely inflating inpatient event rates. - When line-level diagnosis attribution is required but pointer data are absent. If the research question requires knowing exactly which diagnosis prompted a specific procedure (e.g., an imaging study for cancer surveillance versus pain), and the database lacks diagnosis pointers, the answer is not obtainable from professional claims alone without probabilistic inference. Presenting claim-level attribution as line-level attribution in this setting produces misclassified procedure-diagnosis pairs. - When the "primary reason for visit" must be adjudicated. Position A in Item 21 is a billing decision by the coder, not a clinical adjudication. For studies where the principal reason for an outpatient visit is outcome-relevant (e.g., characterizing visits specifically for a condition vs. incidental coding), using first-listed outpatient diagnosis as a surrogate for "primary diagnosis" imports substantial measurement error. This contrasts with inpatient principal diagnosis, which is subject to UHDDS guidelines and payer audit. - When rendering NPI is consistently missing or defaulted to group NPI. In some databases or billing configurations, individual rendering NPIs are not reported or are filled with the group NPI, making individual provider attribution impossible. Proceeding with a provider-level study without validating NPI completeness and rendering vs. billing NPI fill rates produces an attribution analysis anchored to a meaningless identifier. - For Medicare Advantage patients when encounter data are incomplete. MA plans submit encounter data rather than FFS claims. In some MA data products, professional-claim-equivalent encounter records may be incomplete or missing line-level detail. Treating MA encounter data as equivalent to FFS professional claims without source-specific validation can produce differential outcome and covariate misclassification.
Worked example
Scenario
A pharmacy outcomes analyst is building a cohort of adults with type 2 diabetes who received a new GLP-1 receptor agonist injection (HCPCS J3490) at an outpatient clinic. She pulls all professional claims for a single patient — Patricia H., age 57 — to check which diagnoses were attached to the injection visits versus her regular office visits. The claim below is one of three service lines on a single professional claim submitted by her endocrinologist's group. The analyst needs to decide: how many of the 12 header diagnoses should be counted as "present on this visit," and which diagnoses can be attributed specifically to each service line?
Dataset
One professional claim for Patricia H., showing the Item 21 header diagnoses (A–L) and three service lines from box 24. This is the structure an analyst sees in a professional claims research database.
| field | value |
|---|---|
| Claim header: Item 21 diagnoses | A=E11.9 (T2DM), B=I10 (HTN), C=E78.5 (hyperlipidemia), D=Z79.4 (long-term insulin use), E=E11.65 (T2DM with hyperglycemia), F=Z00.00 (general exam), G=J34.89 (other nasal disorders), H=M54.5 (low back pain), I=K21.0 (GERD), J=Z82.49 (family hx heart disease), K=Z96.641 (presence of knee prosthesis), L=E66.9 (obesity) |
| Line 1: box 24A (service date) | 2023-08-15 |
| Line 1: box 24B (place of service) | 11 (Office) |
| Line 1: box 24D (procedure) | CPT 99214 (office/outpatient visit, moderate complexity E/M) |
| Line 1: box 24E (diagnosis pointer) | A, B, C, E |
| Line 1: box 24G (units) | 1 |
| Line 1: box 24J (rendering NPI) | 1234567890 (Dr. Elena Reyes) |
| Line 2: box 24A (service date) | 2023-08-15 |
| Line 2: box 24B (place of service) | 11 (Office) |
| Line 2: box 24D (procedure) | HCPCS J3490 (unclassified drug — GLP-1 injection) |
| Line 2: box 24E (diagnosis pointer) | A, E |
| Line 2: box 24G (units) | 1 |
| Line 2: box 24J (rendering NPI) | 1234567890 (Dr. Elena Reyes) |
| Line 3: box 24A (service date) | 2023-08-15 |
| Line 3: box 24B (place of service) | 11 (Office) |
| Line 3: box 24D (procedure) | CPT 83036 (hemoglobin A1c) |
| Line 3: box 24E (diagnosis pointer) | A, D, E |
| Line 3: box 24G (units) | 1 |
| Line 3: box 24J (rendering NPI) | 1234567890 (Dr. Elena Reyes) |
Steps
Count the header diagnoses: Item 21 has 12 codes (positions A through L). All 12 are associated with this claim at the claim level. If the research database drops diagnosis pointers, an analyst must attribute all 12 diagnoses to all 3 service lines — every procedure appears co-present with every diagnosis.
Service lines on this claim: 3 total. Each has a service date (2023-08-15), a POS code (11 = Office for all three), a procedure code, a diagnosis pointer, and a rendering NPI.
Resolving the diagnosis pointer for Line 1 (E/M visit CPT 99214): pointer letters A, B, C, E map to E11.9 (T2DM), I10 (HTN), E78.5 (hyperlipidemia), and E11.65 (T2DM with hyperglycemia). The E/M visit was billed for 4 of the 12 header diagnoses. The 8 remaining diagnoses (F through L plus D) are on the claim but NOT pointed to by Line 1.
Resolving the pointer for Line 2 (GLP-1 injection J3490): pointer letters A and E map to E11.9 and E11.65 only. The injection is explicitly attributed to T2DM — the 10 non-pointed diagnoses are irrelevant to this line. This is the correct denominator for a diabetes-specific utilization count: expr = 2 diagnosis codes pointed to line 2.
Resolving the pointer for Line 3 (HbA1c CPT 83036): pointer letters A, D, E map to E11.9 (T2DM), Z79.4 (long-term insulin use), and E11.65 (T2DM with hyperglycemia). The lab is pointed to 3 of the 12 header codes.
Provider attribution check: box 24J (rendering NPI 1234567890 = Dr. Reyes) is the same on all 3 lines. Box 33 on this claim carries the group NPI for the endocrinology practice (not shown). For a physician-level study, use rendering NPI from 24J. For a practice-level study, use the billing NPI from box 33.
Confirming the pointer arithmetic: total header diagnoses = 12 (A–L). Line 1 points to 4 (A, B, C, E). Line 2 points to 2 (A, E). Line 3 points to 3 (A, D, E). No line points to more than 4 diagnoses, and no line exceeds the 12-position limit. Total unique diagnosis codes pointed across all 3 lines = A, B, C, D, E = 5 unique positions out of 12. Diagnoses in positions F through L (7 codes) appear on the claim but are not pointed to by any service line.
Result
With pointers available: Line 2 (GLP-1 injection) is attributed to 2 diagnosis codes (positions A and E = T2DM diagnoses only), giving a precise diabetes-specific utilization count. Line 1 (E/M visit) is attributed to 4 diagnoses (A, B, C, E). Line 3 (HbA1c) is attributed to 3 diagnoses (A, D, E). Total service lines on this claim = 3; header diagnoses = 12; diagnoses pointed to by at least one line = 5 (out of 12); diagnoses present on claim but unpointed = 7. If pointer data are absent (common in commercial databases), all 3 lines would be attributed to all 12 diagnoses — inflating the apparent diagnostic burden per line by a factor of up to 12/2 = 6 for the injection line. This is the claim-level ambiguity that drives conservative phenotyping practice.
Runnable example
python implementation
Explodes a professional claims table into line-diagnosis pairs by resolving the diagnosis pointer, then counts pointer-attributed diagnoses per procedure line. Also demonstrates rendering vs. billing NPI extraction for provider attribution. Data are...
import pandas as pd
# Synthetic professional claim table (one row per service line)
# Field names follow standard Medicare carrier extract conventions.
claim_lines = pd.DataFrame({
"claim_id": ["CLM001","CLM001","CLM001"],
"line_num": [1, 2, 3],
"service_dt": ["2023-08-15","2023-08-15","2023-08-15"],
"pos_cd": [11, 11, 11], # 24B: place of service (11=office)
"proc_cd": ["99214","J3490","83036"], # 24D: CPT/HCPCS
"units": [1, 1, 1], # 24G: units
"rendering_npi": ["1234567890","1234567890","1234567890"], # 24J
"billing_npi": ["9876543210","9876543210","9876543210"], # box 33
"dx_ptr": ["A,B,C,E", "A,E", "A,D,E"], # 24E: diagnosis pointer
# Claim-level header diagnoses (Item 21, positions A-L)
"dx_A": ["E11.9"]*3, "dx_B": ["I10"]*3, "dx_C": ["E78.5"]*3,
"dx_D": ["Z79.4"]*3, "dx_E": ["E11.65"]*3, "dx_F": ["Z00.00"]*3,
"dx_G": ["J34.89"]*3,"dx_H": ["M54.5"]*3, "dx_I": ["K21.0"]*3,
"dx_J": ["Z82.49"]*3,"dx_K": ["Z96.641"]*3,"dx_L": ["E66.9"]*3,
})
# Build a lookup: position letter -> dx column name
pos_to_col = {letter: f"dx_{letter}" for letter in "ABCDEFGHIJKL"}
def resolve_pointers(row):
"""For one service line, return the list of ICD codes the pointer maps to."""
ptrs = [p.strip() for p in str(row["dx_ptr"]).split(",") if p.strip()]
codes = []
for letter in ptrs:
col = pos_to_col.get(letter.upper())
if col and col in row.index and pd.notna(row[col]):
codes.append(row[col])
return codes
# Line-level diagnosis attribution (pointer-resolved)
claim_lines["pointed_dx"] = claim_lines.apply(resolve_pointers, axis=1)
claim_lines["n_pointed_dx"] = claim_lines["pointed_dx"].str.len()
print("=== Pointer-resolved line-diagnosis pairs ===")
for _, row in claim_lines.iterrows():
print(f" Line {row['line_num']} ({row['proc_cd']}, POS {row['pos_cd']}): "
f"{row['pointed_dx']} (n={row['n_pointed_dx']})")
# Claim-level ascertainment (fallback when pointer absent)
dx_cols = [f"dx_{l}" for l in "ABCDEFGHIJKL"]
all_claim_dx = (
claim_lines[dx_cols].iloc[0].dropna().tolist()
)
print(f"\n=== Claim-level dx (all {len(all_claim_dx)} header codes, pointer absent) ===")
print(f" All lines attributed to: {all_claim_dx}")
# Provider attribution: rendering vs billing NPI
print("\n=== Provider attribution ===")
print(f" Rendering NPI (24J, individual): {claim_lines['rendering_npi'].unique()}")
print(f" Billing NPI (box 33, group): {claim_lines['billing_npi'].unique()}")
print(" -> Use rendering NPI for individual provider studies.")
print(" -> Use billing NPI for practice/group-level studies.")
# Diagnosis inflation factor when pointers are absent
avg_pointed = claim_lines["n_pointed_dx"].mean()
n_header = len([c for c in all_claim_dx if c])
print(f"\n=== Diagnosis pointer ambiguity metric ===")
print(f" Avg diagnoses per line with pointer: {avg_pointed:.1f}")
print(f" Diagnoses per line without pointer: {n_header}")
# n_header / avg_pointed = 12 / (avg ~3) ≈ 4
print(f" Inflation factor (claim-level vs pointed): "
f"{n_header} / {avg_pointed:.1f} = {n_header / avg_pointed:.1f}")r implementation
Resolves diagnosis pointers on professional claims to produce line-level dx pairs, and demonstrates rendering vs. billing NPI extraction for provider attribution. Uses base R and tidyr for the pointer explosion step. Implementation notes field is...
library(tidyr)
library(dplyr)
# Synthetic professional claim (one row per service line)
claim_lines <- data.frame(
claim_id = rep("CLM001", 3),
line_num = 1:3,
service_dt = rep("2023-08-15", 3),
pos_cd = rep(11L, 3), # 24B: place of service (11=office)
proc_cd = c("99214","J3490","83036"), # 24D: CPT/HCPCS
units = rep(1L, 3),
rendering_npi = rep("1234567890", 3), # 24J: individual clinician
billing_npi = rep("9876543210", 3), # box 33: practice group
dx_ptr = c("A,B,C,E","A,E","A,D,E"), # 24E: diagnosis pointer
# Header diagnoses Item 21 (positions A-L, carried on every line row)
dx_A = rep("E11.9", 3), dx_B = rep("I10", 3), dx_C = rep("E78.5", 3),
dx_D = rep("Z79.4", 3), dx_E = rep("E11.65", 3), dx_F = rep("Z00.00", 3),
dx_G = rep("J34.89",3), dx_H = rep("M54.5", 3), dx_I = rep("K21.0", 3),
dx_J = rep("Z82.49",3), dx_K = rep("Z96.641",3), dx_L = rep("E66.9", 3),
stringsAsFactors = FALSE
)
# Resolve the diagnosis pointer for each service line
resolve_pointers <- function(row_df) {
ptrs <- trimws(unlist(strsplit(row_df$dx_ptr, ",")))
cols <- paste0("dx_", toupper(ptrs))
valid <- cols[cols %in% names(row_df)]
codes <- unlist(row_df[valid], use.names = FALSE)
codes[!is.na(codes) & codes != ""]
}
pointer_results <- apply(claim_lines, 1, function(row) {
df <- as.data.frame(t(row), stringsAsFactors = FALSE)
codes <- resolve_pointers(df)
data.frame(
claim_id = row["claim_id"],
line_num = as.integer(row["line_num"]),
proc_cd = row["proc_cd"],
pos_cd = as.integer(row["pos_cd"]),
rendering_npi = row["rendering_npi"],
billing_npi = row["billing_npi"],
pointed_dx = paste(codes, collapse = "; "),
n_pointed = length(codes),
stringsAsFactors = FALSE
)
})
line_dx <- do.call(rbind, pointer_results)
cat("=== Pointer-resolved line-diagnosis pairs ===\n")
print(line_dx[, c("line_num","proc_cd","pos_cd","pointed_dx","n_pointed")])
# Claim-level ascertainment (when pointer absent)
dx_cols <- paste0("dx_", LETTERS[1:12])
all_claim_dx <- unique(unlist(claim_lines[1, dx_cols]))
all_claim_dx <- all_claim_dx[!is.na(all_claim_dx)]
cat(sprintf("\n=== Claim-level dx (pointer absent): %d header codes ===\n",
length(all_claim_dx)))
print(all_claim_dx)
# Provider attribution summary
cat("\n=== Provider attribution ===\n")
cat("Rendering NPI (24J, individual):", unique(claim_lines$rendering_npi), "\n")
cat("Billing NPI (box 33, group): ", unique(claim_lines$billing_npi), "\n")
# Diagnosis inflation when pointer absent
avg_pointed <- mean(line_dx$n_pointed)
n_header <- length(all_claim_dx)
cat(sprintf("\nInflation factor (claim-level vs pointed): %d / %.1f = %.1f\n",
n_header, avg_pointed, n_header / avg_pointed))