Indledning

I denne rapport gives eksempler på tabeloutput i R Studio.

Der vises følgende typer tabeller:

Tabellerne vises med både vægtet og uvægtet stikprøve.

Der er ikke gjort forsøg på at skrive loops, der kan udskrive flere tabeller på en gang.

Del 1: Frekvenstabeller:

I dette afsnit vises eksempler på frekvenstabeller.

I tabellerne vises kolonner for:

Der tilføjes tabeloverskrifter øverst.

Tabeller er udviklet ved at kombinere %>% (pipe) funktionen med forskellige andre pakker, der kan tilføje kolonnetotaler og figurtekster.

Her kommer først en uvægtet frekvenstabel:

# Uvægtet frekvenstabel:
tabel1 <- df %>% # %>% (pipe) er en speciel funktion, der kan binde flere funktioner sammen
  group_by(Køn) %>% # Her væles Køn
  summarise(Frekvens = n()) %>% # Tæller antal
  mutate(Procent=percent(Frekvens/sum(Frekvens), accuracy=1)) %>% # mutate tilføjer en kolonne med procenter
  adorn_totals(where = c("row"), fill = "100%") # Tilføjer kolonnetotaler

kbl(tabel1, # Her tilføjes figurtekst
    caption = "Tabel 1: Deltagernes fordeling på køn.") %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left")
Tabel 1: Deltagernes fordeling på køn.
Køn Frekvens Procent
Mand 478 43%
Kvinde 637 57%
Ønsker ikke at besvare 1 0%
Total 1116 100%

Og her er en vægtet frekvenstabel, hvor der er anvendt den ikke-trimmede vægt (WEIGHTS).

Jeg har ikke kunnet finde en pakke, der kan lave denne type frekvenstabeller med vægtede data, så jeg har kodet løsningen selv. Der er tilføjet survey vægte ved at tælle op på Vægt variablen i stedet for antal rækker. Det fungerer fint.

tabel2 <- df %>% # %>% (pipe) er en speciel funktion, der kan binde flere funktioner sammen
            group_by(Køn) %>% # Her væles Køn
            summarise(Frekvens = round(sum(WEIGHTS),0)) %>% # Vægtene indlæses vha. sum. Har kontrolleret at det stemmer.
            mutate(Procent=percent(Frekvens/sum(Frekvens), accuracy=1)) %>% # mutate tilføjer en kolonne med procenter
            adorn_totals(where = c("row"), fill = "100%") # Tilføjer kolonnetotaler

kbl(tabel2, 
   caption = "Tabel 2: Deltagernes fordeling på køn - vægtet") %>% # Tilføjer tabeloverskrift
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "left") # Definerer størrelse, tilføjer striber
Tabel 2: Deltagernes fordeling på køn - vægtet
Køn Frekvens Procent
Mand 546 49%
Kvinde 569 51%
Ønsker ikke at besvare 1 0%
Total 1116 100%

Del 2: Krydstabeller

I dette afsnit gives eksempler på krydstabeller.

Jeg har brugt tableby pakken, som giver nogle rigtigt flotte tabeller. Pakken har en funktion, hvor man kan tilføje vægte, hvis det ønskes.

Her en uvægtet krydstabel

colnames(df)[colnames(df) == "Q_7"] <- "Bank"

tabel3 <- tableby(Region ~ Bank, data=df, test=FALSE)

kbl(summary(tabel3, text=TRUE), 
    caption = "Tabel 3: I hvilken bank har du dit primære kredit kort? - krydset med region.") %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "float_left")
Tabel 3: I hvilken bank har du dit primære kredit kort? - krydset med region.
Region Hovedstaden (N=364) Region Midtjylland (N=253) Region Nordjylland (N=93) Region Sjælland (N=165) Region Syddanmark (N=241) Total (N=1116)
Bank
  • Danske Bank
113 (31.0%) 38 (15.0%) 14 (15.1%) 44 (26.7%) 66 (27.4%) 275 (24.6%)
  • Jyske Bank
30 (8.2%) 27 (10.7%) 5 (5.4%) 15 (9.1%) 9 (3.7%) 86 (7.7%)
  • Sydbank
9 (2.5%) 18 (7.1%) 3 (3.2%) 7 (4.2%) 31 (12.9%) 68 (6.1%)
  • Nykredit Bank
