Skip to contents

A structured approach to registry data integration

Health and social registries hold data in many different structures. Research questions and operational definitions also change during a project. This vignette describes a modular framework that makes analysis-ready datasets simpler to build and to reproduce. It works for cross-sectional summaries and for high-frequency longitudinal analyses.

The challenge

Most epidemiological analyses involve more than two variables. A typical research question is:

“Estimate the effect of X on Y, adjusted for education, income, sex, birth country, comorbidity, and time since diagnosis.”

The question is simple to state. Each adjustment variable needs its own data work:

  • Education is recorded yearly in administrative databases, but you want the level “on the date of diagnosis.”
  • Comorbidity can need a scan of all inpatient and outpatient ICD codes across 10 or more years to build a Charlson index.
  • Time since diagnosis needs the first occurrence of a disease, and all other data aligned to that date.
  • Income needs adjustment for inflation and weighting by household.

Each variable needs several joins, filters, date comparisons and aggregations.

A common approach builds a wide person-level dataset with pre-calculated variables (one record per person). This works for static analyses. It fails when the research question changes, for example to stratify by calendar year, add time-varying covariates or lag an exposure.

Each such change often means that you rebuild much of the dataset.

The skeleton framework

This approach starts with a structural skeleton, not with the complete dataset.

The skeleton is a long-format table that defines the unit of analysis. It has one row per person per time period, for example one row per person per week. All later data attach to this time structure. For example:

id isoyearweek isoyear
100001 2010-01 2010
100001 2010-02 2010
100001 2010-03 2010
100002 2009-52 2009
100002 2010-01 2010

The skeleton contains:

  • One row per person and time period within the analysis window
  • No exposure, outcome, or covariate data at the start
  • Weekly rows (isoyearweek) in the analysis window, and yearly rows (isoyear) for the years before it

create_skeleton() builds weekly rows from week 01 of isoyear_min to isoyearweek_max. Each ISO year from 1900 to isoyear_min - 1 gets one yearly row. swereg has no monthly or daily skeleton.

After you build the skeleton, you add the data to it one step at a time. The data are:

  • Outcomes: binary indicators for events of interest (e.g., myocardial infarction occurrence)
  • Exposures: treatment or intervention status (e.g., vaccination, hospitalization, benefit receipt)
  • Covariates: time-fixed (e.g., sex), semi-time-varying (e.g., annual income), or high-resolution (e.g., new diagnoses)

Each step is a separate operation with standard joins and transformations. This gives three advantages:

  • You can run, debug, or change one step without the others
  • The source of each variable stays visible
  • The original time structure stays intact

When an analysis needs one row per person (e.g., logistic regression, baseline tables), you collapse the skeleton at the last stage.

Temporal data classification

Registry data change over time in three ways, and the skeleton handles each of them:

1. Time-invariant data (demographics, baseline characteristics)

A variable that does not change gets the same value on all rows for the person:

  • Sex assigned at birth, birth country, genetic markers

2. Periodically updated data (socioeconomic status, family structure)

A variable with a regular update cycle gets its value on all rows within the period it covers:

  • Annual income from tax records
  • Family composition, marital status
  • Education level, which can change from year to year
  • Employment status

3. Event-based data (diagnoses, prescriptions, deaths)

A variable tied to an event gets its value on the rows for the periods when the event occurred:

  • Hospital admissions and diagnoses
  • Prescription dispensing dates
  • Surgical procedures
  • Death dates and causes

Methodological advantages

The skeleton gives these practical benefits:

  • Data quality checks: missing rows show where follow-up stops.
  • Changes to the analysis: to redefine an exposure or add a lag, you change only the step that makes that variable.
  • Time-varying covariates: variables with different time resolutions (annual income, daily prescriptions) join on the matching time unit.
  • Multiple outcomes: one skeleton supports the analysis of several endpoints at the same time.

Example: a model of sickness absence after COVID-19 infection. The skeleton spans person-weeks from March 2020 to December 2022. You add these data in sequence:

  • Positive COVID-19 test dates from laboratory databases
  • Inpatient diagnoses from hospital registers
  • Sickness absence benefits from social insurance records
  • Income and education from administrative data
  • Age, calculated for each follow-up date
  • Outcome variable: weekly sickness absence status (binary)

The result supports time-to-event models, generalized estimating equations, fixed-effects regressions, or conditional logistic regression. The choice depends on how you aggregate time and how you encode the variables.

The two-step swereg workflow

swereg implements this skeleton concept through two steps:

Step 1: create the skeleton

  • Create the time-structured skeleton
  • Add raw registry data in sequence (demographics, diagnoses, prescriptions, etc.)
  • Derive analysis-ready variables (composites, first-occurrence markers, quality filters)
  • Result: a complete skeleton with all data and derived variables

Step 2: analyse the skeleton

  • Collapse weekly data to yearly (or other time units) as needed
  • Create analysis datasets for specific research questions
  • Run descriptive statistics, regression models, or survival analyses
  • Result: final analysis outputs

You can debug, change, or rerun each step on its own.

Software implementation

The swereg package has functions to:

  • Define skeletons for populations with given follow-up periods
  • Add and aggregate registry data in the skeleton
  • Calculate exposures and outcomes from ICD, ATC, and other medical classification codes
  • Align data in time (e.g., find the income or education closest to a diagnosis date)
  • Handle time relationships and links to calendar years

The package gives:

  • Consistent time handling (ISO week standards, rules for partial overlap)
  • Operational definitions that you can read in the code (e.g., the criteria for “hospital admission”)
  • Reproducible methods across research projects and teams

Getting started

To learn swereg, read the vignettes in this order:

  1. “Creating the skeleton”: build the time grid, add registry data, and derive variables
  2. “Analysing the skeleton”: collapse to the right granularity and run analyses

For production-scale pipelines with incremental rebuilds, see “The skeleton pipeline”.

Summary

Most registry-based variables come from deliberate transformations, not from direct extraction. The skeleton makes each transformation a separate step that you can maintain and debug. The swereg package has functions for the common steps.