Übung 1

Aufgaben

  1. Beschreiben Sie den Unterschied zwischen relativer und absoluter Reliabiliät. Beschreiben Sie wichtige Kennwerte, welche im entsprechenden Kontext relevant sind.
  2. Beschreiben Sie, die ICC-Typen ICC1, ICC2 und ICC3. Nennen Sie die Varianzkomponenten, welche jeweils in den Nenner zur Berechung eingehen.
  3. Sie möchten die Inter-Rater Reliabilität eines Messinstuments bestimmen. Dazu werden 50 Personen von jeweils zwei Ratern gemessen. Ziel es es, eine Aussage über die zwei Rater hinaus zu machen. Welchen ICC berechnen Sie? Begründen Sie.

Lösungen

1: Absolute Reliabilität

  • Bezieht sich auf die Genauigkeit der Einzelwerte in den Einheiten des Messinstruments (z. B. \(\pm\) 2 kg auf einer Waage).
  • Leitfrage: Wie stark weicht ein beobachteter Wert vom „wahren“ Wert einer Person ab?
  • Fokus: Stabilität der Messung einer einzelnen Person über Zeit oder Bedingungen.
  • Wichtige Kennwerte:
    • Standard Error of Measurement (SEM): Schätzt den zufälligen Messfehler in der Einheit der Messung.
    • Minimal Detectable Change (MDC): Kleinste messbare Veränderung, die über den Messfehler hinausgeht.
    • Bias: Systematische Abweichung zwischen wiederholten Messungen oder Messmethoden.
  • Absolute Reliabilität ist wichtig für klinische Entscheidungen auf Individualebene.

1: Relative Reliabilität

  • Bezieht sich auf die Genauigkeit der Rangordnung zwischen Personen auf einer dimensionslosen Skala.
  • Leitfrage: Wie zuverlässig können Personen anhand des Messwerts voneinander unterschieden werden?
  • Fokus: Konsistenz der Unterschiede zwischen Personen, trotz Messfehler.
  • Wichtiger Kennwert: Intraklassen-Korrelationskoeffizient (ICC): Verhältnis der zwischen-Personen-Varianz zur Gesamtvarianz.
    • Hoher ICC = Unterschiede zwischen Personen sind gross im Vergleich zum Messfehler.
    • Es gibt verschiedene ICC-Typen, siehe unten.
  • Relative Reliabilität ist in erster Linie wichtig für Gruppenvergleiche und Forschungszwecke.

2: ICC-Typen

ICC quantifiziert die relative Reliabilität, also das Verhältnis der Varianz zwischen Objekten zur Gesamtvarianz. Je nach Modellannahmen über die Rater unterscheidet man verschiedene ICC-Typen.

ICC1

  • Anwendung: Wenn jede Person von einem zufällig ausgewählten Rater bewertet wird oder Rater nicht explizit modelliert werden.
  • Systematische Raterunterschiede (\(\beta_j\)) werden nicht separat berücksichtigt, da Rater als zufällige Stichprobe gelten.
  • Interpretation: Misst, wie gross der Anteil der Unterschiede zwischen Objekten an der Gesamtvarianz ist.

Formel:

\[ ICC1 = \frac{\sigma_\alpha^2}{\sigma_\alpha^2 + \sigma_\epsilon^2} \]
Varianzkomponenten im Nenner:

  • \(\sigma_\alpha^2\) = Varianz zwischen Objekten
  • \(\sigma_\epsilon^2\) = Restvarianz (Raterunterschiede + zufällige Messfehler)

ICC2

  • Anwendung: Wenn alle Objekte von denselben Ratern bewertet werden und Rater als zufällige Effekte modelliert werden. Wenn Rater als zufällige Effekte modelliert werden heisst das, dass die Ergebnisse auf andere Rater der Population generalisiert werden können.
  • Systematische Raterunterschiede (\(\beta_j\)) werden berücksichtigt.
  • Interpretation: Misst die exakte Übereinstimmung zwischen Ratern, inklusive Bias. Wenn z.B. ein Rater konstant 5 Punkte höher bewertet, sinkt ICC2.

