Tutorials › Propensity Score Matching and Instrumental Variables › Encoding Diagnosis and Procedure Histories

Time-Varying and High-Dimensional Confounding · Tutorial 621 of 699

Encoding Diagnosis and Procedure Histories

You will build auditable binary history indicators from claims records and learn how code mappings, date boundaries, repetition rules, and enrollment gaps affect their interpretation.

Advanced 11 min read

What You'll Learn

  • Define code groups and map diagnosis, procedure, and medication records consistently.
  • Construct binary indicators using explicit lookback windows and date boundaries.
  • Distinguish repeated events from duplicated claim lines when encoding histories.
  • Decide how incomplete enrollment and absent records should be represented.
  • Diagnose common coding choices that can distort a claims-based covariate.

From Claims Records to History Indicators

A claims file can contain many rows for one person: diagnosis codes, procedure codes, and medication records on different dates, sometimes repeated for the same encounter. Before these records can serve as covariates, an analyst must define what counts as a history and how that history becomes a variable. A binary history indicator records whether a person had at least one qualifying event in a specified code group and time window.

This construction is not merely data cleaning. Changing the code group, the lookback period, or the rule for repeated events changes what the covariate measures. For causal analyses, the date boundary is especially important: a baseline history covariate must be measured before treatment assignment or initiation, not partly from information that occurs after it.

Definition: Let \(t_0\) be the analysis index date for person \(i\), let \(W_i\) be a prespecified lookback window ending before \(t_0\), and let \(G_g\) be a defined group of codes for feature \(g\). The binary history covariate \(X_{ig}\) equals 1 if person \(i\) has at least one qualifying record with a code in \(G_g\) and an event date in \(W_i\); otherwise it equals 0, provided the person has adequate observable coverage of that window.

The definition has several parts that should be written down before creating variables. Specify the index date, the start and end of the window, which code systems and code versions are used, the mapping from codes to groups, which dates determine eligibility, and how repeated records are handled. For treatment comparisons, the window should end before treatment begins or is assigned. A common convention is to use the half-open interval \([t_0-L,t_0)\): the start date is included, and the index date itself is excluded. If same-day records could precede treatment, include them only under a clearly justified and consistently applied timing rule.

Code Groups and Window Rules

A code group can contain one code, a list of exact codes, or a defined range or prefix, depending on the coding system. For example, a hypothetical respiratory diagnosis group might include all codes beginning with J45 or J44 in a specified diagnosis-code version. A medication group might be defined by a list of product codes for a drug class. A procedure group might use a prespecified list of procedure codes. The mapping should be clinically interpretable and reproducible; vague instructions such as “include related codes” are not enough to reproduce a feature.

Groups need not be mutually exclusive. If a code is intentionally mapped to two groups, one record can activate both indicators; document that choice. If the aim is a partition of codes, instead define mutually exclusive groups and check that each included code maps to only one group. In either design, keep the original code and mapping available so a value of 1 can be traced back to qualifying records.

Lookback windows express the period of history represented. A one-year window, a recent-quarter window, and an ever-recorded history are different covariate definitions, even when they use the same code group. The window also needs to be feasible for each person. If claims are observed only for part of a requested window, no recorded event may mean “not observed” rather than “no event.” Do not automatically convert incomplete history to zero.

Worked Example: A Diagnosis Group in a Six-Month Window

Suppose a hypothetical analysis has an index date of July 1, 2025, and defines the baseline window as January 1 through June 30, 2025. A prespecified respiratory diagnosis group contains codes beginning J45 or J44. The records for three hypothetical patients are:

PatientDiagnosis records in the windowCoverage
AJ45.2 on February 10; J45.2 again on February 10Complete
BJ18.9 on March 4Complete
CNo qualifying record observedCoverage begins April 1

For Patient A, both records match the group and fall within the window. The binary rule asks whether there is at least one qualifying record, not how many claim lines appear, so \(X_{A,g}=1\). Patient B’s J18.9 record is not in the defined group, so \(X_{B,g}=0\). Patient C has no recorded qualifying event, but the data cover only April through June; the full January-to-June history is not observable. Code this value as missing or otherwise explicitly mark inadequate coverage, rather than treating it as a verified zero.