23 (6.3%) 11 (4.3%) 4 (4.3%) 9 (5.5%) 7 (2.9%) 54 (4.8%)
  • Spar Nord Bank
8 (2.2%) 9 (3.6%) 22 (23.7%) 2 (1.2%) 9 (3.7%) 50 (4.5%)
  • Arbejdernes Landsbank
27 (7.4%) 13 (5.1%) 0 (0.0%) 6 (3.6%) 14 (5.8%) 60 (5.4%)
  • Ringkjøbing Landbobank
6 (1.6%) 3 (1.2%) 11 (11.8%) 0 (0.0%) 0 (0.0%) 20 (1.8%)
  • Sparekassen Danmark
5 (1.4%) 9 (3.6%) 14 (15.1%) 1 (0.6%) 2 (0.8%) 31 (2.8%)
  • Nordea
66 (18.1%) 49 (19.4%) 5 (5.4%) 50 (30.3%) 35 (14.5%) 205 (18.4%)
  • Anden bank
76 (20.9%) 75 (29.6%) 15 (16.1%) 30 (18.2%) 66 (27.4%) 262 (23.5%)
  • Ved ikke
1 (0.3%) 1 (0.4%) 0 (0.0%) 1 (0.6%) 2 (0.8%) 5 (0.4%)

Og her er samme tabel, hvor den trimmede vægt er slået til:

tabel4 <- tableby(Region ~ Bank, data=df, weights = WEIGHTS.TRIM, test=FALSE)

kbl(summary(tabel4, text=TRUE), 
    caption = "Tabel 4: I hvilken bank har du dit primære kredit kort? - krydset med region - vægtet.") %>%
  kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "float_left")
Tabel 4: I hvilken bank har du dit primære kredit kort? - krydset med region - vægtet.
Region Hovedstaden (N=348) Region Midtjylland (N=246) Region Nordjylland (N=111) Region Sjælland (N=147) Region Syddanmark (N=264) Total (N=1116)
Bank
  • Danske Bank
87 (25.1%) 32 (13.0%) 20 (18.0%) 34 (22.8%) 67 (25.5%) 240 (21.5%)
  • Jyske Bank
35 (10.1%) 25 (10.2%) 8 (7.2%) 15 (10.2%) 9 (3.3%) 92 (8.2%)
  • Sydbank
7 (2.1%) 16 (6.6%) 2 (2.1%) 5 (3.5%) 30 (11.4%) 61 (5.5%)
  • Nykredit Bank
24 (7.0%) 9 (3.5%) 3 (3.0%) 6 (3.8%) 7 (2.8%) 49 (4.4%)
  • Spar Nord Bank
8 (2.4%) 7 (3.0%) 26 (23.1%) 1 (1.0%) 13 (4.8%) 55 (5.0%)
  • Arbejdernes Landsbank
27 (7.7%) 11 (4.5%) 0 (0.0%) 7 (4.7%) 15 (5.8%) 60 (5.4%)
  • Ringkjøbing Landbobank
6 (1.7%) 5 (1.9%) 11 (10.0%) 0 (0.0%) 0 (0.0%) 22 (1.9%)
  • Sparekassen Danmark
9 (2.5%) 13 (5.4%) 20 (17.7%) 1 (0.4%) 2 (0.8%) 44 (4.0%)
  • Nordea
62 (17.8%) 50 (20.2%) 5 (4.7%) 43 (29.2%) 40 (15.1%) 200 (17.9%)
  • Anden bank
81 (23.4%) 77 (31.5%) 16 (14.1%) 35 (23.6%) 79 (29.8%) 288 (25.8%)
  • Ved ikke
1 (0.2%) 1 (0.3%) 0 (0.0%) 1 (0.8%) 2 (0.8%) 5 (0.4%)

Som det ses, har vægtningen ganske stor indflydelse på resultaterne!

Rent kosmetisk er et lidt irriterende, at der bliver tilføjet em bindestreg foran hver rækkelabel, men det er desværre en begrænsning i tableby pakken, når man bruger kbl til at tilføje tabeloverskrift. Man kan få en pænere formaterring ved at slette den nederste kbl kode og i stedet vise tabelle via funktionen summary(tabel4).

