Saml & klargør datasættet

Joins, pivots og klargøring af dit analysedatasæt

Published

July 2, 2026

Du ankommer til denne fase med separate RDS-filer: din kohort fra Fase 10 og de variable du har udtrukket i Fase 11 - udfald, socioøkonomi og komorbiditet (plus evt. demografi fra Fase 6). Du forlader med ét analyseklart datasæt klar til Fase 13 - Analyse.

Tip

Kort fortalt: Form hvert udtræk til én række per person (med group_by() + slice() eller pivot_wider()), og kobl dem så sammen på pnr med left_join() til ét analyseklart datasæt.

Inden du kan analysere, skal du:

  1. Forme hvert udtræk til én række per person (de fleste registre er i langt format med mange rækker per person)
  2. Samle dem til ét analyseklart datasæt med left_join()

Det er det, denne fase handler om. Teknikken til trin 1 er enten group_by() + slice() eller pivot_wider() - valget afhænger af, hvad du vil have ud af registret. Trin 2 er altid left_join().

Note

Kodeeksemplerne bruger generiske stier og variabelnavne. Tilpas til dit projekts mappestruktur og kolonnenavne.


Hvad er et analyseklart datasæt?

Et analyseklart datasæt har én række per person og én kolonne per variabel - det vi kalder bredt format:

pnr index_date censor_date followup_years event alder koen nmi_score
001 2015-03-01 2022-07-14 7.4 0 58 2 12
002 2016-11-20 2019-11-20 3.0 1 63 1 7
Note

Eksemplet bruger et kohortestudie med exposed, event og followup_years. For et prævalensstudie vil kolonnestrukturen se anderledes ud - typisk uden opfølgningstid, men med en tværsnitsdato og kovariater målt på det tidspunkt. Teknikken i denne fase (joins, pivots, group_by() + slice()) er den samme uanset studiedesign.

Registrene du trækker fra - LPR, LMDB, BEF - er næsten altid i langt format med mange rækker per person. Denne fase viser, hvordan du former dem om og samler dem.

Hvad har du allerede gemt?

Hvert udtræk fra Fase 6, 9 og 11 m.fl. bør gemmes som sin egen RDS-fil - ét register, ét emne. Eksempel på hvad du typisk har:

Fil Indhold Nøglekolonner
full_cohort.rds Kohorte med index-dato pnr, index_date, exposed
extract_demens.rds Første demensdiagnose pnr, event_date (NA = ingen)
extract_doed.rds Dødsdato pnr, death_date (NA = i live)
extract_emigration.rds Første emigration pnr, emigration_date (NA = ikke emigreret)
extract_bef.rds Demografi ved index pnr, alder, koen
extract_nmi.rds Komorbiditet ved baseline pnr, nmi_score
extract_ses.rds Socioøkonomiske variable pnr, udda, indkomst, socio

Målet med denne fase er at samle dem til ét datasæt med left_join() - én ny kolonne per fil. Kohorten er rygraden: hvert udtræk kobles på via pnr og tilføjer sine kolonner - alle kohortemedlemmer bevares, og personer uden match får NA.

Important

Saml kun det du skal bruge. Det er fristende at beholde alle kolonner “for en sikkerheds skyld”. Gør det ikke. Afslut altid med select() og vælg eksplicit de kolonner analysen kræver. Et datasæt med kun de nødvendige kolonner er langt lettere at debugge og forstå.


To redskaber til at forme data

De to centrale operationer i denne fase er pivots og joins - de ligner hinanden i navn, men gør noget fundamentalt forskelligt:

Pivots Joins
Hvad det gør Former én tabel om - ændrer formen, ikke indholdet Kobler to tabeller - tilføjer kolonner fra en anden tabel
Input Én tabel To tabeller med en fælles nøgle (typisk pnr)
Output Samme data, ny form Bredere tabel med kolonner fra begge
Brugt til Langt → bredt format (pivot_wider) eller bredt → langt (pivot_longer) Saml kohort + udfald + kovariater til ét datasæt

Tommelfingerregel: Brug pivot når du vil ændre formen på én tabel. Brug join når du vil kombinere to tabeller.


Afledte variable: lav nye kolonner

Ud over at forme og koble skal du næsten altid beregne nye variable ud fra dem, du har. Det gør du med mutate() (introduceret i Fase 2): den tilføjer en kolonne, der er beregnet fra eksisterende kolonner.

library(dplyr); library(lubridate)

df <- df %>%
  mutate(
    # Alder ved index: antal dage mellem to datoer / 365.25 (et år = 365.25 dage pga. skudår)
    alder_ved_index = as.numeric(index_date - foed_dag) / 365.25,

    # BMI fra højde (m) og vægt (kg)
    bmi = vaegt_kg / (hoejde_m^2),

    # Binær hændelses-indikator: 1 hvis udfaldet skete før censurering, ellers 0
    event = if_else(!is.na(event_date) & event_date <= censor_date, 1L, 0L),

    # Kategorisér en kontinuerlig variabel i grupper
    alders_gruppe = case_when(
      alder_ved_index < 50 ~ "<50",
      alder_ved_index < 65 ~ "50-64",
      TRUE                 ~ "65+"     # alt andet (her: 65 og derover)
    )
  )

Et par vaner:

  • Beregn en variabel ÉN gang og genbrug den - så fx alder ved index er den samme i matchingen og i Table 1.
  • if_else() til ja/nej (to udfald); case_when() til flere kategorier. Sæt typen ens i alle grene (fx 1L/0L, eller tekst i alle).
  • Opfølgningstid (censor_date - index_date) beregnes typisk efter joinet, fordi den bruger datoer fra flere udtræk - se Kobl udtræk sammen.
Tip

mutate(), if_else() og case_when() er forklaret i Funktioner: oversigt.


Fasens sider

To kerne-sider fører dig fra separate udtræk til ét analyseklart datasæt:

  1. Langt ↔︎ bredt format: få hvert udtræk ned til én række per person. Forstå forskellen på langt og bredt format, og brug enten group_by() + slice() (én repræsentativ værdi per person) eller pivot_wider() (flere tidspunkter side om side).
  2. Kobl udtræk sammen: kobl udtrækkene på pnr (left_join(), inner_join(), semi_join(), anti_join()), stak to versioner af samme register lodret (bind_rows()), validér joinet, og beregn opfølgningstid og hændelsesvariabel. Her samles det endelige datasæt.

Rækkefølgen er bevidst: form først, kobl bagefter. Du kan ikke koble forudsigeligt, før hvert udtræk har én række per person.

To valgfrie tillægssider tager du kun, hvis dit projekt har brug for dem:

  • Manglende data: hvordan du forstår og håndterer missing values, inkl. multipel imputation.
  • Tidsvarierende variable: hvad du gør, når en variabel ændrer sig under opfølgningen (og hvornår du ikke behøver at gøre noget).

Næste skridt

Begynd med at få hvert udtræk ned til én række per person:

Langt ↔︎ bredt format

Se også

TipLæs mere

Generel uddybning i The Epidemiologist R Handbook (på engelsk):

Back to top