The repeated lines for A do not change the binary result. They may represent duplicate lines or multiple records for one encounter; either way, the stated “at least one” definition yields 1. The example also shows why code matching and coverage checks must both occur before assigning zero.

Formal Construction and Repeated Events

Suppose person \(i\) has \(m_i\) records in the eligible window. For record \(r\), define \(I_{ir,g}=1\) if its code belongs to \(G_g\), and \(I_{ir,g}=0\) otherwise. For a person with adequate window coverage, the any-event indicator is

$$ X_{ig} = \mathbb{1}\left(\sum_{r=1}^{m_i} I_{ir,g} \geq 1\right) $$

Equivalently, it can be calculated as one minus the product of the “not a match” indicators:

$$ X_{ig}=1-\prod_{r=1}^{m_i}(1-I_{ir,g}) $$

This identity follows directly from the two possible cases. If no record matches, every \(I_{ir,g}=0\), so the product is 1 and \(X_{ig}=0\). If at least one record matches, one factor is \(1-1=0\), so the product is 0 and \(X_{ig}=1\). This also explains why duplicating a matching record does not alter an any-event indicator: the product is already zero after the first match.

A binary indicator is only one possible repeated-event rule. An analyst may instead define a count, such as the number of distinct service dates with a matching diagnosis, or a threshold indicator such as “at least two qualifying dates.” These are different covariates and require their own rules. Specify whether “repeat” means multiple lines, multiple claims, multiple dates, or multiple encounters. When several codes occur on one claim, deduplicating to distinct claim dates can prevent a single encounter from being mistaken for repeated episodes.

Worked Example: One Event, Two Claim Lines, or Two Dates?

Consider a hypothetical patient with a complete 12-month lookback window, January 1 through December 31, 2024, before an index date of January 1, 2025. A medication group contains two specified product codes. The file has two matching lines on May 6, 2024, and one matching line on November 12, 2024. The analyst prespecifies two features: an any-use indicator and an indicator for use on at least two distinct dates.

All three lines match the product-code group and fall inside the window. For the any-use feature, the number of qualifying lines is 3, so

$$ X_{\text{any}}=\mathbb{1}(3\geq 1)=1 $$

For the repeat-use feature, first reduce the records to distinct qualifying dates: May 6 and November 12. There are 2 distinct dates, so

$$ X_{\text{at least 2 dates}}=\mathbb{1}(2\geq 2)=1 $$

If the second date were absent, the two claim lines on May 6 would still produce \(X_{\text{any}}=1\), but they would produce \(X_{\text{at least 2 dates}}=0\). Thus, counting rows would incorrectly classify duplicate lines as repeated use under the stated distinct-date rule. The data do not, by themselves, establish medication adherence or ingestion; these indicators represent claims records under the chosen definition.

Choosing and Auditing the Representation

Different representations answer different questions. An any-event indicator is compact and captures whether any coded history was observed in the window. A count retains frequency information, but can be sensitive to billing practices and duplicate records. Separate recent and longer-term indicators can distinguish timing, while a time-varying representation can retain when events occur. The choice should follow the intended feature definition and analysis, not whichever form is easiest to generate.

RepresentationWhat it recordsKey rule to specify
Any-event binaryAt least one qualifying recordCode group, window, and adequate coverage
CountNumber of qualifying records or eventsWhether to count lines, claims, dates, or encounters
Threshold binaryWhether a specified number of events is reachedThreshold and event-deduplication rule
Separate window indicatorsHistory in distinct time periodsNonoverlapping or intentionally overlapping boundaries

For a baseline covariate, post-index records must not leak into the feature. If a code is recorded after treatment begins, including it can encode a consequence of treatment or follow-up rather than pretreatment history. The distinction between treatment prediction and confounder control is important: a feature is not automatically appropriate for adjustment merely because it predicts treatment. The target is a well-defined pretreatment history consistent with the causal question.

Worked Example: Separate Recent and Earlier Diagnosis History