Formel:

\[ ICC2 = \frac{\sigma_\alpha^2}{\sigma_\alpha^2 + \sigma_\beta^2 + \sigma_\epsilon^2} \]

Varianzkomponenten im Nenner:

  • \(\sigma_\alpha^2\) = Varianz zwischen Objekten
  • \(\sigma_\beta^2\) = systematischer Rater-Effekt
  • \(\sigma_\epsilon^2\) = Restvarianz (zufälliger Fehler)

ICC3

  • Anwendung: Wenn alle Objekte von denselben Ratern bewertet werden und Rater als fester Effekt betrachtet werden (nur diese Rater interessieren, keine generalisierung).
  • Systematische Raterunterschiede (\(\beta_j\)) werden herausgerechnet.
  • Interpretation: Misst die Konsistenz der Rangordnung bei den gegebenen Ratern, unabhängig von systematischem Bias.
  • Beispiel: Wenn ein Rater konstant 5 Punkte höher bewertet, bleibt ICC3 = 1.

Formel:

\[ ICC3 = \frac{\sigma_\alpha^2}{\sigma_\alpha^2 + \sigma_\epsilon^2} \]

Varianzkomponenten im Nenner:

  • \(\sigma_\alpha^2\) = Varianz zwischen Objekten
  • \(\sigma_\epsilon^2\) = Restvarianz (zufälliger Fehler, ohne systematischen Rater-Bias)

Zusammenfassung der ICC-Typen

ICC-Typ Modell Rater-Effekt \(\beta_j\) Nenner-Varianzkomponenten Typische Anwendung
ICC1 Einweg-Random-Effects nicht modelliert \(\sigma_\alpha^2 + \sigma_\epsilon^2\) (inkl. Rater-Effekte) Zufällige Einzelratings
ICC2 Two-Way Random als Random berücksichtigt \(\sigma_\alpha^2 + \sigma_\beta^2 + \sigma_\epsilon^2\) Absolute Übereinstimmung
ICC3 Two-Way Mixed als Fixed herausgerechnet \(\sigma_\alpha^2 + \sigma_\epsilon^2\) (ohne Bias) Konsistenz der Rangordnung

3

ICC2 - absolute Übereinstimmung.

Begründung:

  • Gleiche Rater messen alle 50 Personen → zweifaktorielles (two-way) Design.
  • Aussage über die zwei Rater hinaus → Rater als Random-Effect modellieren → ICC2.
  • Bei Inter-Rater-Reliabilität geht es in der Regel um exakte Austauschbarkeit der Rater (Bias soll zählen) → absolute agreement statt nur Konsistenz (also nicht ICC3).
  • Nicht ICC1, da alle Personen von denselben Ratern beurteilt wurden.

Übung 2

Die Rohdaten der Studie mit dem Titel “Test-retest reliability and minimal detectable change scores for the short physical performance battery, one-legged standing test and timed up and go test in patients undergoing hemodialysis” finden Sie auf Moodle. Auf den Volltext können Sie hier zugreifen.

Aufgaben

  1. Laden Sie die Daten in R. Splitten Sie den Datensatz auf nach Test und bringen Sie die drei Teildatensätze in ein long-format. Sie können dafür folgenden Code verwenden:
library(tidyverse)
df.long <- df %>% 
  pivot_longer(cols = c(X,Y), values_to = "value_name", names_to = "time_point")
  1. Reproduzieren Sie die angegebenen ICCs in Tabelle 3. Verwenden Sie das Paket SimplyAgree oder psych (R-Code siehe Slides).

  2. Welchen ICC-Typ haben die Autor:innen berechnet? (siehe auch Methodikteil im Artikel). Interpretieren Sie sinngemäss.

Lösungen

Hier wird der Datensatz importiert, gesplitted nach Test und dann jeweils ins long-format gebracht. Natürlich gibt es auch andere Möglichkeiten, dies zu tun.

