Pakker, algoritmer og hjælp

Hvilken pakke til hvilken opgave — og hvad der er på DST

Published

June 6, 2026

Dette er et opslags-hub: hvilket redskab løser hvilken opgave, om det er tilgængeligt på DST, og hvor du finder mere hjælp. Guiden tager dig frem til et analyseklart datasæt og peger dig mod de rigtige værktøjer til selve analysen — men underviser ikke i de statistiske metoder. Til det skal du bruge en statistiker, et kursus eller pakkernes egen dokumentation.


1. Validerede algoritmer

Publicerede, peer-reviewede metoder du kan bruge direkte til at konstruere kovariater. Koden til NMI og SEPLINE-algoritmen er under udvikling.

Algoritme Hvad den gør Artikel
Open Source Diabetes Classifier (OSDC) Klassificerer alle i Danmark som T1D, T2D eller ingen diabetes doi:10.2147/CLEP.S407019
Nordic Multimorbidity Index (NMI) Vægtet comorbiditetsscore (50 prediktorer) doi:10.2147/CLEP.S353398
SEPLINE — Socioeconomic Position in Epidemiological Research National vejledning til socioøkonomiske variable doi:10.2147/CLEP.S520772
Tip

Charlson som alternativ til NMI: både heaven::charlsonIndex() og EpiForsk (se nedenfor) beregner Charlson comorbiditetsscore fra LPR-diagnoser — begge er på DST.


2. Eksisterende funktioner du kan bruge til datahåndtering og udtræk

heaven — dansk registerdata-toolkit

(forudinstalleret på DST; ikke på CRAN — github.com/tagteam/heaven)

Funktioner bygget specifikt til danske registerdata af Thomas Gerds (KU, Biostatistik): Lexis-splitting til tidsvarierende kovariater, drug exposure-vinduer fra LMDB, risikoset-matching og Charlson-score.

Hvad heaven kan — og hvornår du bruger det

Lexis-splitting — opdel opfølgningstid på flere tidsakser, når en kovariat ændrer sig over tid (alder, kalenderperiode, tid siden eksponering).

library(heaven)

df_split <- lexisTwo(
  indat      = kohort,
  invars     = c("pnr", "inn", "out", "event"),   # id, startdato, slutdato, udfald
  splitvars  = list(age = c(40, 50, 60, 70),       # aldersgrænser
                    cal = c(2010, 2015, 2020))      # kalenderår
)
# Returnerer: én data frame med FLERE rækker per person — én per tidsinterval.
# Nye kolonner tilføjes for de aktuelle bånd (aldersgruppe, kalenderperiode mv.).
# Klar til en Cox-model med tidsvarierende kovariater.

Drug exposure fra LMDB — beregn eksponeringsperioder fra receptdata (fx “var personen i behandling med metformin på index-dato?”).

exp_tabel <- medicinMacro(
  indat = lmdb_data, id = "pnr", atc = "atc", eksd = "eksd",
  ddds = "ddds", maxdepot = 3
)
# Returnerer: én række per eksponeringsperiode per person med start- og slutdato
# for perioden. Brug efterfølgende joins til at afgøre eksponering på index-dato.

Charlson comorbiditetsscore fra LPR-diagnoser:

charlson_data <- charlsonIndex(indat = lpr_diag_data, id = "pnr",
                               code = "c_diag", code_type = "icd10")
# Returnerer: én række per person med samlet Charlson-score og binære indikatorer
# per Charlson-sygdomsgruppe. Funktionen matcher selv ICD-10-koder til kategorier.

Risikoset-matching — match cases til kontroller på index-dato:

matched <- riskSetMatch(ptid = "pnr", event = "event",
                        terms = c("koen", "foedselsaar"), dat = kohort, ratio = 5)
# Returnerer: matchet datasæt med matchID der kobler cases og kontroller.
Note

heaven er bekræftet tilgængelig på DST — brug library(heaven) direkte. Den er ikke på CRAN, så uden for DST skal den hentes fra GitHub.


EpiForsk — registerdata-hjælpefunktioner fra SSI

(CRAN; på DST — github.com/Laksafoss/EpiForsk)

Kode-delingspakke fra Statens Serum Institut. Særligt nyttig: flatten_date_intervals() der smelter overlappende hospitalskontakter til sammenhængende perioder — nødvendigt inden comorbiditetslookback. Dansk Charlson-score inkluderet.

Vigtigste funktioner og hvornår du bruger dem

flatten_date_intervals() — overlappende kontakter

En person kan have to indlæggelser der overlapper i LPR (fx en overflytning). Inden comorbiditetslookback skal overlappende perioder smeltes:

library(EpiForsk)

