Kapitel 33 Reliabilitaet: ICC

33.1 Reliabilität mit ICC

Im letzten Kapitel haben wir den Messfehler (SEM, Standard Error of Measurement) kennengelernt. In diesem Kapitel besprechen wir zuerst den Intraclass Correlation Coefficient, den ICC. Dieser hängt einerseits vom Messfehler ab, anderseits von der Variabilität zwischen den gemessenen Patientinnen und Patienten. Danach betrachten wir drei Berechnungen für den SEM.

Am Ende des Kapitels wissen wir folgendes:

  • ICC ist ein Reliabilitätsindex, der mit dem Korrelationsindex verwandt ist
  • Es gibt verschiedene Formeln für den ICC, die anhand der Situation ausgewählt werden
  • Der ICC ist ein Quotient (Verhältnis) von Varianzen - Wir kennen die Varianzen zwischen den Patienten, die Varianzen zwischen zwei Messungen, und die Residual-Varianz
  • 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 wir der ICC höher (besser) sein, wenn die Standardabweichung des Merkmals grösser ist.

33.2 Beispiel schmerzhafte und gesunde Schulter

Schauen wir uns den ICC an einem Beispiel an. Zuerst laden wir ein paar R-Pakete.

library(psych)
library(tidyverse)
library(janitor)
library(BlandAltmanLeh)

33.3 Simulieren der Daten

Jetzt simulieren wir Daten für die schmerzhaften und die gesunden Schultern.

par(mfrow=c(1,2)) # Plot side by side

sampleSize=100
painful_shoulder<-rnorm(sampleSize, 90, 20)
hist(painful_shoulder)

healthy_shoulder<-rnorm(sampleSize, 180, 2)
hist(healthy_shoulder)
Histogramm der gesunden und der schmerzhaften Schultern

Abbildung 2.8: Histogramm der gesunden und der schmerzhaften Schultern

id<-1:sampleSize

data_shoulder<-data.frame(id, painful_shoulder, healthy_shoulder)

33.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))
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.

Abbildung 33.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] 2.232619
sd(painful_shoulder)
## [1] 20.69921

33.5 Simulieren der Test-Retest Fehler

data_shoulder<-data_shoulder %>% 
  mutate(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))

33.6 Streudiagramm mit den Test-Retest Messungen

wir können das Streudiagramm einfach mit den base-R Plot Befehlen darstellen:

plot(data_shoulder$painful_shoulder_1, data_shoulder$painful_shoulder_2, xlim=c(0,150), ylim=c(0,150),xaxs="i", yaxs="i")
abline(lm(data_shoulder$painful_shoulder_2~data_shoulder$painful_shoulder_1))
Streudiagramm der Messungen in der schmerzhaften Schulter beim ersten und zweiten Test. Wir sehen, dass es praktisch keine systematische Abweichungen zwischen den beiden Messungen gibt.

Abbildung 33.2: Streudiagramm der Messungen in der schmerzhaften Schulter beim ersten und zweiten Test. Wir sehen, dass es praktisch keine systematische Abweichungen zwischen den beiden Messungen gibt.

Es gibt jedoch eine Darstellungsform, die uns den zufälligen Fehler und den systematischen Fehler noch besser darstellt: den Bland-Altman Plot.

33.7 Bland-Altman Plot

Eine andere Darstellungsform ist der Bland-Altman Plot.

library(MethComp)
library(BlandAltmanLeh)
mean(data_shoulder$painful_shoulder_1)
## [1] 93.06765
mean(data_shoulder$painful_shoulder_2)
## [1] 92.57516
bland.altman.plot(data_shoulder$painful_shoulder_1, data_shoulder$painful_shoulder_2, main="This is a Bland Altman Plot", xlab="Means painful_shoulder_1, painful_shoulder_2", ylab="Difference painful_shoulder_1 - painful_shoulder_2")
## NULL
bland.altman.plot(data_shoulder$healthy_shoulder_1, data_shoulder$healthy_shoulder_2, main="This is a Bland Altman Plot", xlab="Means healthy_shoulder_1, healthy_shoulder_2", ylab="Difference healthy_shoulder_1 - healthy_shoulder_2")
## NULL
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.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.

Abbildung 33.3: 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.

33.8 Berechnen des ICC mit dem Paket psych

Wir schauen uns zuerst die gesunden Schultern an:

psych::ICC(data_shoulder[c("healthy_shoulder_1", "healthy_shoulder_2")])
## 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.23 1.6  99 100 0.0097       0.038        0.41
## Single_random_raters     ICC2 0.24 1.6  99  99 0.0082       0.045        0.41
## Single_fixed_raters      ICC3 0.24 1.6  99  99 0.0082       0.045        0.41
## Average_raters_absolute ICC1k 0.38 1.6  99 100 0.0097       0.074        0.58
## Average_random_raters   ICC2k 0.38 1.6  99  99 0.0082       0.086        0.58
## Average_fixed_raters    ICC3k 0.39 1.6  99  99 0.0082       0.086        0.59
## 
##  Number of subjects = 100     Number of Judges =  2
## See the help file for a discussion of the other 4 McGraw and Wong estimates,

Wir sehen, dass die Reliabilität für die gesunden Schultern nicht gut ist. Der Grund ist, dass hier die Standardabweichungen der Beweglichkeit der gesunden Schultern sehr gering ist, da praktisch alle Personen ihre Schulter bis 180° heben können. So gibt es praktisch keine Variabilität (d.h. SD klein).

Nun schauen wir uns die ICCs für die schmerzhafte Seite an:

psych::ICC(data_shoulder[c("painful_shoulder_1", "painful_shoulder_2")])
## boundary (singular) fit: see help('isSingular')
## Call: psych::ICC(x = data_shoulder[c("painful_shoulder_1", "painful_shoulder_2")])
## 
## Intraclass correlation coefficients 
##                          type  ICC  F df1 df2       p lower bound upper bound
## Single_raters_absolute   ICC1 0.93 29  99 100 1.3e-46        0.90        0.95
## Single_random_raters     ICC2 0.93 29  99  99 3.1e-46        0.90        0.95
## Single_fixed_raters      ICC3 0.93 29  99  99 3.1e-46        0.90        0.95
## Average_raters_absolute ICC1k 0.97 29  99 100 1.3e-46        0.95        0.98
## Average_random_raters   ICC2k 0.97 29  99  99 3.1e-46        0.95        0.98
## Average_fixed_raters    ICC3k 0.97 29  99  99 3.1e-46        0.95        0.98
## 
##  Number of subjects = 100     Number of Judges =  2
## See the help file for a discussion of the other 4 McGraw and Wong estimates,
Hier sind die ICCs gut, da die Standardabweichung der Beweglichkeit der schmerzhaften Schultern gross ist.

Trotz gleichem Messfehler gibt es - abhängig von der Variabilität der gemessenen Schultern - unterschiedliche ICC Werte für die Reliabilität.

Zusätzlich sehen wir: Es gibt unterschiedliche ICC Typen mit unterschiedlichen Formeln - Wir müssen entscheiden, welcher ICC wir benutzen. * ICC1 –>(ist eigentlich ICC1,1) Wenn nicht alle Patienten vom selben Therapeuten untersucht wurden. Dieser ICC-Typ berücksichtigt auch den systematischen Fehler * ICC2 –> (ist eigentlich ICC2,1) Wenn wir von den Physiotherapeuten in der Studien auf andere Physiotherapeuten schliessen wollen (was wir meistens tun wollen). * ICC3 –> (ist eigentlich ICC3,1) Wenn uns nur die Physiotherapeuten der Studie interessieren - zum Beispiel, wenn wir für eine zukünftige Studie die Reliabilität der Physiotherapeuten testen wollen: hier interessieren uns nur die Physiotherapeuten die wir untersuchen. * Die ICCx,k –> Für Situationen, wo wir mehrmals testen und dann den Mittelwert dieser Tests nehmen. Das k bedeutet, wie oft wir testen. Beispiel: Wenn wir eine Test-Retest Studie machen, könnten wir am ersten Test-Tag drei mal testen und danach den Mittelwert für die Berechnungen des ICCs nehmen. Am zweiten Test-Tag (d.h. dem Re-Test Tag), würden wir auch wieder drei Mal messen und den Mittelwert für die Berechnung des ICCs nehmen.

Das folgende Help-File des psych::IcC Befehls ist auch sehr interessant. Hier auch der Link zu einem Buch über psychometric theory.

Benutzen wir das psych Paket und die ICC Befehle, werden wir nicht genau die gleichen Konfidenzintervalle erhalten, wie man sie mit dem Statistikprogramm SPSS erhalten würde. Möchten wir die genau gleichen Konfidenzintervalle haben, so können wir das Paket irr und der Befehl icc nehmen.

Zum Beispiel der folgende Befehl wird das Modell ICC2.1 berechnen:

irr::icc(data_shoulder[c("painful_shoulder_1", "painful_shoulder_2")], model="twoway", type="agreement", unit="single")
##  Single Score Intraclass Correlation
## 
##    Model: twoway 
##    Type : agreement 
## 
##    Subjects = 100 
##      Raters = 2 
##    ICC(A,1) = 0.934
## 
##  F-Test, H0: r0 = 0 ; H1: r0 > 0 
##  F(99,99.7) = 29 , p = 2.25e-46 
## 
##  95%-Confidence Interval for ICC Population Values:
##   0.903 < ICC < 0.955

For a comparison between the models, see below and here:

ICC(1,1) = \(\frac{σ^2_r}{σ^2_r + σ^2_w}\) = \(\frac{MS~between~subjects}{MS~between~ + (number~ raters-1)*MS~within~subjects}\) = SPSS One-Way Random Model, Absolute Agreement, Single Measure

ICC(1,k) = SPSS One-Way Random Model, Absolute Agreement, Average Measure

ICC(2,1) = \(\frac{σ^2_r}{σ^2_r + σ^2_c +σ^2_{rc} + σ^2_e}\) = \(\frac{MS~between~subjects - MS~error}{MS~between~subjects + \frac{number~raters*(MS~between~measurements - MS~error)}{number~patients}}\) = SPSS Two-Way Random Model, Absolute Agreement, Single Measure

Wir können diese Formel auch benutzen, um selber den ICC2.1zu berechnen (mit dem Befehl ICC aus dem psych Paket).

out<-psych::ICC(data_shoulder[c("painful_shoulder_1", "painful_shoulder_2")])
## boundary (singular) fit: see help('isSingular')
out
## Call: psych::ICC(x = data_shoulder[c("painful_shoulder_1", "painful_shoulder_2")])
## 
## Intraclass correlation coefficients 
##                          type  ICC  F df1 df2       p lower bound upper bound
## Single_raters_absolute   ICC1 0.93 29  99 100 1.3e-46        0.90        0.95
## Single_random_raters     ICC2 0.93 29  99  99 3.1e-46        0.90        0.95
## Single_fixed_raters      ICC3 0.93 29  99  99 3.1e-46        0.90        0.95
## Average_raters_absolute ICC1k 0.97 29  99 100 1.3e-46        0.95        0.98
## Average_random_raters   ICC2k 0.97 29  99  99 3.1e-46        0.95        0.98
## Average_fixed_raters    ICC3k 0.97 29  99  99 3.1e-46        0.95        0.98
## 
##  Number of subjects = 100     Number of Judges =  2
## See the help file for a discussion of the other 4 McGraw and Wong estimates,

Oben sehen wir alle ICCs.

Wir sehen in der Tabelle unten die benötigten Varianzkomponenten.

DT::datatable(out$stats)
  • df = Degree of Freedom

  • SumSq = Sum of Squares

  • MS = Mean Square = Varianz

  • MS in der Spalte Judges = MS between measurements (je nach Situation ist es korrekter von Judges (Ratern) zu sprechen oder von Measurement. In einer Test-Retest Situation würden wir eher von Measurements reden, in einer Inter-Rater Reliabilitäts Situation würden wir eher von Ratern oder Judges sprechen.)

Die Varianz innerhalb der Teilnehmer / Patienten finden wir hier:

out$MSW
## [1] 28.41981

Jetzt können wir die benötigten Varianzen auslesen um sie dann in der Formel zu benutzen:

Wir finden die Anzahl Patienten mit folgendem Befehl:

numberOfPatients=nrow(data_shoulder)
numberOfPatients
## [1] 100

Die Anzahl der Rater können wir manuell eingeben (oder wir würden sie mit der zweiten Zeile finden):

numberOfRaters=2

numberOfRaters=out$stats[1,2]+1
numberOfRaters
## [1] 2

Die Varianz (Mean Squares) zwischen den Patienten:

varBetweenPatients<-out$stats[3,1]

Die Fehlervarianz (Mean Square Error, MSE)

varResidual<-out$stats[3,3]
varResidual
## [1] 28.41981

Die wahre Varianz zwischen den Patienten (die oben genannte Patientenvarianz beinhaltet ja auch den Messfehler, deswegen müssen wir die Fehlervarianz abziehen)

varTrueBetweenPatients<-(varBetweenPatients-varResidual)/numberOfRaters
varTrueBetweenPatients
## [1] 399.885

Die Varianz zwischen den Ratern (oft auch MSJ, d.h. Mean Square Judges genannt, oder eben je nach Situation auch Varianz zwischen den Messzeitpunkten, oben MS between measurements).