library(rio)
df.tests <- import("../data/data-villar.csv")

library(tidyverse)
df.sppb <- df.tests %>% 
  select(ID, SPPB_A, SPPB_B)

df.sppb.long <- df.sppb %>% 
  pivot_longer(cols = c(SPPB_A, SPPB_B), values_to = "value", names_to = "time")

df.olst <- df.tests %>% 
  select(ID, OLST_A, OLST_B)

df.olst.long <- df.olst %>% 
  pivot_longer(cols = c(OLST_A, OLST_B), values_to = "value", names_to = "time")

df.tug <- df.tests %>% 
  select(ID, TUG_A, TUG_B)

df.tug.long <- df.tug %>% 
  pivot_longer(cols = c(TUG_A, TUG_B), values_to = "value", names_to = "time")

Die ICCs erhalten wir wie folgt:

SPPB:

library(SimplyAgree)

reli_stats(
  measure = "value",   # name of the column with ratings
  item = "time",      # rater or time identifier
  id = "ID",      # subject identifier
  data = df.sppb.long, # your data frame
  se_type = "ICC2",   # this is important!
  cv_calc = "MSE",     # how to calculate CV
  conf.level = 0.95,
  other_ci = TRUE
)
## 
## Coefficient of Variation (%): 7.04 95% C.I. [6.04, 8.45]
## Standard Error of Measurement (SEM): 0.71 95% C.I. [0.61, 0.851]
## Standard Error of the Estimate (SEE): 0.69 95% C.I. [0.592, 0.827]
## Standard Error of Prediction (SEP): 0.99 95% C.I. [0.85, 1.19]
## 
## Intraclass Correlation Coefficients
##            Model         Measures  Type    ICC Lower CI Upper CI
## 1 one-way random        Agreement  ICC1 0.9442   0.9183   0.9620
## 2 two-way random        Agreement  ICC2 0.9442   0.9178   0.9622
## 3  two-way fixed      Consistency  ICC3 0.9459   0.9206   0.9632
## 4 one-way random   Avg. Agreement ICC1k 0.9713   0.9574   0.9806
## 5 two-way random   Avg. Agreement ICC2k 0.9713   0.9571   0.9808
## 6  two-way fixed Avg. Consistency ICC3k 0.9722   0.9587   0.9813
  • Die Autoren schreiben: “The ICC (model alpha) and a two-way random-effects model were used to assess the test–retest reliability of the data for all the repeated tests”. Also ICC2.
  • Der Punktschätzer von 0.94 kann reproduziert werden. Das 95% CI kommt leicht anders raus. Das kann z.B. auf die Software und die entsprechend hinterlegten Formeln zurückgeführt werden. Für die Studie haben die Autor;innen SPSS verwendet.
  • Die relative Reliabiliät ist als sehr gut einzuschätzen. Der Test unterscheidet also gut zwischen den Objekten (Personen). Diese Aussage lässt sich auch auf weitere Rater der Population generalisieren. Zudem lieg kein systematischer Fehler vor (ICC3 ist praktisch gleich).


OLST:

library(SimplyAgree)

reli_stats(
  measure = "value",   # name of the column with ratings
  item = "time",      # rater or time identifier
  id = "ID",      # subject identifier
  data = df.olst.long, # your data frame
  se_type = "ICC2",   # this is important!
  cv_calc = "MSE",     # how to calculate CV
  conf.level = 0.95,
  other_ci = TRUE
)
## 
## Coefficient of Variation (%): 34.3 95% C.I. [28.9, 42.4]
## Standard Error of Measurement (SEM): 4.99 95% C.I. [4.27, 6.01]
## Standard Error of the Estimate (SEE): 4.71 95% C.I. [4.03, 5.67]
## Standard Error of Prediction (SEP): 6.86 95% C.I. [5.87, 8.26]
## 
## Intraclass Correlation Coefficients
##            Model         Measures  Type    ICC Lower CI Upper CI
## 1 one-way random        Agreement  ICC1 0.8905   0.8405   0.9255
## 2 two-way random        Agreement  ICC2 0.8905   0.8405   0.9255
## 3  two-way fixed      Consistency  ICC3 0.8905   0.8403   0.9256
## 4 one-way random   Avg. Agreement ICC1k 0.9421   0.9134   0.9613
## 5 two-way random   Avg. Agreement ICC2k 0.9421   0.9134   0.9613
## 6  two-way fixed Avg. Consistency ICC3k 0.9421   0.9132   0.9614
  • Gleiche Bemerkungen wie oben. Der Punktschätzer ist minim verschieden (Rundungsfehler?).

