H1 – Schulformunterschiede im Selbstwert

PACO-SIM | Deskriptive Statistik, ANOVA und Visualisierung

Veröffentlichungsdatum

12. März 2026

Der Prompt für Claude Sonnet 4.6 (free version)

# Persona 
Du bist Expert:in für Statistik mit Schwerpunkt Methoden in den Sozialwissenschaften und Visualisierung.

# Task
Erstelle ein Quarto-Dokument, welches Daten einließt und anschließend eine ANOVA durchführt und die Daten sinnvoll visualisiert. Basiere das Quarto Dokument auf den unter "#Context" bereitgestellten R-Code und entferne die Pipe-Operatoren und ersetze diese durch Base-R code. Entferne tidyverse.

# Context
````
rstudioapi::documentPath() |> dirname() |> setwd()
# Pakete laden
library(tidyverse)
# Daten einlesen
df <- read_csv("paco_sim_workshop.csv")
# Schritt 1: Auf Tag 1 filtern und Summenscore bilden
df_t1 <- df |>
  filter(day == 1) |>
  mutate(selfesteem_sum = child_selfesteem_1 + child_selfesteem_2 + child_selfesteem_3)
# Schritt 2: Deskriptive Statistiken nach Schulform
df_t1 |>
  group_by(school_type) |>
  summarise(
    M  = mean(selfesteem_sum, na.rm = TRUE),
    SD = sd(selfesteem_sum, na.rm = TRUE),
    n  = n()
  )
# Schritt 3: ANOVA – Selbstwert ~ Schulform
anova_h1 <- aov(selfesteem_sum ~ school_type, data = df_t1)
summary(anova_h1)
# Schritt 4: Boxplot
ggplot(df_t1, aes(x = school_type, y = selfesteem_sum, fill = school_type)) +
  geom_boxplot() +
  labs(
    title = "H1: Selbstwert zu Studienbeginn nach Schulform",
    x = "Schulform",
    y = "Selbstwert (Summenscore)"
  ) +
  theme_minimal() +
  theme(legend.position = "none")