varBetweenRaters<-out$stats[3,2]
varBetweenRaters
## [1] 28.41981

Auch da können wir wieder die wahre Varianz zwischen den Ratern/Messunten berechnen.

varTrueBetweenRaters<-(varBetweenRaters-varResidual)/numberOfPatients
varTrueBetweenRaters
## [1] 0

Jetzt können wir die Formel ICC2.1 wie folgt umsetzen:

ICC_agreement<-varTrueBetweenPatients/(varTrueBetweenPatients+varTrueBetweenRaters+varResidual)
round(ICC_agreement,2)
## [1] 0.93
Der ICC2.1 berechnet mit dem Paket psych und dem Befehl ICC ist 0.93, von “Hand” berechnet ist er 0.93. Wir haben also alles richtig gemacht.

Zum Vergleich jetzt noch einmal das Paket irr mit dem Befehl icc:

irr::icc(data_shoulder[c("painful_shoulder_1", "painful_shoulder_2")], model="twoway", type="agreement", unit="single")
##  Single Score Intraclass Correlation
## 
##    Model: twoway 
##    Type : agreement 
## 
##    Subjects = 100 
##      Raters = 2 
##    ICC(A,1) = 0.934
## 
##  F-Test, H0: r0 = 0 ; H1: r0 > 0 
##  F(99,99.7) = 29 , p = 2.25e-46 
## 
##  95%-Confidence Interval for ICC Population Values:
##   0.903 < ICC < 0.955

Der ICC2.1 wird wie folgt übersetzt: ICC(2,k) = SPSS Two-Way Random Model, Absolute Agreement, Average Measure

irr::icc(data_shoulder[c("painful_shoulder_1", "painful_shoulder_2")], model="twoway", type="agreement", unit="average")
##  Average Score Intraclass Correlation
## 
##    Model: twoway 
##    Type : agreement 
## 
##    Subjects = 100 
##      Raters = 2 
##    ICC(A,2) = 0.966
## 
##  F-Test, H0: r0 = 0 ; H1: r0 > 0 
##  F(99,99.7) = 29 , p = 2.23e-46 
## 
##  95%-Confidence Interval for ICC Population Values:
##   0.949 < ICC < 0.977

Hier der ICC3,1 ICC(3,1) = \(\frac{σ^2_r}{σ^2_r + σ^2_c + σ^2_e}\) = \(\frac{MS~between~subjects - MS~error }{MS~between~subjects + (number~raters-1)*MS ~error}\) = SPSS Two-Way Mixed Model, Consistency, Single Measure

irr::icc(data_shoulder[c("painful_shoulder_1", "painful_shoulder_2")], model="twoway", type="consistency", unit="single")
##  Single Score Intraclass Correlation
## 
##    Model: twoway 
##    Type : consistency 
## 
##    Subjects = 100 
##      Raters = 2 
##    ICC(C,1) = 0.933
## 
##  F-Test, H0: r0 = 0 ; H1: r0 > 0 
##    F(99,99) = 29 , p = 4.03e-46 
## 
##  95%-Confidence Interval for ICC Population Values:
##   0.902 < ICC < 0.955

Der ICC3,k: ICC(3,k) = SPSS Two-Way Mixed Model, Consistency, Average Measure

irr::icc(data_shoulder[c("painful_shoulder_1", "painful_shoulder_2")], model="twoway", type="consistency", unit="average")
##  Average Score Intraclass Correlation
## 
##    Model: twoway 
##    Type : consistency 
## 
##    Subjects = 100 
##      Raters = 2 
##    ICC(C,2) = 0.965
## 
##  F-Test, H0: r0 = 0 ; H1: r0 > 0 
##    F(99,99) = 29 , p = 4.03e-46 
## 
##  95%-Confidence Interval for ICC Population Values:
##   0.949 < ICC < 0.977

Falls Sie etwas mehr über die Formeln zu den Varianzkomponenten lernen möchten, finden Sie hier (klicken Sie) eine gute Sammlung der Formeln.

33.9 Wie hoch sollte ein ICC sein?

  • 0.9 für den Einsatz in der Praxis (d.h. an einzelnen Patienten)

  • 0.7 für den Einsatz in Studien - Wobei die benötigte Stichprobengrösse steigt, wenn die Reliabilität sinkt.

Eine Erklärung finden Sie im Kapitel Reliabilität des Buches Measurement in Medicine auf Seite 142.

In einem folgenden Kapitel werden wir auch ein Beispiel aus dem Buch Measurement in Medicine nachrechnen.

Statistik ist ja schön und gut, aber reliables Messen will geübt sein.