TUG:

library(SimplyAgree)

reli_stats(
  measure = "value",   # name of the column with ratings
  item = "time",      # rater or time identifier
  id = "ID",      # subject identifier
  data = df.tug.long, # your data frame
  se_type = "ICC2",   # this is important!
  cv_calc = "MSE",     # how to calculate CV
  conf.level = 0.95,
  other_ci = TRUE
)
## 
## Coefficient of Variation (%): 10.6 95% C.I. [9.11, 12.8]
## Standard Error of Measurement (SEM): 1.18 95% C.I. [1.01, 1.41]
## Standard Error of the Estimate (SEE): 1.16 95% C.I. [0.995, 1.39]
## Standard Error of Prediction (SEP): 1.65 95% C.I. [1.42, 1.98]
## 
## Intraclass Correlation Coefficients
##            Model         Measures  Type    ICC Lower CI Upper CI
## 1 one-way random        Agreement  ICC1 0.9644   0.9476   0.9758
## 2 two-way random        Agreement  ICC2 0.9644   0.9476   0.9759
## 3  two-way fixed      Consistency  ICC3 0.9645   0.9477   0.9760
## 4 one-way random   Avg. Agreement ICC1k 0.9819   0.9731   0.9878
## 5 two-way random   Avg. Agreement ICC2k 0.9819   0.9731   0.9878
## 6  two-way fixed Avg. Consistency ICC3k 0.9819   0.9731   0.9878
  • Siehe oben.

Übung 3

In dieser Übung werden die STRAIN-Daten zur Messung von Work-Privacy Konflikten bei Pflegefachkräften betrachtet. Work-Privacy Konflikte wurden mittels fünf Fragen des COPSOQ-Fragebogens gemessen. Die Antwortekategorien sind jeweils ordinal-skaliert mit den fünf Kategorien “In sehr hohem Mass”, “In hohem Mass”, “Zum Teil”, “In geringem Mass” und “In sehr geringem Mass”. Die fünf Fragen sind:

  1. Die Anforderungen meiner Arbeit stören mein Privat-/ und Familienleben.
  2. Der Zeitaufwand meiner Arbeit macht es schwierig für mich, meinen Pflichten in der Familie oder im Privatleben nachzukommen.
  3. Meine Arbeit beansprucht so viel Energie, dass sich dies negativ auf mein Privatleben auswirkt.
  4. Meine Arbeit nimmt so viel Zeit in Anspruch, dass sich dies negativ auf mein Privatleben auswirkt.
  5. Es kommt vor, dass ich zur gleichen Zeit zu Hause und bei der Arbeit sein sollte.

Für die Analyse wurden die ordinal-skalierten Antwortekategorien wie folgt zu numerischen Werten rekodiert:

  • In sehr geringem Mass = 0
  • In geringem Mass = 25
  • Zum Teil = 50
  • In hohem Mass = 75
  • In sehr hohem Mass = 100

