flowchart TD
A[("Kilderegistre - hele befolkningen<br>LPR2: lpr_sksopr + lpr_adm<br>LPR3: procedurer_kirurgi + lpr_a_kontakt")]:::store
B["Trin 1: filtrér på eksponeringskoder<br>eksponerede med pnr + index_date<br>n = 12.300"]:::step
E1["Ekskluderet i Trin 2:<br>prævalent outcome før index<br>(fra LPR-diagnoser)<br>n = 1.150"]:::excl
C["Eksponeret kohorte<br>n = 11.150"]:::step
F["Valgfrit (Fase 10a):<br>+ matchet sammenligningskohorte"]:::optional
D["Endelig studiepopulation<br>pnr + index_date<br>(→ Fase 11)"]:::result
A --> B
B --> C
B -.->|frafald| E1
C -.-> F
C --> D
F -.-> D
classDef store fill:#eef0f2,stroke:#8a94a6,color:#1f2733;
classDef step fill:#eaf2fb,stroke:#4a78b5,color:#173a5e;
classDef excl fill:#fdecea,stroke:#d9534f,color:#7a1f1a;
classDef optional fill:#fff3e0,stroke:#e69500,color:#7a4f00;
classDef result fill:#e9f7ef,stroke:#3fae6b,color:#14532d;
Byg din studiepopulation
Identificér dine cases/eksponerede - vælg derefter studiedesign
De senere faser - udtræk af variable (Fase 11), saml datasættet (Fase 12) og analyse (Fase 13) - forudsætter, at du allerede har en kohorte: en tabel med pnr og index_date per person. Denne side viser, hvordan du identificerer din studiepopulation og giver hver person en index-dato; derefter vælger du studiedesign.
Kort fortalt: Først identificerer du dine cases/eksponerede og giver hver en index-dato. Derefter afhænger vejen af dit design:
- Prævalensstudie / kohorte uden sammenligningsgruppe: efter denne side er du færdig med at bygge studiepopulationen; gå videre til Fase 11 - Udtræk variable.
- Kohortestudie med sammenligningskohorte: efter denne side fortsætter du til → Sammenligningskohorte.
- (Nested) case-control: efter denne side fortsætter du til → Case-control.
- Selvkontrolleret eller familiebaseret design: lader personen (eller familien) være sin egen kontrol - se Selvkontrollerede og familiebaserede designs.
Hvad er index-dato?
Index-dato er det tidspunkt der markerer starten på opfølgning for en given person.
- Eksponerede: den dato personen fik eksponeringen (fx operationsdato, diagnosedato, første receptudstedelse)
- Sammenligningskohorte: den index-dato der er tildelt fra den matchede eksponerede
Alt efterfølgende - udfaldsdato, kovariater ved baseline, opfølgningstid - beregnes relativt til index-dato. Definitionen af index-dato er afgørende for studievaliditeten.
Denne side er stadig under udvikling. Koden skal gennemgås og testes yderligere inden den bruges direkte. Brug den som strukturel vejledning og tilpas til dit eget projekt.
Funktioner brugt her. inner_join() og bind_rows() er allerede vist i Udtræk fra LPR og gennemgås grundigt i Kobl udtræk sammen. group_by() + slice() forklares i Langt ↔︎ bredt format. Nyt i Trin 2: anti_join(), distinct(), pull() samt nrow(), cat() og stopifnot() - se Guide til funktioner.
Trin 1 - Identificér de eksponerede (eller cases)
Du scanner det register der definerer din eksponering. Du har endnu ingen kohort_pnrs-liste - du forespørger hele registret og filtrerer på eksponeringskriteriet.
Eksponeringen kan defineres på mange måder:
| Type | Eksempel | Register |
|---|---|---|
| Operation / procedure (SKS-kode) | Bariatrisk kirurgi KJDF10/KJDF11 | lpr_sksopra (LPR2), procedurer_kirurgia (LPR3) |
| Hospitaldiagnose (ICD-kode) | Type 2-diabetes E11 | lpr_diag + lpr_adm, lpr_a_diagnose + lpr_a_kontakt |
| Medicineksponering (ATC-kode) | Metformin A10BA02 | LMDB |
| Klinisk mål / biomarkør | BMI > 35, HbA1c > 75 mmol/mol | Projektspecifikke data / OSDC / DBSO |
a lpr_sksopr og procedurer_kirurgi er navnene på DARTER-projektet (708421) - se Register-overblik. Navnene kan variere på andre projekter.
Eksempel A: SKS-koder (operation/procedure)
lpr_sksopr indeholder operationskoden (c_opr) + recnum, men ikke pnr eller dato; dem ligger i lpr_adm. Derfor joiner du de to på recnum for at få person + dato + operation samlet - præcis samme mønster som diagnoser (kontakt- + diagnoseregister), se Forstå LPR.
#=====================================================
# Trin 1A: identificér eksponerede via SKS-koder
#=====================================================
library(arrow) # open_dataset
library(dplyr) # filter, select, group_by, slice, ungroup, bind_rows, mutate
# Tilpas disse koder til dit studie
RYGB <- c("KJDF10", "KJDF11") # Roux-en-Y gastric bypass
SG <- c("KJDF40", "KJDF41", "KJDF96", "KJDF97") # sleeve gastrectomy
BS_KODER <- c(RYGB, SG) # samlet vektor
#-----------------------------------------------------
# LPR2: indgreb frem til 2018/2019
#-----------------------------------------------------
lpr_sksopr <- open_dataset("E:/workdata/[projektnummer]/cleaned-data/parquet-registers/lpr_sksopr/") %>%
rename_with(tolower)
lpr_adm <- open_dataset("E:/workdata/[projektnummer]/cleaned-data/parquet-registers/lpr_adm/") %>%
rename_with(tolower)
eksp_lpr2 <- lpr_sksopr %>%
filter(c_opr %in% !!BS_KODER) %>% # kun bariatri-indgreb
select(recnum, sks_kode = c_opr) %>% # recnum er join-nøgle til lpr_adm
inner_join(
lpr_adm %>% select(pnr, recnum, index_date = d_inddto), # tilknyt pnr og dato
by = "recnum"
) %>%
collect()
#-----------------------------------------------------
# LPR3: indgreb fra 2019 og frem
#-----------------------------------------------------
proc_kir <- open_dataset("E:/workdata/[projektnummer]/cleaned-data/parquet-registers/procedurer_kirurgi/") %>%
rename_with(tolower)
lpr_a_k <- open_dataset("E:/workdata/[projektnummer]/cleaned-data/parquet-registers/lpr_a_kontakt/") %>%
rename_with(tolower)
eksp_lpr3 <- proc_kir %>%
filter(procedurekode %in% !!BS_KODER) %>% # kun bariatri-indgreb
select(dw_ek_forloeb, sks_kode = procedurekode) %>%
inner_join(
lpr_a_k %>% select(pnr, dw_ek_forloeb, index_date = kont_starttidspunkt),
by = "dw_ek_forloeb"
) %>%
collect() %>%
mutate(index_date = as.Date(index_date)) # datetime → dato
#-----------------------------------------------------
# Kombinér og tag ét indgreb per person (det første)
#-----------------------------------------------------
# Resultatet hedder "eksponerede" - kun den eksponerede gruppe, IKKE den fulde kohorte endnu
eksponerede <- bind_rows(eksp_lpr2, eksp_lpr3) %>%
group_by(pnr) %>% # gruppér per person
arrange(index_date) %>% # ældste dato øverst
slice(1) %>% # ét indgreb per person (det første)
ungroup() %>% # frigiv gruppering (se Fase 12)
mutate(exposed = 1L) # markér som eksponeret (1 = ja)
nrow(eksponerede) # antal unikke opereredeeksponerede indeholder kun de opererede. Den fulde kohorte (eksponerede + sammenligningskohorte) bygges på Sammenligningskohorte og gemmes som kohort. Det er kohort - ikke eksponerede - du bruger som kohort_pnrs i de øvrige faser.
Eksempel B: ICD-diagnose som eksponeringskriterium
#=====================================================
# Trin 1B: identificér eksponerede via ICD-diagnose
#=====================================================
# Samme LPR-mønster som Fase 9 - men uden semi_join(tibble(pnr = kohort_pnrs), by = "pnr"),
# da kohorte endnu ikke er bygget. Du søger hele befolkningens data for at finde eksponerede.
lpr_diag <- open_dataset("E:/workdata/[projektnummer]/cleaned-data/parquet-registers/lpr_diag/") %>%
rename_with(tolower)
lpr_adm <- open_dataset("E:/workdata/[projektnummer]/cleaned-data/parquet-registers/lpr_adm/") %>%
rename_with(tolower)
eksponerede <- lpr_adm %>%
inner_join(
lpr_diag %>%
filter(c_diagtype %in% c("A", "B"),
substr(c_diag, 2, 4) == "E11") %>% # T2D: "DE11" → strip D-præfiks
select(recnum, c_diag),
by = "recnum"
) %>%
select(pnr, index_date = d_inddto) %>%
collect() %>%
group_by(pnr) %>%
arrange(index_date) %>%
slice(1) %>% # første diagnose per person
ungroup() %>%
mutate(exposed = 1L)Dette eksempel henter kun fra LPR2. Tag altid stilling til, hvilke registre dit udfald/din eksponering kræver - LPR2 (evt. + psykiatri) og LPR3 - og kombinér dem som i 9b: Udtræk fra LPR. Udelader du et register, mister du de tilfælde, der kun findes der.
Trin 2 - Ekskludér prævalente tilfælde
Personer der allerede havde dit outcome før index-dato skal ekskluderes - ellers tæller de som nye tilfælde, selvom de ikke er det. Det gælder alle designs, også et prævalensstudie uden sammenligningsgruppe, så det hører til her, hvor du bygger den eksponerede kohorte.
Tæl hvor mange der ryger fra ved hvert eksklusionstrin, så du kan beskrive frafaldet og senere tegne et STROBE flow-diagram (også kaldet et deltager- eller attrition-diagram; se STROBE-checklisten). Den generiske N-optællings-skabelon står i Fase 6.
Hjælpefunktion til at ekskludere prævalente tilfælde
Skal samme tjek bruges flere gange (fx også på en sammenligningsgruppe senere, se Sammenligningskohorte), kan du pakke logikken i en funktion, så de to tjek ikke skrider fra hinanden. Se God kode-praksis.
Vis koden: ekskludér prævalente tilfælde
#=====================================================
# Trin 2: ekskludér prævalente tilfælde
#=====================================================
# diagnoser = dit LPR-udtræk fra Fase 9 (kolonner: pnr, date_contact, icd3)
OUTCOME_KODER <- c("G30", "F00", "F01", "F02", "F03") # ICD-10 for dit outcome - tilpas
# Vi laver vores EGEN funktion (en genbrugelig kodeblok). Den tager tre argumenter:
# diagnoser = dit LPR-diagnoseudtræk (kolonner: pnr, date_contact, icd3)
# koder = ICD-koderne der definerer dit outcome (her OUTCOME_KODER)
# kohorte = den gruppe der skal tjekkes, med pnr + index_date
# Den returnerer de pnr, der havde outcome FØR deres egen index-dato.
prior_outcome_pnrs <- function(diagnoser, koder, kohorte) {
diagnoser %>%
filter(icd3 %in% koder) %>%
inner_join(kohorte %>% select(pnr, index_date), by = "pnr") %>% # tilknyt hver persons index
filter(date_contact < index_date) %>% # kun kontakter FØR index
distinct(pnr) %>% # én række per person
pull(pnr) # vektor af pnr at ekskludere
}
praevalente <- prior_outcome_pnrs(diagnoser, OUTCOME_KODER, eksponerede)
n_before <- nrow(eksponerede) # nrow() = antal rækker (her: antal personer)
eksponerede <- eksponerede %>%
filter(!pnr %in% praevalente) # behold kun dem UDEN prævalent outcome
# cat() printer bare en læsbar linje i konsollen, så du kan følge frafaldet undervejs.
cat("Efter prævalens-eksklusion:", nrow(eksponerede),
"| ekskluderet:", n_before - nrow(eksponerede), "\n")
# Er beskeden kun til dig selv, kan du nøjes med: nrow(eksponerede) # antal tilbage
stopifnot(n_distinct(eksponerede$pnr) == nrow(eksponerede)) # tjek: én række per personnrow(), cat() og stopifnot() er forklaret i Guide til funktioner.
Planlægger du en sammenligningskohorte? Så udtræk gerne outcome- (og eksponerings-)datoerne for hele befolkningen allerede her - ikke kun for de eksponerede - og genbrug dem: i Trin 2 afgrænset til de eksponerede (som ovenfor), og senere til sammenligningspoolen (se Sammenligningskohorte). Outcome-udtrækket på diagnosekoderne returnerer alligevel alle med diagnosen, så du sparer en ekstra forespørgsel mod registrene.
Deltagerdiagram (STROBE flow)
De N-optællinger, du lavede i Trin 1 og Trin 2, samles til sidst i et STROBE flow-diagram: en figur, der viser hvor mange personer der var med fra start, hvor mange der blev ekskluderet ved hvert trin og hvorfor, og hvor mange der endte i studiepopulationen. Det forventes i næsten alle observationelle studier. Diagrammet her viser også hvor dataene kommer fra i hvert trin (tallene er simulerede).
Sådan hænger hvert trin sammen med dataene:
- Kilderegistre: hele befolkningens LPR-data (du har endnu ingen kohorteliste). LPR2 og LPR3 åbnes dovent med
open_dataset()- se Trin 1 ovenfor. - Trin 1: du filtrerer på dine eksponeringskoder og knytter
pnr+index_datepå. Resultatet ereksponerede. - Trin 2 (eksklusion): prævalente tilfælde - personer med outcome før deres index-dato - findes i LPR-diagnoserne og fjernes. Det er
n_before - nrow(eksponerede), der står i eksklusionsboksen. - Endelig studiepopulation:
pnr+index_dateper person, klar til Fase 11 - Udtræk variable. Bygger du en sammenligningskohorte, indsættes Fase 10a før det sidste trin.
Outputkontrol: eksklusionsboksene viser rå antal. Små tal (fx en eksklusionsgruppe med ganske få personer) kan være afslørende - rund af eller slå sammen, før diagrammet forlader DST. Se Fase 14 - Eksport og hjemsendelse.
Hvad nu - vælg dit design:
- Prævalensstudie / kohorte uden sammenligningsgruppe: efter denne side er du færdig: du har din studiepopulation med en index-dato. Gå videre til Fase 11 - Udtræk variable og Fase 12 - Saml & klargør datasættet.
- Kohortestudie med sammenligningskohorte: efter denne side fortsætter du til → Sammenligningskohorte, hvor du bygger en matchpool og risk-set matcher en sammenligningsgruppe.
- (Nested) case-control: efter denne side fortsætter du til → Case-control, hvor din “eksponerede” gruppe ovenfor i stedet er dine cases, og du sampler kontroller der var i risiko, da casen fik udfaldet.
Se også
- Fase 1 - Studieforberedelse: designvalg bag kohorte, matching og case-control
- Udtræk fra LPR: diagnosemønster for eksponerings-/case-identifikation
- Register-overblik: kolonnenavne for lpr_sksopr, procedurer_kirurgi m.fl.