Kapitel 35 Berechnungen Standard-Messfehler (SEM)
35.1 SEM aus ICC

Nachdem wir nun den ICC kennengelernt haben, betrachten wir in diesem Kapitel drei Berechnungen für den Standardmessfehlers, auch Standard Error of Measurement oder SEM genannt.
Am Ende des Kapitels wissen wir folgendes:
- Der SEM kann aus dem ICC berechnet werden, wenn es keinen systematischen Fehler gibt.
- Der ICC ist abhängig vom SEM und von der Streuung des zu messenden Merkmals in der Stichprobe - Bei gleichem SEM wird der ICC höher (besser) sein, wenn die Standardabweichung des Merkmals grösser ist. Der SEM hingegen ist nicht von der Variabilität zwischen den Personen betroffen.
35.2 Beispiel schmerzhafte und gesunde Schulter
# load packages ####
library(psych)
library(tidyverse)
library(janitor)
library(BlandAltmanLeh)
35.3 Simulieren der Daten
Wir simulieren wieder Daten für die schmerzhaften und die gesunden Schultern
set.seed(12293425)
=100
sampleSize<-rnorm(sampleSize, 90, 20)
painful_shoulder
<-rnorm(sampleSize, 180, 2)
healthy_shoulder<-1:sampleSize
id
<-data.frame(id, painful_shoulder, healthy_shoulder) data_shoulder
35.4 Streuung der Beweglichkeit
Die nächsten beiden Graphiken zeigen die Variabilität der Beweglichkeiten in den schmerzhaften und den gesunden Schultern.
par(mfrow = c(1, 2))
plot(painful_shoulder, id, xlim=c(0,190))
plot(healthy_shoulder, id, xlim=c(0,190))

