# 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.H1 – Schulformunterschiede im Selbstwert
PACO-SIM | Deskriptive Statistik, ANOVA und Visualisierung
Der Prompt für Claude Sonnet 4.6 (free version)
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"
)| 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 = ""
)| 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
)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])
}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).