tabel4 <- tableby(Region ~ Bank, data=df, weights = WEIGHTS.TRIM, test=FALSE)
summary(tabel4)
Region Hovedstaden (N=348) Region Midtjylland (N=246) Region Nordjylland (N=111) Region Sjælland (N=147) Region Syddanmark (N=264) Total (N=1116)
Bank
   Danske Bank 87 (25.1%) 32 (13.0%) 20 (18.0%) 34 (22.8%) 67 (25.5%) 240 (21.5%)
   Jyske Bank 35 (10.1%) 25 (10.2%) 8 (7.2%) 15 (10.2%) 9 (3.3%) 92 (8.2%)
   Sydbank 7 (2.1%) 16 (6.6%) 2 (2.1%) 5 (3.5%) 30 (11.4%) 61 (5.5%)
   Nykredit Bank 24 (7.0%) 9 (3.5%) 3 (3.0%) 6 (3.8%) 7 (2.8%) 49 (4.4%)
   Spar Nord Bank 8 (2.4%) 7 (3.0%) 26 (23.1%) 1 (1.0%) 13 (4.8%) 55 (5.0%)
   Arbejdernes Landsbank 27 (7.7%) 11 (4.5%) 0 (0.0%) 7 (4.7%) 15 (5.8%) 60 (5.4%)
   Ringkjøbing Landbobank 6 (1.7%) 5 (1.9%) 11 (10.0%) 0 (0.0%) 0 (0.0%) 22 (1.9%)
   Sparekassen Danmark 9 (2.5%) 13 (5.4%) 20 (17.7%) 1 (0.4%) 2 (0.8%) 44 (4.0%)
   Nordea 62 (17.8%) 50 (20.2%) 5 (4.7%) 43 (29.2%) 40 (15.1%) 200 (17.9%)
   Anden bank 81 (23.4%) 77 (31.5%) 16 (14.1%) 35 (23.6%) 79 (29.8%) 288 (25.8%)
   Ved ikke 1 (0.2%) 1 (0.3%) 0 (0.0%) 1 (0.8%) 2 (0.8%) 5 (0.4%)

Del 3: Multiple response tabeller

Multiple response tabeller er lidt vanskeligere at producere. Man kan dog både kode dem selv fra bunden eller bruge pakken expss.

Jeg har valgt at bruge expss, da det er lettest. Expss understøtter desværre ikke procent format, så tallene står som procenter uden procenttegn i tabellerne. Til gengæld kan man bruge vejevariable.

Inden man laver multiple response tabeller, kan det være en fordel at gemme de relevante variable i et nyt dataframe og give kolonnerne passende overskrifter.

df8 <- df %>% 
  rename("Visa Dankort" = "Q_8_1",
         "Dankort" = "Q_8_2",
         "Visakort" = "Q_8_3",
         "Mastercard" = "Q_8_4",
         "Mastercard Dankort" = "Q_8_5",
         "Andet" = "Q_8_6",
         "Har ikke et betalingskort" = "Q_8_7",
         "Ved ikke" = "Q_8_8")

# Gem subset af data (Q_8)
df_Q8 <- df8[ , c("Visa Dankort", "Dankort", "Visakort", "Mastercard", "Mastercard Dankort", 
                  "Andet", "Har ikke et betalingskort", "Ved ikke", 
                  "Køn", "Alder", "Region", "WEIGHTS", "WEIGHTS.TRIM")]

Obs! En ulempe ved expss er, at man er nødt til manuelt at definere kolonneoverskrifter, fordi der indsættes teksten “rownames” i den første kolonne. Det betyder, at man evt. kan springe første step i ovenstående over.

Her er eksempler på en vægtet frekvenstabel med brug af WEIGHTS.TRIM:

tabel5 <- cross_cpct(df_Q8, mdset("Visa Dankort" %to% "Ved ikke"), list(total()), weight = WEIGHTS.TRIM)

kbl(tabel5, caption = "Tabel 5: Hvilke betalingskort har du gennem din bank? - vægtet.",
             col.names = c("Betalingskort:", "Total pct. af resp."), digits=2) %>%
kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "center")
Tabel 5: Hvilke betalingskort har du gennem din bank? - vægtet.
Betalingskort: Total pct. af resp.
Visa Dankort 86.04
Dankort 4.94
Visakort 7.03
Mastercard 46.57
Mastercard Dankort 6.47
Andet 1.39
Har ikke et betalingskort 0.39
Ved ikke 0.12
#Total cases 1116.00

Tallene viser pct. at det totale antal respondenter (1.116).