Abbildung 3.1: Variabilität in den schmerzhaften (links) und gesunden (rechts) Schultern. Auf der horizontalen (x) Achse sehen wir die Flexion in Graden. Auf der vertikalen (y) Achse sehen wir die ID-Nummern, d.h. jede Patientin und jeder Patient ist auf einer Linie.
par(mfrow = c(1, 1))
sd(healthy_shoulder)
## [1] 1.956707
sd(painful_shoulder)
## [1] 20.61599
35.5 Simulieren der Test-Retest Fehler
<-data_shoulder %>%
data_shouldermutate(painful_shoulder_1=painful_shoulder+rnorm(nrow(.), 0, 5)) %>%
mutate(healthy_shoulder_1=healthy_shoulder+rnorm(nrow(.), 0, 5)) %>%
mutate(painful_shoulder_2=painful_shoulder+rnorm(nrow(.), 0, 5)) %>%
mutate(healthy_shoulder_2=healthy_shoulder+rnorm(nrow(.), 0, 5))
35.6 Berechnen des Standardmessfehlers (Standard Error of the Mean, SEM)
Wir können den SEM mit drei unterschiedlichen Formeln berechnen.
Ein Problem ist der systematische Fehler: Wenn wir systematischen Fehler haben (d.h. einen Unterschied in den Mittelwerten der Messung 1 und Messung 2), dürfen wir nicht alle Formeln benutzen - wir werden das jeweils bei den Formeln angeben.
35.6.1 Variante 1: \(\frac{SD~Difference~}{\sqrt{2}}\)
(Achtung: diese Formel berücksichtigt den systematischen Fehler nicht!)
=(sd(data_shoulder$painful_shoulder_2-data_shoulder$painful_shoulder_1))/2^0.5
SEM_painful_shoulder SEM_painful_shoulder
## [1] 4.350445
=(sd(data_shoulder$healthy_shoulder_2-data_shoulder$healthy_shoulder_1))/2^0.5
SEM_healthy_shoulder SEM_healthy_shoulder
## [1] 4.618261
<-SEM_healthy_shoulder SEM_variante_1
35.6.2 Variante 2: \(\sigma\)Merkmal\(\sqrt{(1-ICC)}\) = SDpooled\(\sqrt{(1-ICC)}\)
(Achtung: auch diese Formel berücksichtigt den systematischen Fehler nicht!) Für diese Variante müssen wir zuerst den ICC berechnen. Da diese Formel den systematischen Fehler nicht berücksichtigt, dürfen wir sie nur benutzen, wenn es keinen systematischen Fehler gibt, oder wenn wir ihn nicht berücksichtigen wollen.
Wir benutzen dazu die gepoolte Standardabweichung der beiden Messungen. Die Formel ist unten im R-Chunk. Diese Webseite gibt noch mehr Informationen zu der gepoolten Standardabweichung
<-psych::ICC(data_shoulder[c("healthy_shoulder_1", "healthy_shoulder_2")]) out
## boundary (singular) fit: see help('isSingular')
<-sqrt((sd(data_shoulder$healthy_shoulder_1, na.rm=TRUE)^2 +sd(data_shoulder$healthy_shoulder_2, na.rm=TRUE)^2)/2)
pooled_sd
<-out$results$ICC[3] ICC2_1
Der ICC2,1 für die Gesunde Seite ist 0.26
Jetzt können wir die Formel anwenden:
<-pooled_sd*sqrt(1-ICC2_1)
SEM_variante_2 SEM_variante_2
## [1] 4.609313
35.6.3 Variante 3: SEM = \(\sqrt{sigma^2~Error~}\)
Nun ist es nicht ganz so einfach, diese Fehler-Varianz (\(\sigma^2~Error~\)) zu erhalten. Wir können sie aus dem Objekt extrahieren, das wir mit dem ICC Befehls des psych Pakets erhaltenDies sehen wir im nächsten R-Abschnitt:
Den nächsten Code-Abschnitt braucht ihr als Bachelor of Science nicht zu verstehen - Wir brauchen diesen Code um die benötigten Varianzkomponenten zu erhalten. Diese benötigen wir, um den SEM für das Agreement zu berechnen. Wer mehr dazu wissen möchte, sollte den folgenden Artikel lesen: Vet, H. C., Terwee, C. B., Knol, D. L., & Bouter, L. M. (2006). When to use agreement versus reliability measures. Journal of clinical epidemiology, 59(10), 1033-1039
out
## Call: psych::ICC(x = data_shoulder[c("healthy_shoulder_1", "healthy_shoulder_2")])
##
## Intraclass correlation coefficients
## type ICC F df1 df2 p lower bound upper bound
## Single_raters_absolute ICC1 0.26 1.7 99 100 0.0045 0.066 0.43
## Single_random_raters ICC2 0.26 1.7 99 99 0.0046 0.066 0.43
## Single_fixed_raters ICC3 0.26 1.7 99 99 0.0046 0.065 0.43
## Average_raters_absolute ICC1k 0.41 1.7 99 100 0.0045 0.124 0.60
## Average_random_raters ICC2k 0.41 1.7 99 99 0.0046 0.123 0.60
## Average_fixed_raters ICC3k 0.41 1.7 99 99 0.0046 0.123 0.60
##
## Number of subjects = 100 Number of Judges = 2
## See the help file for a discussion of the other 4 McGraw and Wong estimates,
$stats out
## subjects Judges Residual
## df 9.900000e+01 1.0000000 99.00000
## SumSq 3.555151e+03 21.1970149 2098.50445
## MS 3.591061e+01 21.1970149 21.19701
## F 1.694135e+00 1.0000000 NA
## p 4.645463e-03 0.3197485 NA
$MSW out
## [1] 21.19701
=nrow(data_shoulder)
numberOfPatients=2
numberOfRaters
<-out$stats[3,1]
varBetweenPatients<-out$stats[3,3]
varResidual<-(varBetweenPatients-varResidual)/numberOfRaters
varTrueBetweenPatients<-out$stats[3,2]
varBetweenRaters<-(varBetweenRaters-varResidual)/numberOfPatients
varTrueBetweenRaters
<-varTrueBetweenPatients/(varTrueBetweenPatients+varTrueBetweenRaters+varResidual)
ICC_agreement ICC_agreement
## [1] 0.2576468
# In a lot of publications, you see these formulae from Shrout and Fleiss
# ICC_3.1<-(varBetweenPatients-varResidual)/varBetweenPatients
# ICC_3.1
.1 <-(varBetweenPatients-varResidual) / (varBetweenPatients+(numberOfRaters-1)*varResidual+((numberOfRaters*(varBetweenRaters-varResidual))/numberOfPatients))
ICC_2.1 ICC_2
## [1] 0.2576468
# Method 1, see page 111 in Measurement in Medicine
# For SEMagreement
<-varTrueBetweenRaters+varResidual
varError<-sqrt(varError)
SEMagreementprint(SEMagreement)
## [1] 4.604022
<-SEMagreement SEM_variante_3
SEM Agreement für die gesunde Seite: Der ICC2,1 für die gesunde Seite ist 0.26 mit einem 95% Konfidenzintervall von 0.07 bis 0.43. DER SEMagreement der gesunden Schultern, berechnet mit der Formel aus dem Artikel von de Vet und Kolleginnen, ist: 4.6.
Wir können die drei Varianten noch einmal hier darstellen:
Variante 1: 4.6
Variante 2: 4.6
Variante 3: 4.6
35.7 Smallest Detectable Change
(Auch Minimal Detectable Change oder Difference genannt.) Wir werden in einem späteren Kapitel noch näher auf den Smallest Detectable Change eingehen, hier nur eine kurze Aussage:
- Der Smallest Detectable Change auf dem 95% Niveau (SDC95%) wird mit 1.96*\(\sqrt{2}\) = 2.77 Mal SEM berechnet.
- Die Hälfte des Intervalls zwischen den Limits of Agreement entspricht dem Smallest Detectable Change auf dem 95% Niveau (SDC95%)
Wir können das mit dem Bland-Altman Plot anschauen
library(MethComp)
library(BlandAltmanLeh)
mean(data_shoulder$painful_shoulder_1)
## [1] 92.09715
mean(data_shoulder$painful_shoulder_2)
## [1] 91.96726
<-bland.altman.plot(data_shoulder$painful_shoulder_1, data_shoulder$painful_shoulder_2, xlim=c(0,200), graph.sys = "ggplot2")
bp1<-bp1+xlim(0,200)+ylim(-20,20)+theme_classic()+labs(x="Mean of variables: painful_shoulder_1, painful_shoulder_2", y="Difference painful_shoulder_1 - painful_shoulder_2")
bp1
bp1
<-bland.altman.plot(data_shoulder$healthy_shoulder_1, data_shoulder$healthy_shoulder_2, graph.sys="ggplot2")
bp2<-bp2+xlim(0,200)+ylim(-20,20)+theme_classic()+labs(x="Mean of variables: healthy_shoulder_1, healthy_shoulder_2", y="Difference healthy_shoulder_1 - healthy_shoulder_2")
bp2 bp2


