## Setup

Bevor wir starten, müssen die nötigen Pakete geladen werden. Falls `infer` noch nicht installiert ist (z.B. auf Posit Cloud), einmalig den folgenden Chunk ausführen:

```{r}
#| label: setup-install
#| eval: false
install.packages(c("tidyverse", "infer"))
```

```{r}
#| label: setup-libraries
library(tidyverse)
library(infer)
```

Wir erzeugen einen gemeinsamen Datensatz für die Abschnitte 1–3:

```{r}
#| label: setup-data
set.seed(42)
kunden_zufriedenheit <- tibble(
  zufriedenheit = c(rnorm(50, 7.2, 1.5), rnorm(50, 6.8, 1.5)),
  gruppe = rep(c("A", "B"), each = 50)
)
```

## 1. Bootstrapping mit infer

Bootstrapping erzeugt durch wiederholtes Ziehen mit Zurücklegen eine Verteilung des Mittelwerts und daraus ein Konfidenzintervall — ganz ohne Verteilungsannahmen.

```{r}
#| label: bootstrap-dist
bootstrap_dist <- kunden_zufriedenheit %>%
  filter(gruppe == "A") %>%
  specify(response = zufriedenheit) %>%
  generate(reps = 1000, type = "bootstrap") %>%
  calculate(stat = "mean")

ci_95 <- bootstrap_dist %>%
  get_confidence_interval(level = 0.95, type = "percentile")

print(ci_95)
```

Das 95%-Konfidenzintervall reicht von `r round(ci_95$lower_ci, 2)` bis `r round(ci_95$upper_ci, 2)`.

```{r}
#| label: fig-bootstrap
#| fig-cap: "Bootstrap-Verteilung des Mittelwerts mit 95%-Konfidenzintervall"
bootstrap_dist %>%
  visualize() +
  shade_confidence_interval(endpoints = ci_95) +
  labs(title = "Bootstrap-Verteilung des Mittelwerts",
       subtitle = "mit 95%-Konfidenzintervall")
```

## 2. Permutationstest mit infer

Der Permutationstest prüft, ob ein beobachteter Unterschied zwischen zwei Gruppen zufällig entstanden sein könnte, indem die Gruppenzugehörigkeit wiederholt permutiert wird.

```{r}
#| label: obs-diff
obs_diff <- kunden_zufriedenheit %>%
  specify(zufriedenheit ~ gruppe) %>%
  calculate(stat = "diff in means", order = c("A", "B"))

print(obs_diff)
```

```{r}
#| label: null-dist
null_dist <- kunden_zufriedenheit %>%
  specify(zufriedenheit ~ gruppe) %>%
  hypothesize(null = "independence") %>%
  generate(reps = 1000, type = "permute") %>%
  calculate(stat = "diff in means", order = c("A", "B"))

p_value <- null_dist %>%
  get_p_value(obs_stat = obs_diff, direction = "two-sided")

print(paste("p-Wert:", round(p_value$p_value, 4)))
```

Der p-Wert beträgt `r round(p_value$p_value, 4)`. Siehe @fig-permutation für die Null-Verteilung.

```{r}
#| label: fig-permutation
#| fig-cap: "Permutationstest: Null-Verteilung mit beobachteter Differenz"
null_dist %>%
  visualize() +
  shade_p_value(obs_stat = obs_diff, direction = "two-sided") +
  labs(title = "Permutationstest",
       subtitle = paste("p-Wert =", round(p_value$p_value, 4)))
```

## 3. Traditionelle Tests

Klassische parametrische Tests liefern ähnliche Ergebnisse wie Resampling-Methoden, setzen aber Verteilungsannahmen voraus.

### t-Test

```{r}
#| label: t-test
t_result <- t.test(zufriedenheit ~ gruppe, data = kunden_zufriedenheit)
print(t_result)
```

### ANOVA (mehr als 2 Gruppen)

Für die ANOVA erzeugen wir einen Datensatz mit drei Gruppen:

```{r}
#| label: anova-data
drei_gruppen <- tibble(
  wert = c(rnorm(30, 10, 2), rnorm(30, 12, 2), rnorm(30, 11, 2)),
  gruppe = rep(c("A", "B", "C"), each = 30)
)
```

```{r}
#| label: anova
anova_result <- aov(wert ~ gruppe, data = drei_gruppen)
summary(anova_result)

# Post-hoc Test: Welche Gruppen unterscheiden sich?
TukeyHSD(anova_result)
```

### Shapiro-Wilk Test

Der Shapiro-Wilk-Test prüft die Normalverteilungsannahme:

```{r}
#| label: shapiro
shapiro.test(kunden_zufriedenheit$zufriedenheit)
```

## 4. Regression und Inferenz

Die Regressionstabelle enthält nicht nur Punktschätzungen, sondern auch Unsicherheitsmasse für jeden Koeffizienten.

```{r}
#| label: regression-data
set.seed(123)
n <- 100
sales_data <- tibble(
  werbung = runif(n, 1000, 10000),
  preis = rnorm(n, 50, 10),
  umsatz = 5000 + 2.5 * werbung - 100 * preis + rnorm(n, 0, 3000)
)
```

```{r}
#| label: regression-model
model <- lm(umsatz ~ werbung + preis, data = sales_data)
summary(model)
```

```{r}
#| label: tbl-confint
#| tbl-cap: "95%-Konfidenzintervalle der Regressionskoeffizienten"
confint(model, level = 0.95) |> knitr::kable()
```

::: {.callout-note}
## Interpretation der Regressionstabelle

- **Koeffizient (Estimate):** Punktschätzung des Effekts
- **Std. Error:** Unsicherheit der Schätzung
- **t value:** Koeffizient / Std. Error
- **Pr(>|t|):** p-Wert (H₀: Koeffizient = 0)
:::

