← Methods repository
concept

Informative Presence and Observation-Process Bias

Bias arising when being present in a routinely collected dataset, having more encounters, or having measurements at particular times is related to health status, exposure, or outcome risk, so the observed data represent the care-seeking and clinical-monitoring process as much as the disease process.

Bias_Controlinformative-presenceinformative-observationehr-biasobservation-processvisit-processmissing-datameasurement-biassurveillance
Methods reference only. Use primary source citations and local policy before applying this in a study protocol, regulatory submission, payer dossier, or clinical decision.

In plain language

Informative presence means the fact that a patient appears in the data, or has many measurements, tells you something about their health. In routine care, people are not measured on a research schedule; they are measured when they seek care, are referred, become ill, or are being monitored. If an analysis ignores that process, it may study who was observed instead of what truly happened.

Informative presence and observation-process bias

is the routine-data problem that patients are observed because they interact with care. In EHR and many linked datasets, people with more illness, better access, pregnancy, specialist referral, complications, or clinician concern have more visits, more diagnoses, more labs, and more opportunities to be measured. The absence of data is also informative: a missing HbA1c, no blood pressure, or no recorded diagnosis may mean low need, poor access, outside care, network leakage, death, or simply no visit.

Core conceptual distinction

Surveillance/detection bias concerns differential discovery of outcomes once people are under observation. Informative presence is broader: the observation process itself is related to the exposure or outcome. Cross-sectionally, inclusion in an EHR or the number of encounters can be a marker of health status. Longitudinally, measurement times are often outcome-dependent: a patient has creatinine checked because kidney function is worsening, a cancer patient has scans because symptoms changed, or a diabetic patient has frequent HbA1c values because control is poor. Standard complete-case, last-observation-carried-forward, or naive mixed models can then estimate the encounter process rather than the target health trajectory.

Pros, cons, and trade-offs

- Visit count adjustment vs causal overadjustment. Pre-index encounter counts can reduce bias from differential observability. Post-index visit counts may be mediators or colliders if the exposure changes monitoring or emerging disease drives visits. - Complete-case lab analysis vs observation-process modeling. Complete cases are easy to analyze but often select the sickest, most engaged, or most monitored patients. Inverse-intensity weighting, joint models, multiple outputation, or sensitivity analyses are harder but make the observation process explicit. - EHR-only inference vs linked data. EHR-only analyses can describe patients actively observed in that health system. Linked claims, registries, and mortality data improve observability but introduce linkage selection. - Prediction vs causal inference. Informative presence can improve prediction inside the same health system because encounter frequency is predictive. For causal or transportable inference, the same signal can be bias if it is treated as disease biology.

When to use

Diagnose this bias when cohort entry requires visits or measurements, when an exposure group has more clinical contact, when outcomes or covariates are extracted from EHR encounters, when longitudinal labs/vitals are irregular, when specialty referral defines the data source, or when prediction models use routinely collected measurements. It is especially relevant for pregnancy, oncology surveillance, chronic kidney disease labs, diabetes HbA1c, depression diagnoses, pediatric growth measures, and any EHR phenotype sensitive to encounter volume.

When NOT to use - and when it is actively misleading

- Do not treat missing routine-care measurements as missing completely at random without showing that visit and measurement patterns are unrelated to exposure and outcome risk. - Do not adjust for total post-index visits as a universal fix. If visits are caused by early outcome symptoms, toxicity, pregnancy, or treatment monitoring, adjustment can block causal pathways or open colliders. - Do not interpret an EHR prevalence estimate as population prevalence unless the denominator represents the target population and non-users of the health system are accounted for. - Do not carry last observation forward across long gaps as if the patient were stable; the gap may be the informative signal. - Do not compare groups with different network leakage or insurance capture without a sensitivity analysis for out-of-system care.

Data-source operational depth

Claims with continuous enrollment are more population-denominator oriented than EHR, but encounter capture still depends on covered benefits, plan type, carve-outs, and care seeking; Medicare Advantage or capitated care can make absence of claims non-observation rather than no event. EHR data are the highest-risk source because labs, diagnoses, problem lists, and notes arise from care episodes. Registries often standardize scheduled assessments, reducing some observation bias, but registry enrollment and optional visits remain selected. Linked data can separate "no event" from "not observed" by combining claims, EHR, registry, and mortality, but the linked cohort may be more health-engaged than the full source population.

Worked example

Scenario

An EHR study compares kidney-function decline between two diabetes therapies using outpatient creatinine values. Drug A patients have more nephrology visits because they are sicker at baseline. Creatinine is measured more often when kidney function is worsening.

Dataset

Illustrative one-year observation patterns after treatment initiation.

groupn_patientsmean_baseline_egfrmean_creatinine_testspercent_with_no_followup_labobserved_mean_egfr_change
Drug A1500625.46%-5.8
Drug B1500742.124%-2.1

Steps

  • Tabulate the visit and lab process before modeling the clinical outcome.

  • Show that Drug A patients are measured more often and are more likely to have nephrology visits.

  • Fit the naive mixed model and then a sensitivity analysis using pre-index utilization, baseline kidney function, and inverse observation-intensity weights.

  • Repeat using a fixed assessment window, such as the lab closest to 12 months within a narrow window, and report the proportion unobserved.

Result

If the Drug A decline shrinks after modeling observability, the naive estimate was partly driven by outcome-dependent monitoring rather than true treatment-associated decline.

Runnable example

python implementation

Diagnose informative observation by summarizing encounter and measurement patterns.

import pandas as pd
import statsmodels.formula.api as smf

def observation_process_diagnostics(df):
    # One row per patient with exposure, outcome, encounter_count, n_measurements,
    # any_measurement, baseline_risk, age, and site.
    summary = df.groupby("exposure").agg(
        n=("patient_id", "size"),
        mean_encounters=("encounter_count", "mean"),
        mean_measurements=("n_measurements", "mean"),
        pct_any_measurement=("any_measurement", "mean"),
        outcome_rate=("outcome", "mean"),
    )
    visit_model = smf.poisson(
        "encounter_count ~ exposure + baseline_risk + age + C(site)",
        data=df,
    ).fit(cov_type="HC3")
    measurement_model = smf.logit(
        "any_measurement ~ exposure + baseline_risk + age + encounter_count + C(site)",
        data=df,
    ).fit(disp=0)
    return summary, visit_model, measurement_model
r implementation

Encounter-count and measurement-availability diagnostics before modeling outcomes.

observation_process_diagnostics <- function(df) {
  summary <- aggregate(cbind(encounter_count, n_measurements, any_measurement, outcome) ~ exposure,
                       data = df, FUN = mean)
  visit_model <- glm(encounter_count ~ exposure + baseline_risk + age + factor(site),
                     family = poisson(), data = df)
  measurement_model <- glm(any_measurement ~ exposure + baseline_risk + age +
                             encounter_count + factor(site),
                           family = binomial(), data = df)
  list(summary = summary, visit_model = visit_model, measurement_model = measurement_model)
}