`````

# Format
Erstelle ein Quarto-Dokument auf Deutsch mit:
1) R-Code, der innerhalb des Codes erklärt wird auf PhD Niveau für Sozialwissenschaften
2) Keine Pipe-Operatoren enthält
3) Die Ergebnisse sollen mit Inline Code interpretiert werden
4) Stelle den Ouptut des linearen Modells (ANOVA) als eine APA Tabelle mit einem entsprechenden geeigneten Paket dar

# Tone
Wissenschaftlich und präzise.

Im Chat als zusätzlichen Context (RAG) lagen:

  • Hypothesen.html
  • PACO_SIM_Codebook.html
  • prompt_engineering_aufgabe.html [vermutlich irrelevant…]

Der Code innerhalb des Prompts wurde zuvor durch einen iterativen Prozess erstellt…

Hypothese und Analyseziel

H1: Kinder aus unterschiedlichen Schulformen unterscheiden sich bereits zu Beginn des Untersuchungszeitraums signifikant in ihrem State-Selbstwert.

Da child_selfesteem als Level-1-Variable im Tagebuchdesign erhoben wurde, beschränkt sich die Analyse auf den ersten Studientag (Tag 1), um einen querschnittlichen Gruppenvergleich zu ermöglichen. Der Selbstwert wird als Summenscore der drei Items operationalisiert (Wertebereich: 3–21).


Daten einlesen und aufbereiten

# Arbeitsverzeichnis setzen – Pfad relativ zur .qmd-Datei
# rstudioapi::documentPath() |> dirname() |> setwd()
# Alternativ explizit:
# setwd("/pfad/zum/projektordner")

# Daten einlesen (Base-R)
df <- read.csv("paco_sim_workshop.csv", stringsAsFactors = FALSE)

# Schritt 1: Auf Tag 1 filtern
# day == 1 wählt ausschließlich den ersten Erhebungstag;
# so wird sichergestellt, dass jedes Kind genau einmal in die Analyse eingeht.
df_t1 <- df[df$day == 1, ]

# Summenscore Selbstwert: Summe der drei Rohwert-Items (je 1–7)
# Summenscores sind bei gleicher Itemanzahl äquivalent zu Mittelwertscores
# und erleichtern die Interpretation des Gesamtwertebereichs (3–21).
df_t1$selfesteem_sum <- df_t1$child_selfesteem_1 +
                        df_t1$child_selfesteem_2 +
                        df_t1$child_selfesteem_3

# Schulform als geordneten Faktor kodieren
# Gymnasium dient als Referenzkategorie für spätere Kontraste.
df_t1$school_type <- factor(
  df_t1$school_type,
  levels = c("Gymnasium", "Realschule", "Hauptschule", "Grundschule")
)

Deskriptive Statistiken

# tapply() wendet eine Funktion gruppenweise an – Base-R-Äquivalent zu group_by + summarise.
# Ergebnis sind benannte Vektoren, die zu einem data.frame zusammengeführt werden.
desc_M  <- tapply(df_t1$selfesteem_sum, df_t1$school_type, mean,   na.rm = TRUE)
desc_SD <- tapply(df_t1$selfesteem_sum, df_t1$school_type, sd,     na.rm = TRUE)
desc_n  <- tapply(df_t1$selfesteem_sum, df_t1$school_type, length)

desc_table <- data.frame(
  Schulform = names(desc_M),
  M         = round(desc_M,  2),
  SD        = round(desc_SD, 2),
  n         = as.integer(desc_n),
  row.names = NULL
)

# Ausgabe der deskriptiven Tabelle
knitr::kable(
  desc_table,
  caption = "Tabelle 1. Deskriptive Statistiken des Selbstwerts (Summenscore) nach Schulform (Tag 1).",
  col.names = c("Schulform", "*M*", "*SD*", "*n*"),
  align = "lrrr"
)
Tabelle 1. Deskriptive Statistiken des Selbstwerts (Summenscore) nach Schulform (Tag 1).
Schulform M SD n
Gymnasium 14.18 4.68 177
Realschule 13.59 4.73 133
Hauptschule 13.90 4.91 30
Grundschule 13.68 4.74 108

ANOVA

# Einfaktorielle ANOVA: Selbstwert ~ Schulform
# aov() schätzt ein lineares Modell und partitioniert die Gesamtvarianz in
# Zwischen-Gruppen-Varianz (school_type) und Fehlerstreuung (Residuals).
anova_h1 <- aov(selfesteem_sum ~ school_type, data = df_t1)

# summary() liefert die klassische ANOVA-Tabelle mit F-Statistik und p-Wert.
anova_summary <- summary(anova_h1)
anova_summary
             Df Sum Sq Mean Sq F value Pr(>F)
school_type   3     32   10.62   0.476  0.699
Residuals   444   9915   22.33               

APA-konforme Ergebnistabelle

# apaTables::anova1way() oder alternativ: manuelle APA-Tabelle mit knitr::kable()
# Hier: robuste manuelle Lösung, die keine zusätzlichen Paketabhängigkeiten erfordert
# und exakt die benötigten Spalten nach APA 7 enthält.

anova_df <- data.frame(
  Quelle     = c("Schulform", "Residuen", "Total"),
  SS         = c(
    round(ss_group, 2),
    round(ss_resid, 2),
    round(ss_group + ss_resid, 2)
  ),
  df         = c(df_num, df_den, df_num + df_den),
  MS         = c(
    round(ss_group / df_num, 2),
    round(ss_resid / df_den, 2),
    NA
  ),
  F          = c(f_val, NA, NA),
  p          = c(ifelse(p_val < .001, "< .001", round(p_val, 3)), NA, NA),
  `eta2`     = c(eta_sq, NA, NA),
  check.names = FALSE
)

knitr::kable(
  anova_df,
  caption  = "Tabelle 2. Einfaktorielle ANOVA: Selbstwert nach Schulform (Tag 1).",
  col.names = c("Quelle", "*SS*", "*df*", "*MS*", "*F*", "*p*", "*η²*"),
  align    = "lrrrrrr",
  na       = ""
)
Tabelle 2. Einfaktorielle ANOVA: Selbstwert nach Schulform (Tag 1).
Quelle SS df MS F p η²
Schulform 31.87 3 10.62 0.48 0.699 0.003
Residuen 9914.83 444 22.33 NA NA NA
Total 9946.69 447 NA NA NA NA

Ergebnisinterpretation

Die einfaktorielle ANOVA ergab einen nicht signifikanten Unterschied im State-Selbstwert zwischen den vier Schulformen zum ersten Studientag, F(3, 444) = 0.48, p = 0.699, η² = 0.003. Der Effekt ist nach konventionellen Benchmarks als klein einzustufen (η² < .06). Das bedeutet, dass 0.3 % der Gesamtvarianz im Selbstwert auf Schulformzugehörigkeit zurückgeführt werden können.

Methodischer Hinweis: Die ANOVA setzt Varianzhomogenität voraus (Levene-Test empfohlen) und prüft lediglich den Omnibus-Effekt. Für gerichtete Hypothesen zu spezifischen Schulformpaaren sind Post-hoc-Tests (z. B. Tukey-HSD) oder geplante Kontraste erforderlich.


Visualisierung

# Farbpalette (farbenblindfreundlich, angelehnt an Okabe-Ito)
farben <- c(
  "Gymnasium"   = "#0072B2",
  "Realschule"  = "#009E73",
  "Hauptschule" = "#E69F00",
  "Grundschule" = "#CC79A7"
)

# Boxplot in Base-R
# par() setzt globale Grafikparameter; mar justiert die Randabstände (unten, links, oben, rechts)
par(mar = c(5, 5, 3, 1), family = "sans")

boxplot(
  selfesteem_sum ~ school_type,
  data     = df_t1,
  col      = farben[levels(df_t1$school_type)],
  border   = "grey30",
  xlab     = "Schulform",
  ylab     = "Selbstwert (Summenscore)",
  main     = "H1: Selbstwert zu Studienbeginn nach Schulform",
  cex.lab  = 1.1,
  cex.axis = 0.95,
  las      = 1,       # Achsenbeschriftungen horizontal
  ylim     = c(3, 21) # Vollständiger Wertebereich des Summenscores
)

# Mittelwerte als gefüllte Rauten einzeichnen
# points() ergänzt den Boxplot um Lagemaße, die im Boxplot selbst nicht sichtbar sind.
means_ordered <- desc_M[levels(df_t1$school_type)]
points(
  x   = seq_along(levels(df_t1$school_type)),
  y   = means_ordered,
  pch = 18,   # Raute
  col = "white",
  cex = 1.6
)
points(
  x   = seq_along(levels(df_t1$school_type)),
  y   = means_ordered,
  pch = 5,    # offene Raute als Kontur
  col = "grey20",
  cex = 1.6,
  lwd = 1.5
)

# Legende
legend(
  "topright",
  legend = "Mittelwert (◇)",
  bty    = "n",
  cex    = 0.85
)
Abbildung 1: Abbildung 1. Verteilung des Selbstwerts (Summenscore, Tag 1) nach Schulform. Horizontale Linien kennzeichnen Mediane, Punkte Ausreißer.
par(mar = c(5, 5, 3, 1), family = "sans")

# Stripchart: zeigt alle Einzelbeobachtungen und vermeidet die Informationsverdichtung
# des Boxplots – besonders sinnvoll bei ungleichen Gruppengrößen (Hauptschule: n = 30).
stripchart(
  selfesteem_sum ~ school_type,
  data    = df_t1,
  method  = "jitter",   # leichte Streuung zur Vermeidung von Überlagerungen
  jitter  = 0.15,
  pch     = 16,
  col     = adjustcolor(farben[levels(df_t1$school_type)], alpha.f = 0.45),
  vertical = TRUE,
  xlab    = "Schulform",
  ylab    = "Selbstwert (Summenscore)",
  main    = "H1: Einzelbeobachtungen mit M ± 1 SD",
  cex.lab = 1.1,
  ylim    = c(3, 21),
  las     = 1
)

# Mittelwert und SD-Balken je Gruppe einzeichnen
for (i in seq_along(levels(df_t1$school_type))) {
  gruppe <- levels(df_t1$school_type)[i]
  m_i  <- desc_M[gruppe]
  sd_i <- desc_SD[gruppe]

  # Mittelwertlinie
  segments(x0 = i - 0.2, x1 = i + 0.2, y0 = m_i, y1 = m_i,
           lwd = 2.5, col = farben[gruppe])

  # SD-Whisker
  arrows(x0 = i, x1 = i,
         y0 = m_i - sd_i, y1 = m_i + sd_i,
         angle = 90, code = 3, length = 0.08,
         lwd = 1.8, col = farben[gruppe])
}
Abbildung 2: Abbildung 2. Streudiagramm (Stripchart) der Einzelbeobachtungen überlagert mit Mittelwert ± 1 SD nach Schulform.

Zusammenfassung

Die deskriptiven Befunde und die ANOVA-Ergebnisse liefern keine empirische Evidenz für H1: Kinder unterscheiden sich zum ersten Erhebungstag nicht signifikant in ihrem State-Selbstwert in Abhängigkeit von der besuchten Schulform (F[3, 444] = 0.48, p = 0.699, η² = 0.003). Der höchste mittlere Selbstwert findet sich bei Gymnasium (M = 14.18, SD = 4.68), der niedrigste bei Realschule (M = 13.59, SD = 4.73). Für eine vollständige Prüfung von H1 sind Post-hoc-Kontraste sowie – als methodisch stringentere Alternative – ein latenter Multigruppenvergleich mit vorheriger Messinvarianzprüfung empfehlenswert (vgl. Stufe 3 der Modellierungsvorschläge).