Deskriptive tabeller (Table 1)

Baseline-karakteristika for din studiepopulation med gtsummary

Published

July 2, 2026

Warning

Under udvikling. Flere eksempler (undergrupper, flere statistikker) kommer.

En “Table 1” beskriver din studiepopulation: alder, køn og andre baseline-variable, typisk opdelt efter eksponering. Den er næsten altid den første tabel i en registerartikel. Her bruger vi pakken gtsummary, der laver en publikationsklar tabel med få linjer.

Note

Kodeeksemplerne bruger generiske sti- og variabelnavne. Tilpas til dit projekt. gtsummary (og huxtable, hvis du vil eksportere til Excel) skal være installeret i dit R-miljø på DST; er de ikke det, så kontakt din datamanager.


Udgangspunkt

Du starter fra dit analyseklare datasæt med én række per person (Fase 12).

library(dplyr)                         # %>% (rør)
library(gtsummary)                     # tbl_summary() + eksport-funktioner

df <- readRDS("sti/til/analyse.rds")   # analyseklart datasæt, én række per person

Eksempel

tbl_summary() opsummerer de variable, du peger på. Med by = opdeler du tabellen i kolonner efter en gruppe (fx eksponering).

tabel1 <- df %>%
  tbl_summary(
    by = eksponering,                       # én kolonne per gruppe (udelad for samlet tabel)
    include = c(alder, koen, bmi),          # variable der skal med
    statistic = list(
      all_continuous()  ~ "{median} ({p25}, {p75})",
      all_categorical() ~ "{n} ({p}%)"
    ),
    digits  = all_continuous() ~ 1,          # antal decimaler for kontinuerte tal
    label   = list(alder ~ "Alder (år)", koen ~ "Køn", bmi ~ "BMI"),  # pæne variabelnavne
    missing = "ifany",                       # vis en "ukendt"-række hvis der mangler værdier
    missing_text = "Mangler"                 # teksten for den række
  ) %>%
  add_overall() %>%                           # tilføj en "I alt"-kolonne: ALLE personer samlet (begge grupper)
  bold_labels() %>%                           # gør variabelnavnene fede
  modify_header(label ~ "**Variabel**")       # tekst i overskriften på variabel-kolonnen (vælg selv)

tabel1                                        # skriv tabellen ud (vis den)
Uddybende forklaring
  • tbl_summary() gætter selv variabeltypen ud fra kolonnens indhold og vælger en passende statistik:
    • faktor- og tekst-variable - og tal med under 10 forskellige værdier - bliver kategoriske og vises som {n} ({p}%) (antal og procent);
    • øvrige tal bliver kontinuerte og vises som {median} ({p25}, {p75}) (median og kvartiler, dvs. IQR);
    • variable kodet 0/1, ja/nej eller TRUE/FALSE bliver dikotome og vises kun med den ene (“ja”-)række.
  • statistic = er derfor valgfri. Udelader du linjen helt, får du præcis standardvisningen ovenfor. Den er kun med for at vise, hvordan du ændrer det - vil du fx have gennemsnit i stedet for median, skriver du all_continuous() ~ "{mean} ({sd})".
  • I gtsummary betyder tilde-tegnet ~ “tildel”: hvad ~ værdi. Fx giver alder ~ "Alder (år)" variablen alder etiketten “Alder (år)”, og all_continuous() ~ "{mean} ({sd})" sætter den statistik for alle kontinuerte variable.
  • all_continuous() / all_categorical() betyder “alle kontinuerte” hhv. “alle kategoriske” variable, så reglen rammer dem alle på én gang.
  • digits styrer antallet af decimaler (her 1 for de kontinuerte).
  • add_overall() tilføjer en I alt-kolonne med alle personer samlet (begge grupper i én kolonne), ved siden af kolonnerne per gruppe - praktisk til at vise det samlede antal og den samlede fordeling. Udelad den, hvis du kun vil vise grupperne.
Skal der p-værdier på?

Du kan tilføje en p-værdi-kolonne med add_p(). Du kan enten køre det bagefter på den færdige tabel1 (som her), eller sætte add_p() ind i kæden ovenfor lige efter tbl_summary() - resultatet er det samme. Vær opmærksom på, at hypotesetests i en ren baseline-tabel ofte frarådes (de tester ikke det, man tror, ved store registerpopulationer). Brug dem kun bevidst.

tabel1 %>%           # tag den allerede byggede tabel ...
  add_p()            # ... og tilføj en kolonne med p-værdier

Crude incidensrate (per 1000 personår)

Registerartikler rapporterer ofte den rå (crude) incidensrate per eksponeringsgruppe ved siden af Table 1: antal hændelser delt med samlet opfølgningstid (personår), skaleret til per 1000 personår. Det kræver event (1 = hændelse, 0 = censureret) og followup_years fra dit analyseklare datasæt (bygget i Fase 12).

df %>%
  group_by(eksponering) %>%                                  # én linje per eksponeringsgruppe
  summarise(
    haendelser   = sum(event),                                # antal udfald i gruppen
    personaar    = sum(followup_years),                       # samlet opfølgningstid (personår)
    rate_pr_1000 = sum(event) / sum(followup_years) * 1000    # rå rate per 1000 personår
  )

Det er en deskriptiv rate uden justering, og tæller som aggregeret output (tjek for små celler inden eksport). Vil du sammenligne grupperne med kontrol for confounding, hører det til regression og time-to-event, hvor en Cox-model giver en hazard ratio.

Eksportér tabellen (til outputkontrol)

Alt, der forlader DST, skal gennem outputkontrol. En tabel som denne er aggregeret, men tjek altid for små celler før eksport.

# Til Excel: as_hux_xlsx() kræver, at pakken huxtable er INSTALLERET
# (du behøver ikke selv kalde library(huxtable) - gtsummary bruger den bag kulisserne).
tabel1 %>% as_hux_xlsx(file = "tabel1.xlsx")   # skriv tabellen til en .xlsx-fil

# Til Word: kræver pakken flextable installeret
tabel1 %>% as_flex_table()                     # giver et flextable-objekt til et Word-dokument

# Virker ALTID uden ekstra pakker (base R): lav tabellen om til en data.frame og gem som CSV
tabel1 %>%
  as_tibble() %>%                              # tabellen som almindelig data.frame
  write.csv("tabel1.csv", row.names = FALSE)   # en CSV kan åbnes direkte i Excel

Er huxtable eller flextable ikke tilgængelig på DST, så brug CSV-vejen (base R, ingen pakker nødvendige) eller kontakt din datamanager.

Alternativ pakke

finalfit::summary_factorlist() laver en lignende baseline-tabel og er populær i epidemiologi. gtsummary er valgt her, fordi eksport til Excel og Word er ligetil.

Note

Husk: alt der forlader DST skal gennem outputkontrol - ingen små celler, kun aggregerede resultater. Se Fase 14 - Eksport og hjemsendelse.

TipLæs mere

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

Back to top