Aufgaben

  1. Die STRAIN-Daten finden Sie auf Moodle als Datei STRAIN.RData. Speichern Sie diese Datei zuerst in ein lokales Verzeichnis. In R kann die Datei mittels dem Befehl load("STRAIN.RData") eingelesen werden weil es eine R-Datei ist.
  2. Die fünf Variablen zu Working-Privacy Konflikten sind in den STRAIN-Daten df.strain als Spalten cq_wpkonf1, cq_wpkonf2, cq_wpkonf3, cq_wpkonf4 und cq_wpkonf5 abgelegt. Speichern Sie die fünf Variablen in einen neuen data.frame.
  3. Berechnen Sie die Work-Privacy Konflikt-Scores. Der Work-Privacy Konflikt-Score eines Studiensubjekts berechnet sich als Mittelwert der zugehörigen 5 Werte zu den Variablen cq_wpkonf1, cq_wpkonf2, cq_wpkonf3. cq_wpkonf4 und cq_wpkonf5.
  4. Stellen Sie den berechneten Work-Privacy Konflikt-Score in einem Histogramm dar. In welchem Bereich gibt es die meisten Beobachtungen?
  5. Berechnen Sie das Cronbachsche \(\alpha\) mittels der R-Funktion alpha() des Pakets psych. Lesen Sie aus dem Resultat das Cronbachsche \(\alpha\) und das standardisierte Cronbachsche \(\alpha\). Sind diese genügend hoch (vgl. Richtwerte in Vorlesungsunterlagen)? Lesen Sie ebenso aus dem Resultat, bei welchen Variablen das Weglassen zu einem höheren bzw. tieferen Cronbachsche \(\alpha\) führt (Abschnitt Reliability if an item is dropped).
  6. (Optional) Berechnen Sie anhand der Formel aus der Vorlesung das standardisierte Cronbachsche \(\alpha\).

Lösungen

  1. Als erstes wird der Datensatz importiert.
load("../data/STRAIN.RData")
df.strain <- dat.STRAIN # diese Unbenennung ist nicht unbedingt nötig

  1. Die relevanten Variablen werden in einem neuen Datensatz (df.wpkonf) abgespeichert:
df.wpkonf <- df.strain[ , c("cq_wpkonf1", "cq_wpkonf2", "cq_wpkonf3", "cq_wpkonf4", "cq_wpkonf5")]
head(df.wpkonf)
##   cq_wpkonf1 cq_wpkonf2 cq_wpkonf3 cq_wpkonf4 cq_wpkonf5
## 1         25         25         25         25         25
## 2         50         25         75         25          0
## 3         50         50         50         50         50
## 4         25         25         25         25         50
## 5          0         50         25          0          0
## 6          0          0          0          0          0

  1. Berechnen des Work-Privacy Konflikt-Scores (natürlich gibt es andere richtige Wege):
wp.score <- (df.strain$cq_wpkonf1 + df.strain$cq_wpkonf2 + 
         df.strain$cq_wpkonf3 + df.strain$cq_wpkonf4 + df.strain$cq_wpkonf5) / 5

  1. Verteilung des Work-Privacy Konflikt-Scores
hist(wp.score)

Die meisten Beobachtungen (ca. 75%) liegen im Bereich zwischen 0 und 50. Wir sehen, dass die Scores rechtsschief verteilt sind. Alternativ eignet sich auch ein Boxplot, um die Quartile darzustellen:

boxplot(wp.score)


  1. Berechnen Sie das Cronbachsche \(\alpha\) mittels der R-Funktion alpha() des Pakets psych. Lesen Sie aus dem Resultat das Cronbachsche \(\alpha\) und das standardisierte Cronbachsche \(\alpha\). Sind diese genügend hoch (vgl. Richtwerte in Vorlesungsunterlagen)? Lesen Sie ebenso aus dem Resultat, bei welchen Variablen das Weglassen zu einem höheren bzw. tieferen Cronbachsche \(\alpha\) führt (Abschnitt Reliability if an item is dropped).