A hypothetical study uses an index date of January 1, 2025, and a diagnosis group \(G\). It defines two windows: an earlier window from January 1 through September 30, 2024, and a recent window from October 1 through December 31, 2024. Both windows are fully observed. One patient has a qualifying code on March 8, 2024, and another on November 19, 2024; a further matching record is dated January 1, 2025.

The March record activates the earlier-window indicator: \(X_{\text{earlier}}=\mathbb{1}(1\geq1)=1\). The November record activates the recent-window indicator: \(X_{\text{recent}}=\mathbb{1}(1\geq1)=1\). The January 1 record is on the index date and is outside both half-open baseline windows, so it activates neither indicator. This is true even though its code matches the group: code membership alone does not determine eligibility.

The resulting pair \((1,1)\) represents qualifying records in both specified periods. It does not mean that there were exactly two events, because the indicators record presence within each period, not event counts. If the analysis instead intended a single 12-month any-history covariate, the two earlier records would produce one indicator equal to 1; the index-date record would remain excluded.

Quality Checks and Failure Modes

An auditable construction should include checks of both the input records and the resulting person-level variables. At minimum, verify code formats and versions, date parsing, window endpoints, group membership, and coverage. Inspect how many records and people match each group before and after applying the window. For a binary feature, confirm that all nonmissing values are 0 or 1 and that every 1 can be traced to at least one qualifying record.

1
Freeze the definition.
Record the index-date rule, window boundaries, code-system version, and code-to-group mapping before producing the feature.
2
Apply temporal eligibility.
Keep only records in the specified pre-index window, using the same endpoint convention for every person.
3
Apply the event rule.
Match codes to the group, then deduplicate or count records according to the prespecified meaning of repetition.
4
Check observability and traceability.
Assign zero only when absence is interpretable under adequate coverage, and retain the records supporting each positive value.

Common warning signs include an unexpectedly large jump in prevalence after a code-version change, many qualifying records on the index date, implausible values caused by date parsing, and a feature that is nearly universal because a broad code prefix captured unrelated conditions. Very low prevalence can signal an overly narrow mapping, incomplete enrollment, or failure to normalize code formats. Compare a sample of assigned values against the underlying records, including both positive and zero cases.

No coding strategy eliminates limitations of claims data. A billed diagnosis is not identical to a confirmed disease, and a medication claim is not proof that medication was taken. Coding intensity can differ across people and settings, while changes in coverage can make recorded absence misleading. Code groupings should therefore be described as claims-based proxies for histories, not definitive clinical measurements. Consistent, explicit rules improve reproducibility, but they do not guarantee that the resulting variables capture every relevant confounder.

Common Mistake

Common mistake: “There is no matching code in the file, so the patient has no history.” This conclusion is not justified if the patient was observable for only part of the lookback window, if the code mapping omitted relevant codes, or if the records were filtered using the wrong date. The correction is to check code mapping, time eligibility, and window coverage separately. Assign zero only when the defined history was adequately observable and no qualifying record was found; otherwise represent the history as unknown or insufficiently observed.

Check Your Understanding

Answer each question using the stated coding and window rules. Solutions follow the questions.

  1. A person has a complete window and two matching diagnosis lines on one service date. What is the any-event binary value, and what is the count of distinct matching dates?
  2. A lookback window ends immediately before the index date. A matching procedure occurs on the index date. Should it activate the baseline indicator?
  3. A patient has no matching medication record but is enrolled for only half of the requested lookback window. Is a zero justified?
  4. Explain why counting claim lines may give a different repeated-event feature from counting distinct service dates.
  5. Give one advantage and one limitation of using an any-event binary instead of a count.

Solutions. (1) The any-event value is 1 because at least one qualifying record exists; the distinct-date count is 1. (2) No. The index date is excluded by the stated endpoint rule. (3) No. The unobserved half of the window prevents interpreting the absence of a record as no history; mark coverage as inadequate or the value as unknown. (4) Several matching lines can occur on one date, so the line count may exceed the distinct-date count without representing separate dates. (5) An any-event indicator is simple and unaffected by duplicate matching lines once a match exists; it loses frequency information and depends on the chosen code group and window.

Clinical Biostats