lpr_flat <- flatten_date_intervals(
  data = lpr_kontakter, id = "pnr",
  start_date = "d_inddto", end_date = "d_uddto"
)
# Returnerer: en data frame med sammensmeltet start/slut per person —
# overlappende perioder er reduceret til den samlede dækkede periode.

charlson_score() — dansk-kalibreret Charlson comorbiditetsscore fra ICD-10 (inkl. D-præfiks). Se callout nedenfor for hvad den kræver.

charlson <- charlson_score(data = lpr_diag_data, id = "pnr", icd_codes = "c_diag")
# Returnerer: én række per person med Charlson-score.
Important

Hvad kræver charlson_score()? Du skal selv udtrække en lookback-periode fra LPR (typisk 5 år inden index-dato) og give funktionen alle diagnoser i det vindue — A-, B- og G-type. Du behøver ikke at filtrere på specifikke ICD-koder på forhånd; funktionen matcher selv koderne til Charlson-kategorierne. D-præfikset (DG30 osv.) håndteres af EpiForsk — det skal ikke strippes inden.

# Eksempel: udtrækker lookback og giver alle diagnoser videre
# pnr og d_inddto sidder i lpr_adm — ikke lpr_diag

# Trin 1: bredest muligt tidsvindue for hele kohorten
min_lookback <- min(kohort$index_date) - 365.25 * 5   # tidligste lookback-start

# Trin 2: hent kontakter og join til diagnoser
lpr2_lookback <- lpr_adm %>%
  filter(pnr %in% !!kohort$pnr,
         d_inddto >= !!min_lookback) %>%              # bred forfiltrering
  select(pnr, recnum, d_inddto) %>%
  inner_join(
    lpr_diag %>%
      filter(c_diagtype %in% c("A", "B", "G")) %>%   # A/B/G til comorbiditet
      select(recnum, c_diag),
    by = "recnum"
  ) %>%
  collect() %>%
  left_join(kohort %>% select(pnr, index_date), by = "pnr") %>%
  filter(d_inddto >= index_date - 365.25 * 5,        # præcis per-person lookback
         d_inddto < index_date)

charlson <- charlson_score(data = lpr2_lookback, id = "pnr", icd_codes = "c_diag")

dataReporter — automatisk datakvalitetsrapport

(CRAN; bekræftet på DST — github.com/ekstroem/dataReporter)

Genererer automatisk en HTML/PDF-rapport over alle kolonner i et datasæt: fordeling, manglende værdier, outliers og typetjek. Nyttigt til at validere et nyt registerudtræk, inden du begynder analysen. Publiceret i Journal of Statistical Software.

library(dataReporter)
makeDataReport(mit_udtraek)   # åbner rapport i browser

Se også Fase 7 — Inspicér din data for de manuelle inspektionskommandoer.


fakeregs — syntetiske danske registerdata

(kun GitHub — kun lokalt — github.com/steno-aarhus/fakeregs)

Opdigtede, men strukturelt realistiske data for ni DST-registre. Til at øve og teste kode lokalt uden DST-adgang. Bruges ikke på serveren. Se Fase 6 — Første udtræk.


fastreg — SAS → parquet

(kun GitHub — github.com/dp-next/fastreg)

Struktureret pipeline til at konvertere et helt SAS-workspace til parquet. Kun relevant hvis du selv bygger et parquet-workspace fra bunden. Se Fase 4 — SAS → parquet.


3. Analyseværktøjer

Alle pakker i dette afsnit er bekræftet på DST (juni 2026). Guiden underviser ikke i de statistiske metoder — se pakkernes dokumentation for metodevalgene.

survival — fundamentet for overlevelsesanalyse

(CRAN; altid tilgængelig — cran.r-project.org/package=survival)

Giver Surv(time, status), coxph() og survfit() — de grundlæggende byggeblokke som alle overlevelsespakker nedenfor bygger ovenpå. Du behøver sjældent at kalde {survival} direkte til plot og tabeller, men library(survival) skal i toppen af dine analysescripts.

library(survival)
cox <- coxph(Surv(tid, event) ~ alder + koen + nmi_score, data = kohort)
summary(cox)   # HR, 95% KI, p-værdier — viderebehandles med Publish eller gtsummary

gtsummary — Table 1 og manuskripttabeller

(CRAN — cran.r-project.org/package=gtsummary)

Standard til manuskripttabeller: tbl_summary() laver Table 1 stratificeret på eksponering, tbl_regression() formaterer Cox- og logistisk regression, tbl_survfit() opsummerer overlevelsesmodeller. Publiceret i R Journal 2021.

Eksempel: Table 1
library(gtsummary)

tabel1 <- kohort %>%
  select(gruppe, alder, koen, nmi_score, occupation_cat) %>%
  tbl_summary(
    by = gruppe,                                               # stratifier på eksponering
    statistic = list(
      all_continuous()  ~ "{mean} ({sd})",                    # kontinuerte: middelværdi (SD)
      all_categorical() ~ "{n} ({p}%)"                        # kategoriske: n (%)
    ),
    missing = "no"
  ) %>%
  add_overall() %>%
  add_p()
