Deskriptive tabeller (Table 1)
Baseline-karakteristika for din studiepopulation med gtsummary
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.
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 personEksempel
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/nejellerTRUE/FALSEbliver dikotome og vises kun med den ene (“ja”-)række.
- faktor- og tekst-variable - og tal med under 10 forskellige værdier - bliver kategoriske og vises som
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 duall_continuous() ~ "{mean} ({sd})".- I
gtsummarybetyder tilde-tegnet~“tildel”:hvad ~ værdi. Fx giveralder ~ "Alder (år)"variablenalderetiketten “Alder (år)”, ogall_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.digitsstyrer 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ærdierCrude 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 ExcelEr 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.
Husk: alt der forlader DST skal gennem outputkontrol - ingen små celler, kun aggregerede resultater. Se Fase 14 - Eksport og hjemsendelse.
Generel uddybning i The Epidemiologist R Handbook (på engelsk):