Kapitel 87 Runden immer erst am Schluss

In diesem Kapitel lernen Sie folgendes:

  • Tabellen erstellen, die man für Publikationen benutzen kann
  • Exportieren und weiterverarbeiten dieser Tabellen

87.0.2 Pakete, die wir hier benutzen:

library(dplyr)
library(tidyr)
library(tableone)
library(arsenal)
library(Statamarkdown)
library(kableExtra)
library(gtsummary)
library(DescTools)

Es war ein schöner Wintersonntag morgens um acht und ich wollte eigentlich den 9:36 Zug nach Kandersteg nehmen um kurz lang zu laufen. Ich wollte nur noch schnell ein Kapitel fertig schreiben, in dem ich das Erstellen von Tabellen zeigte. In der Tabelle sollte ein Konfidenzintervall des Mittelwerts sein. Ich erstellte also im dplyr::summarise die Formel für das Konfidenzintervall und verglich mein Resultat mit dem Resultat der base-R Funktion t.test.

Hier das Resultat mit dem one-sample t.test:

result<-t.test(data$value)
result

    One Sample t-test

data:  data$value
t = 16.519, df = 40, p-value < 2.2e-16
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 23.61100 30.19388
sample estimates:
mean of x 
 26.90244 

Und hier das Konfidenzintervall:

result$conf.int
[1] 23.61100 30.19388
attr(,"conf.level")
[1] 0.95

Nun das von Hand berechnete

length2 <- function (x, na.rm=FALSE) {
        if (na.rm) sum(!is.na(x))
        else       length(x)
}



table_summary<-data %>% 
  dplyr::select(-id) %>% 
  summarise(across(where(is.numeric), 
                   .fns=list(mean=mean, sd=sd, n=length2), na.rm=TRUE, 
                   .names="{col}_{fn}")) %>% 
  mutate(across(contains("mean"), round,1)) %>% 
  mutate(across(contains("sd"), round,1)) %>% 
  mutate(lci=value_mean-abs(qt(0.025,df=value_n-1))*(value_sd/value_n^0.5)) %>% 
  mutate(uci=value_mean+abs(qt(0.025,df=value_n-1))*value_sd/value_n^0.5) %>% 
  dplyr::select(value_n, value_mean, value_sd, lci, uci ) 

  table_summary%>%
  kbl() %>%
kable_classic(full_width = F, html_font = "Cambria")
value_n value_mean value_sd lci uci
41 26.9 10.4 23.61735 30.18265

Ich war natürlich verwirrt, da das Konfidenzintervall nicht gleich war. Ich habe dann lange gegoogelt um nachzulesen, ob eventuell t.test eine andere Formel benutzt. Doch das Result müsste übereinstimmen.

  • Was war der Grund für den Fehler? Ganz einfach:

  • Ich habe zu früh gerundet und dann das Konfidenzintervall mit den gerundeten Werten berechnet.

Als ich das korrigiert habe, stimmte es überein:

(Die Zeile für das Runden des Konfidenzintervalls habe ich hier auskommentiert, damit wir kontrollieren können ob die Konfidenzintervalle übereinstimmen. )

length2 <- function (x, na.rm=FALSE) {
        if (na.rm) sum(!is.na(x))
        else       length(x)
}



table_summary<-data %>% 
  dplyr::select(-id) %>% 
  summarise(across(where(is.numeric), 
                   .fns=list(mean=mean, sd=sd, n=length2), na.rm=TRUE, 
                   .names="{col}_{fn}")) %>% 
  mutate(lci=value_mean-abs(qt(0.025,df=value_n-1))*(value_sd/value_n^0.5)) %>% 
  mutate(uci=value_mean+abs(qt(0.025,df=value_n-1))*value_sd/value_n^0.5) %>% 
  mutate(across(contains("mean"), round,1)) %>% 
  mutate(across(contains("sd"), round,1)) %>% 
  #mutate(across(contains("ci"), round,1)) %>% 
  dplyr::select(value_n, value_mean, value_sd, lci, uci )


table_summary%>%
  kbl() %>%
  kable_classic(full_width = F, html_font = "Cambria")
value_n value_mean value_sd lci uci
41 26.9 10.4 23.611 30.19388

Man könnte das jetzt noch anders darstellen:

length2 <- function (x, na.rm=FALSE) {
        if (na.rm) sum(!is.na(x))
        else       length(x)
}



table_summary<-data %>% 
  dplyr::select(-id) %>% 
  summarise(across(where(is.numeric), 
                   .fns=list(mean=mean, sd=sd, n=length2), na.rm=TRUE, 
                   .names="{col}_{fn}")) %>% 
  mutate(lci=value_mean-abs(qt(0.025,df=value_n-1))*(value_sd/value_n^0.5)) %>% 
  mutate(uci=value_mean+abs(qt(0.025,df=value_n-1))*value_sd/value_n^0.5) %>% 
  mutate(across(contains("mean"), round,1)) %>% 
  mutate(across(contains("sd"), round,1)) %>% 
  mutate(across(contains("ci"), round,1)) %>% 
  mutate(ci=paste0("(95% CI", lci, " to ", uci, ")")) %>% 
  dplyr::select(value_n, value_mean, value_sd, ci )
  
  table_summary %>% 
  kbl() %>%
  kable_classic(full_width = F, html_font = "Cambria")
value_n value_mean value_sd ci
41 26.9 10.4 (95% CI23.6 to 30.2)
  • Take Home Message: Immer erst ganz am Schluss runden!