Warning

Outputkontrol: Tælleværdier på 0–4 må ikke hjemsende. Manuel afrunding: round(x / 5) * 5. Z.gtsummary.addons::round_5_gtsummary() automatiserer det — ikke på DST, importér via datamanager.


carpenter — pipe-baseret tabelstruktur

(CRAN — github.com/lwjohnst86/carpenter)

Ældre alternativ til gtsummary med en simplere pipe-baseret API: start med outline_table(), tilføj rækker med add_rows() og afslut med build_table(). Lavet af Luke Johnston.

library(carpenter)

outline_table(kohort, "gruppe") %>%
  add_rows("alder",     stat_meanSD) %>%     # kontinuert: middelværdi (SD)
  add_rows("koen",      stat_nPct) %>%       # kategorisk: n (%)
  add_rows("nmi_score", stat_medianIQR) %>%  # kontinuert: median (IKR)
  build_table()

prodlim — Kaplan-Meier og Aalen-Johansen kumulativ incidens

(CRAN — github.com/tagteam/prodlim)

Estimerer og plotter overlevelseskurver og kumulativ incidens. Hist() håndterer competing risks med én statusvariabel: 0 = censureret, 1 = primær hændelse, 2 = konkurrerende hændelse (fx død). Brug prodlim til deskriptive kurver — riskRegression til regression.

Eksempel: KM-kurve og Aalen-Johansen
library(prodlim)

# Kaplan-Meier:
fit_km <- prodlim(Hist(tid, event) ~ gruppe, data = kohort)
plot(fit_km)

# Aalen-Johansen kumulativ incidens (competing risks):
# status: 0 = censureret, 1 = primær hændelse, 2 = konkurrerende (fx død)
fit_aj <- prodlim(Hist(tid, status) ~ gruppe, data = kohort)
plot(fit_aj, cause = 1)   # kumulativ incidens for primær hændelse
Note

KM alene overestimerer kumulativ incidens ved competing risks. Brug Aalen-Johansen (cause = 1) når competing events er til stede.


riskRegression — Cause-Specific Cox, Fine-Gray og absolut risiko

(CRAN — github.com/tagteam/riskRegression)

Til regression med competing risks. CSC() fitter Cause-Specific Cox (én model per årsag), FGR() fitter Fine-Gray subdistribution hazard. predictRisk() beregner absolut risiko ved specifikke tidspunkter. Score() validerer og sammenligner modeller (Brier-score, tidsafhængig AUC).

Eksempel: CSC-model og absolut risiko
library(riskRegression)
library(survival)

# Cause-Specific Cox:
csc_model <- CSC(Hist(tid, status) ~ alder + koen + nmi_score, data = kohort)
summary(csc_model)

# Absolut risiko ved 1, 3 og 5 år for primær hændelse:
ar <- predictRisk(csc_model, newdata = kohort,
                  times = c(1, 3, 5), cause = 1)
# ar: matrix — én kolonne per tidspunkt, én række per person

Publish — regressionsresultater klar til manuskript

(CRAN — github.com/tagteam/Publish)

regressionTable() tager en fittet model (Cox, logistisk, lineær) og returnerer en tabel med estimater, 95 % KI og p-værdier. plotConfidence() laver forest plots fra samme output.

library(Publish)
library(survival)

cox_model <- coxph(Surv(tid, event) ~ alder + koen + nmi_score, data = kohort)

regressionTable(cox_model)               # HR, 95% KI, p-værdier
plotConfidence(regressionTable(cox_model))   # forest plot

MatchIt — propensity score og eksakt matching

(CRAN — cran.r-project.org/package=MatchIt)

Matcher eksponerede til ueksponerede på observerede kovariater. Understøtter nearest-neighbor, eksakt og optimal matching. summary() giver balance-statistik (SMD), match.data() returnerer det matchede datasæt. Alternativ til heaven::riskSetMatch() med bedre balance-diagnostik.

Eksempel: 1:1 nearest-neighbor matching
library(MatchIt)

m <- matchit(eksponeret ~ alder + koen + nmi_score,
             data   = kohort,
             method = "nearest",   # nearest-neighbor matching
             ratio  = 1)           # 1:1

# Balance-tjek — SMD < 0.1 er tommelfingerregel:
summary(m, standardize = TRUE)

# Matchet datasæt:
matched <- match.data(m)

pec — prædiktionsfejlkurver

(CRAN — cran.r-project.org/package=pec)

Beregner og plotter Brier-score over tid til sammenligning og validering af prædiktionsmodeller. Niche — kun relevant ved prædiktionsmodeller; riskRegression::Score() dækker oftest behovet.