library(psych)
alpha(df.wpkonf)
## 
## Reliability analysis   
## Call: alpha(x = df.wpkonf)
## 
##   raw_alpha std.alpha G6(smc) average_r S/N    ase mean sd median_r
##        0.9       0.9    0.89      0.64 8.8 0.0071   29 22     0.65
## 
##     95% confidence boundaries 
##          lower alpha upper
## Feldt     0.88   0.9  0.91
## Duhachek  0.88   0.9  0.91
## 
##  Reliability if an item is dropped:
##            raw_alpha std.alpha G6(smc) average_r S/N alpha se  var.r med.r
## cq_wpkonf1      0.87      0.87    0.85      0.63 6.9   0.0092 0.0099  0.62
## cq_wpkonf2      0.87      0.87    0.84      0.62 6.4   0.0097 0.0105  0.63
## cq_wpkonf3      0.88      0.88    0.85      0.64 7.0   0.0090 0.0069  0.63
## cq_wpkonf4      0.86      0.86    0.83      0.60 6.1   0.0102 0.0085  0.61
## cq_wpkonf5      0.90      0.90    0.88      0.70 9.2   0.0073 0.0024  0.70
## 
##  Item statistics 
##              n raw.r std.r r.cor r.drop mean sd
## cq_wpkonf1 500  0.85  0.85  0.80   0.76   34 26
## cq_wpkonf2 500  0.87  0.87  0.84   0.79   30 27
## cq_wpkonf3 500  0.85  0.84  0.80   0.75   33 27
## cq_wpkonf4 500  0.89  0.89  0.87   0.82   27 26
## cq_wpkonf5 500  0.75  0.76  0.66   0.62   20 24

Das Cronbachsche \(\alpha\) und das standardisierte Cronbachsche \(\alpha_{std}\) betragen \(0.9\) und \(0.9\). Diese Werte sind gemäss den Richtwerten aus der Vorlesung “gut” bis “exzellent”. Das Weglassen der Variablen 1 bis 4 führt je zu einem tieferen Cronbachschen \(\alpha_{std}\), und das Weglassen der fünften Variablen hätte keinen negativen Einfluss auf \(\alpha_{std}\). Zudem hat die fünfte Variable den tiefsten Zusammenhang mit dem Summenscore (siehe Item statistics)


  1. (Optional) Berechnen Sie anhand der Formel aus der Vorlesung das standardisierte Cronbachsche \(\alpha_{\text{std}}\).

Standardisiertes Cronbachsches alpha:

\[ \alpha_{\text{std}} = \frac{k \cdot \bar{r}}{1 + (k-1) \cdot \bar{r}} \] Wir berechnen zuerst die paarweisen Korrelationen der \(k=5\) Items:

cor.cq.wpkonf <- cor(df.wpkonf)
cor.cq.wpkonf 
##            cq_wpkonf1 cq_wpkonf2 cq_wpkonf3 cq_wpkonf4 cq_wpkonf5
## cq_wpkonf1  1.0000000  0.7267348  0.6709312  0.6554320  0.5167773
## cq_wpkonf2  0.7267348  1.0000000  0.6353824  0.7273329  0.5872147
## cq_wpkonf3  0.6709312  0.6353824  1.0000000  0.7616160  0.4863276
## cq_wpkonf4  0.6554320  0.7273329  0.7616160  1.0000000  0.6071124
## cq_wpkonf5  0.5167773  0.5872147  0.4863276  0.6071124  1.0000000

In der Korrelationsmatrix sehen wir, dass die Items relativ stark miteinander korrelieren. Die Items 3 und 4 korrelieren am stärksten. Die Matrix ist gespiegelt (jeder Wert kommt doppelt vor), wir brauchen nur die untere Hälfte. Wir bekommen diese Werte mit der Funktion lower.tri:

cor.cq.wpkonf[lower.tri(cor.cq.wpkonf)]
##  [1] 0.7267348 0.6709312 0.6554320 0.5167773 0.6353824 0.7273329 0.5872147
##  [8] 0.7616160 0.4863276 0.6071124

\(\bar{r}\) erhalten wir als Mittelwert dieser Korrelationskoeffizienten:

r.bar <- mean(cor.cq.wpkonf[lower.tri(cor.cq.wpkonf)])

Nun setzen wir in die Formel ein:

k <- 5
(k*r.bar) / (1 + (k-1) * r.bar)
## [1] 0.8978818