Abbildung 22.1: Bland Altman Plot. Auf der vertikalen Achse sehen wir die Differenz der Messung 1 minus die Messung 2 der schmerzhaften Schultern; auf der horizontalen Achse sehen wir den Durchschnitt der beiden Messungen. Wir sehen, dass es praktischen keinen systematische Differenz (Fehler) zwischen den beiden Messungen gibt, d.h. der Mittelwert der Differenz (mittlere gestrichelte Linie) ist praktisch bei Null.
Wir könnten sogar noch visuell untersuchen, ob die Differenz zwischen den beiden Messungen über die Werte der Messungen gleich bleibt. Wir sehen, dass es einen leichten Trend gibt, die Daten sind jedoch immer noch kompatibel mit der Hypothese, dass die Differenz über alle Wertebereiche 0 ist.
+geom_smooth(method=lm) bp1
## `geom_smooth()` using formula = 'y ~ x'

Abbildung 1.2: Bland-Altman Plot mit eingezeichneter Regressionslinie für die Differenzen über die Durchschnittswerte. Wir sehen einen leichten Trend dafür, dass die Differenzen sich verändern über die Durchschnittswerte. Angesichts des Konfidenzintervalles (graues Band um die blaue Regressionslinie) können wir jedoch die Nullhypothese (dass die Differenz über alle Wertebereiche 0 ist) beibehalten.
<-bland.altman.stats(data_shoulder$healthy_shoulder_1, data_shoulder$healthy_shoulder_2)
res$upper.limit res
## [1] 13.20601
$lower.limit res
## [1] -12.39633
Dort hatten wir die obere Limit of Agreement bei 13.2 und die untere Limit of Agreement bei -12.4. Die Hälfte des Intervalls ist somit 12.8. Mit der 2.77 Mal SEM Formel kommen wir auf einen SDC95% von 12.8. Wir sehen also, dass der SEM eine Hälfte der Distanz zwischen den Limits of Agreements ist.
35.8 Wir berechnen nun das Gleiche noch für die schmerzhafte Seite:
35.8.1 Variante 1: \(\frac{SD~Difference~}{\sqrt{2}}\) (Achtung: diese Formel berücksichtigt den systematischen Fehler nicht!)
=(sd(data_shoulder$painful_shoulder_2-data_shoulder$painful_shoulder_1))/2^0.5
SEM_painful_shoulder <-SEM_painful_shoulder SEM_variante_1
35.8.2 Variante 2: SDMessung\(\sqrt{(1-ICC)}\)
(Achtung: auch diese Formel berücksichtigt den systematischen Fehler nicht!) Für diese Variante müssen wir zuerst den ICC berechnen. Da diese Formel den systematischen Fehler nicht berücksichtigt, dürfen wir sie nur benutzen, wenn es keinen systematischen Fehler gibt, oder wenn wir ihn nicht berücksichtigen wollen.
Wir benutzen dazu die gepoolte Standardabweichung der beiden Messungen. Die Formel ist unten im R-Chunk. Diese Webseite gibt noch mehr Informationen zu der gepoolten Standardabweichung
<-psych::ICC(data_shoulder[c("painful_shoulder_1", "painful_shoulder_2")]) out
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control$checkConv, :
## Model failed to converge with max|grad| = 0.0178828 (tol = 0.002, component 1)
<-sqrt((sd(data_shoulder$painful_shoulder_1, na.rm=TRUE)^2 +sd(data_shoulder$painful_shoulder_1, na.rm=TRUE)^2)/2)
pooled_sd<-out$results$ICC[3] ICC2_1
Der ICC2,1 für die schmerzhafte Seite ist 0.96
Jetzt können wir die Formel anwenden:
<-pooled_sd*sqrt(1-ICC2_1)
SEM_variante_2 SEM_variante_2
## [1] 4.280763
35.8.3 Variante 3: SEM = \(\sqrt{sigma^2~Error~}\)
Nun ist es nicht ganz so einfach, diese Fehler-Varianz (\(\sigma^2~Error~\)) zu erhalten. Wir können sie aus dem Objekt extrahieren, das wir mit dem ICC Befehls des psych Pakets erhaltenDies sehen wir im nächsten R-Abschnitt:
Den nächsten Code-Abschnitt braucht ihr als Bachelor of Science nicht zu verstehen - Wir brauchen diesen Code um die benötigten Varianzkomponenten zu erhalten. Diese benötigen wir, um den SEM für das Agreement zu berechnen. Wer mehr dazu wissen möchte, sollte den folgenden Artikel lesen: Vet, H. C., Terwee, C. B., Knol, D. L., & Bouter, L. M. (2006). When to use agreement versus reliability measures. Journal of clinical epidemiology, 59(10), 1033-1039
# out
# out$stats
# out$MSW
=nrow(data_shoulder)
numberOfPatients=2
numberOfRaters
<-out$stats[3,1]
varBetweenPatients<-out$stats[3,3]
varResidual<-(varBetweenPatients-varResidual)/numberOfRaters
varTrueBetweenPatients<-out$stats[3,2]
varBetweenRaters<-(varBetweenRaters-varResidual)/numberOfPatients
varTrueBetweenRaters
<-varTrueBetweenPatients/(varTrueBetweenPatients+varTrueBetweenRaters+varResidual)
ICC_agreement# In a lot of publications, you see these formula from Shrout and Fleiss
# ICC_3.1<-(varBetweenPatients-varResidual)/varBetweenPatients
# ICC_3.1
.1 <-(varBetweenPatients-varResidual) / (varBetweenPatients+(numberOfRaters-1)*varResidual+((numberOfRaters*(varBetweenRaters-varResidual))/numberOfPatients))
ICC_2# Method 1, see page 111 in Measurement in Medicine
# For SEMagreement
<-varTrueBetweenRaters+varResidual
varError<-sqrt(varError)
SEMagreement<-SEMagreement SEM_variante_3
SEM Agreement für die schmerzhafte Seite: Der ICC2,1 für die schmerzhafte Seite ist 0.96 mit einem 95% Konfidenzintervall von 0.94 bis 0.97. Wir sehen, dass der ICC für die schmerzhafte Seite, bei vergleichbarem SEM, deutlich besser ist als der ICC für die gesunde Seite. DER SEMagreement der gesunden Schultern, berechnet mit der Formel aus dem Artikel von de Vet und Kolleginnen, ist: 4.33.
Wir können die drei Varianten noch einmal hier darstellen:
Variante 1: 4.4
Variante 2: 4.3
Variante 3: 4.3
35.9 Smallest Detectable Change für die schmerzhafte Seite
Mit der 2.77 Mal SEM Formel kommen wir auf einen SDC95% von 12.001.
- Wir sehen, dass der SDC für die gesunde und die schmerzhafte Seite praktisch gleich ist, obschon der ICC anders ist. Warum? Der SDC wird mit dem SEM berechnet.

Je genauer - d.h. reliabler - wir messen können, desto kleinere Veränderungen können wir zuverlässig erkennen. Ist der Smallest Detectable Change grösser als eine Veränderung des Patienten, sind wir nicht sicher, ob es eine echte Veränderung ist, oder nur ein Messfehler.