Alternativt kan man vise tallene som pct. at det total antal afgivne svar (1.719):

tabel6 <- cross_cpct_responses(df_Q8, mdset("Visa Dankort" %to% "Ved ikke"), list(total()), weight = WEIGHTS.TRIM)

kbl(tabel6, caption = "Tabel 6: Hvilke betalingskort har du gennem din bank? - vægtet.",
             col.names = c("Betalingskort:", "Total pct. af svar"), digits=2) %>%
kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "center")
Tabel 6: Hvilke betalingskort har du gennem din bank? - vægtet.
Betalingskort: Total pct. af svar
Visa Dankort 56.25
Dankort 3.23
Visakort 4.60
Mastercard 30.45
Mastercard Dankort 4.23
Andet 0.91
Har ikke et betalingskort 0.25
Ved ikke 0.08
#Total responses 1719.00

Og sådan kunne en ** vægtet krydstabel** se ud:

tabel7 <- cross_cpct(df_Q8, mdset("Visa Dankort" %to% "Ved ikke"), list(total(), Alder), weight = WEIGHTS.TRIM)

kbl(tabel7, caption = "Tabel 7: Hvilke betalingskort har du gennem din bank? - krydset med alder - vægtet.",
             col.names = c("Betalingskort:", "Total pct. af resp.", "Under 30 år", "30-39 år",
                           "40-49 år", "50-59 år", "60-69 år", "70+ år", "Ønsker ikke at oplyse"), digits=2) %>%
kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "float_left")
Tabel 7: Hvilke betalingskort har du gennem din bank? - krydset med alder - vægtet.
Betalingskort: Total pct. af resp. Under 30 år 30-39 år 40-49 år 50-59 år 60-69 år 70+ år Ønsker ikke at oplyse
Visa Dankort 86.04 86.96 81.06 83.18 87.04 85.87 89.64 100
Dankort 4.94 4.35 7.66 5.65 4.05 4.13 4.46 NA
Visakort 7.03 8.70 9.61 7.71 7.18 6.36 5.21 NA
Mastercard 46.57 43.48 51.28 42.80 41.68 47.82 50.35 NA
Mastercard Dankort 6.47 8.70 3.97 5.50 6.46 6.87 7.65 NA
Andet 1.39 NA NA 2.07 2.49 0.85 1.56 NA
Har ikke et betalingskort 0.39 NA NA 1.15 0.66 NA 0.27 NA
Ved ikke 0.12 NA NA NA NA 0.33 0.23 NA
#Total cases 1116.00 23.00 53.00 108.00 191.00 309.00 431.00 1

Bemærk i øvrigt, at det de uvejede samplestørrelser, der står nederst i tabellen!

Her til sidst et alternativt layout for en multipel frekvenstabel, med kolonner for både pct. af resp. og svar:

tabel8 <- data.frame(Frekvens = round(colSums(df_Q8[1:8]*df_Q8$WEIGHTS.TRIM),0),
                      Pct.af.Svar = percent(round((colSums(df_Q8[1:8]*df_Q8$WEIGHTS.TRIM)/sum(df_Q8[1:8])),2)),
                      Pct.af.Resp = percent(round((colSums(df_Q8[1:8]*df_Q8$WEIGHTS.TRIM)/nrow(df_Q8[1:8])),2)))

kbl(tabel8, caption = "Tabel 8: Hvilke betalingskort har du gennem din bank? - vægtet.") %>%
kable_styling(bootstrap_options = "striped", full_width = FALSE, position = "center")
Tabel 8: Hvilke betalingskort har du gennem din bank? - vægtet.
Frekvens Pct.af.Svar Pct.af.Resp
Visa Dankort 960 56% 86%
Dankort 55 3% 5%
Visakort 79 5% 7%
Mastercard 520 30% 47%
Mastercard Dankort 72 4% 6%
Andet 15 1% 1%
Har ikke et betalingskort 4 0% 0%
Ved ikke 1 0% 0%

Del 4: Afrunding

I denne rapport er vist eksempler på, hvordan man kan lave tabeller.

Det letteste er nok at lave det hele i expss, da det ikke kræver helt så meget kodning. Fordelen er også, at man får det samme visuelle output.

Personligt kan jeg dog bedst lide, at der står procenter med procenttegn i tabellerne, og det kan expss ikke.