BuyseTest — Generalized Pairwise Comparisons

(CRAN, bekræftet på DST v3.3.3 — github.com/bozenne/BuyseTest)

Implementerer Generalized Pairwise Comparisons (GPC): sammenligner to grupper via win ratio, net benefit og win probability på prioriterede endpoints. Niche — relevant når du har et hierarki af endpoints og vil undgå klassiske event-time-antagelser.

library(BuyseTest)

# Ét time-to-event endpoint:
result <- BuyseTest(gruppe ~ tte(tid, event, threshold = 0),
                    data = kohort,
                    method.inference = "u-statistic")
summary(result)   # win ratio, net benefit, win probability

powerBuyseTest() beregner den nødvendige stikprøvestørrelse givet ønsket power og forventet effekt — nyttigt inden dataindsamling eller ansøgning.


kinship2 — pedigrees og kinship-matricer

(CRAN — cran.r-project.org/web/packages/kinship2)

Opretter pedigree-objekter fra forældre-barn-relationer og beregner kinship-koefficienter (sandsynlighed for delt allel: 0,5 = forældre/barn, 0,25 = søskende). Nyttigt til multigenerationelle familiestudier. Lavet af Terry Therneau (Mayo Clinic).

Eksempel: opret pedigree og beregn kinship
library(kinship2)

# Opret pedigree:
# DST's koen-variabel (1 = mand, 2 = kvinde) matcher kinship2's forventning direkte
ped <- pedigree(
  id    = familie$pnr,
  dadid = familie$pnr_far,   # 0 eller NA hvis far ukendt
  momid = familie$pnr_mor,   # 0 eller NA hvis mor ukendt
  sex   = familie$koen        # 1 = mand, 2 = kvinde
)

# Kinship-koefficienter:
km <- kinship(ped)

# Visualisér stamtræ:
plot(ped)

tame — klustrer medicineksponering fra LMDB

(CRAN — github.com/Laksafoss/tame)

Agglomerativ hierarkisk klustring af medicindata. Kombinerer ATC-klassifikation, timing og dosis i én custom distance-measure. medic() er den primære funktion. Relevant ved karakterisering af polyfarmacimønstre. Lavet af Anders Laksafoss (SSI).

Eksempel: klustrer medicinmønstre
library(tame)

# Klustrer på ATC-kode alene:
clust <- medic(lmdb_data, id = pnr, atc = atc, k = 5)
# k = ønsket antal kluster — vælg med scree-plot eller domæneviden

# Med timing-information (angiv som kolonneinterval):
clust <- medic(lmdb_data, id = pnr, atc = atc,
               timing = trimester_1:trimester_3,   # kolonner der angiver tidsvinduer
               k = 5)

summary(clust)   # opsummér klustrer
Note

id, atc og timing-argumenterne bruger bare kolonnenavne (NSE — ingen anførselstegn). lmdb_data skal have én række per receptekspedition.


Mulig inspiration — ikke bekræftet på DST

famnet (GitHub, eksperimentel) — identificerer familierelationer fra person-ID’er: givet et datasæt med PersonID, FaderID og ModerID finder fmn_siblings() alle søskendepar med relationstype. Relevant til familikobling på tværs af generationer i dansk registerdata. Lavet af Luke Johnston.

plotsurv (GitHub, ikke på DST) — publikationsklar Kaplan-Meier og Aalen-Johansen competing-risks-plots med at-risk-tabel, KI-bånd og censureringsprikker. plotsurv(survfit_objekt).

Z.gtsummary.addons (GitHub, ikke på DST) — udvider gtsummary med add_SMD() (standardiserede middeldifferencer til Table 1) og round_5_gtsummary() (afrunder tælleværdier til nærmeste 5 — relevant for DST’s outputkontrol).


4. Hvor får du mere hjælp?

Community og kurser — se den prioriterede hjælpeliste og kursuslinks i Fase 2 — R: det allermest nødvendige (Stack Overflow, Zheers R Coding Café, DDEA, R for Data Science, Epi R Handbook).

Institutionelt referencemateriale:

Kilde Hvad du finder
ctpteam/RDST “R on DST”-manual: projektopsætning, dataadgang, god kodepraksis på DST-serveren
ctpteam/DST Guide til LPR3, DST-manualer, slides og en heaven-PDF
steno-aarhus/registers-project-database SDCA’s egen database: variabellister, registerbeskrivelser og ansøgningsskabeloner til Sundhedsdatastyrelsen
github.com/tagteam riskRegression, prodlim, Publish, pec, heaven — Thomas Gerds og Brice Ozenne, KU Biostatistik

Næste skridt

Fase 16 — Eksport og hjemsendelse

Back to top