## 5. Fehler 1. und 2. Art simulieren

Wir simulieren, wie oft ein t-Test fälschlicherweise signifikant wird, wenn in Wahrheit kein Unterschied existiert (Typ-I-Fehler).

```{r}
#| label: type-i-sim
set.seed(42)
n_simulations <- 1000
n_samples <- 50
alpha <- 0.05

type_i_errors <- replicate(n_simulations, {
  gruppe_a <- rnorm(n_samples, mean = 10, sd = 2)
  gruppe_b <- rnorm(n_samples, mean = 10, sd = 2)  # Gleicher Mittelwert!
  p_value <- t.test(gruppe_a, gruppe_b)$p.value
  return(p_value < alpha)
})

type_i_rate <- mean(type_i_errors)
cat("Typ-I-Fehlerrate:", round(type_i_rate, 3), "(erwartet: 0.05)\n")
```

Die beobachtete Typ-I-Fehlerrate liegt bei `r round(type_i_rate, 3)` — nahe am theoretischen Wert von 0.05.

## 6. Multiple Testing und FDR

Wenn viele Tests gleichzeitig durchgeführt werden, steigt die Wahrscheinlichkeit für falsch-positive Ergebnisse. Korrekturen wie Bonferroni und FDR (Benjamini-Hochberg) kontrollieren diese Fehlerrate.

```{r}
#| label: multiple-tests
set.seed(42)
n_tests <- 20
p_values <- replicate(n_tests, {
  x <- rnorm(50)
  y <- rnorm(50)  # Unabhaengig, kein Effekt
  t.test(x, y)$p.value
})

cat("Signifikant ohne Korrektur:", sum(p_values < 0.05), "von", n_tests, "\n")

p_bonferroni <- p.adjust(p_values, method = "bonferroni")
cat("Signifikant mit Bonferroni:", sum(p_bonferroni < 0.05), "\n")

p_fdr <- p.adjust(p_values, method = "BH")
cat("Signifikant mit FDR:", sum(p_fdr < 0.05), "\n")
```

```{r}
#| label: tbl-correction
#| tbl-cap: "Vergleich der p-Werte: Original, Bonferroni und FDR"
data.frame(
  original = round(p_values, 4),
  bonferroni = round(p_bonferroni, 4),
  fdr = round(p_fdr, 4)
) |> knitr::kable()
```

## 7. Effektstärke: Cohen's d

Statistische Signifikanz sagt nichts über die praktische Relevanz eines Effekts. Cohen's d misst die Effektstärke in Einheiten der Standardabweichung.

```{r}
#| label: cohens-d-fn
cohens_d <- function(x, y) {
  n1 <- length(x)
  n2 <- length(y)
  pooled_sd <- sqrt(((n1-1)*sd(x)^2 + (n2-1)*sd(y)^2) / (n1+n2-2))
  d <- (mean(x) - mean(y)) / pooled_sd
  return(d)
}
```

```{r}
#| label: effect-sizes
# Kleiner Effekt
gruppe1 <- rnorm(100, mean = 10, sd = 2)
gruppe2 <- rnorm(100, mean = 10.4, sd = 2)  # 0.2 SD Unterschied
d_small <- cohens_d(gruppe1, gruppe2)
cat("Kleiner Effekt d:", round(d_small, 2), "\n")

# Grosser Effekt
gruppe3 <- rnorm(100, mean = 10, sd = 2)
gruppe4 <- rnorm(100, mean = 11.6, sd = 2)  # 0.8 SD Unterschied
d_large <- cohens_d(gruppe3, gruppe4)
cat("Grosser Effekt d:", round(d_large, 2), "\n")
```

```{r}
#| label: interpret-d
interpret_d <- function(d) {
  d <- abs(d)
  if (d < 0.2) return("vernachlaessigbar")
  if (d < 0.5) return("klein")
  if (d < 0.8) return("mittel")
  return("gross")
}

cat("Interpretation:", interpret_d(d_large), "\n")
```

Faustregel nach Cohen: |d| < 0.2 = vernachlässigbar, 0.2–0.5 = klein, 0.5–0.8 = mittel, > 0.8 = gross.

## 8. Expected Value Berechnung

Der Erwartungswert (Expected Value) hilft bei geschäftlichen Entscheidungen unter Unsicherheit: Lohnt sich eine Investition im Durchschnitt?

```{r}
#| label: expected-value
expected_value <- function(p_success, gain_success, loss_failure) {
  ev <- p_success * gain_success + (1 - p_success) * loss_failure
  return(ev)
}

p_success <- 0.6
gain <- 100000
loss <- -40000

ev <- expected_value(p_success, gain, loss)
cat("Expected Value:", ev, "CHF\n")
```

```{r}
#| label: fig-sensitivity
#| fig-cap: "Sensitivitätsanalyse: Expected Value in Abhängigkeit der Erfolgswahrscheinlichkeit"
probabilities <- seq(0.1, 0.9, by = 0.1)
evs <- sapply(probabilities, function(p) expected_value(p, gain, loss))

plot(probabilities, evs, type = "b", pch = 19,
     xlab = "Erfolgswahrscheinlichkeit",
     ylab = "Expected Value (CHF)",
     main = "Expected Value vs. Erfolgswahrscheinlichkeit")
abline(h = 0, col = "red", lty = 2)
```

```{r}
#| label: breakeven
breakeven <- -loss / (gain - loss)
cat("Break-even bei P(Erfolg) =", round(breakeven, 2), "\n")
```

Der Break-even-Punkt liegt bei einer Erfolgswahrscheinlichkeit von `r round(breakeven, 2)` — ab diesem Wert ist der erwartete Gewinn positiv (siehe @fig-sensitivity).
