---
title: "Analyzing a typical user study"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Analyzing a typical user study}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 7,
  fig.height = 5
)

# The ART section needs ARTool and emmeans (both in Suggests). Guard those
# chunks so the vignette still builds without them.
has_art <- requireNamespace("ARTool", quietly = TRUE) &&
  requireNamespace("emmeans", quietly = TRUE)
```

```{r}
library(colleyRstats)
```

This vignette walks through the workflow `colleyRstats` was built for: a
within-subjects user study, from raw data to the text and figures that go into
the manuscript. Every number in the paper should come out of this script -- no
retyping, no copy-paste drift.

## The study data

Twenty-four participants experienced three interface conditions and rated their
mental demand (0--100, NASA-TLX style) and trust (1--7 Likert) after each. In
your project this data frame comes from your logging or survey export; here we
simulate it.

```{r}
set.seed(42)
n <- 24

main_df <- data.frame(
  Participant = factor(rep(seq_len(n), each = 3)),
  ConditionID = factor(rep(c("Baseline", "HUD", "LED"), times = n))
)

cond_effect <- c(Baseline = 55, HUD = 46, LED = 44)[as.character(main_df$ConditionID)]
main_df$tlx_mental <- pmin(100, pmax(0, round(cond_effect + rnorm(nrow(main_df), sd = 10))))
main_df$trust <- pmin(7, pmax(1, round(3.5 +
  (main_df$ConditionID != "Baseline") * 0.9 + rnorm(nrow(main_df), sd = 1))))
```

Two things matter before any analysis:

- the participant and condition columns must be **factors** (they are above);
- decide up front whether the design is within- or between-subjects -- it
  changes the tests, the plots, and the effect sizes.

## The quick route: one call per dependent variable

`analyze_and_report()` runs the whole per-DV pipeline: it checks the
assumptions (and phrases the justification for the methods section), builds the
matching `ggstatsplot` figure with automatic parametric/non-parametric
selection, reports the omnibus test, and -- for three or more groups -- the
significant post-hoc comparisons.

```{r}
res <- analyze_and_report(
  main_df,
  dv = "tlx_mental", iv = "ConditionID",
  design = "within",
  ylab = "Mental Demand (TLX)"
)
```

The result carries everything separately, so you can place the pieces where
they belong:

```{r}
res$plot
```

```{r}
res$methods  # for the Methods section
res$text     # the omnibus result
res$posthoc  # significant pairwise comparisons (NULL for 2 groups)
```

For a whole questionnaire battery, `report_all()` does this for every scale and
adds a Holm-corrected summary across the dependent variables:

```{r}
battery <- report_all(
  main_df,
  dvs = c("tlx_mental", "trust"),
  iv = "ConditionID",
  design = "within",
  labels = c(tlx_mental = "Mental Demand", trust = "Trust")
)
battery$summary
```

## Step by step, if you prefer control

### 1. Check the assumptions

```{r}
check_normality_by_group(main_df, "ConditionID", "tlx_mental")
```

`assumption_methods_text()` turns the same checks into the sentence reviewers
expect next to the choice of test:

```{r}
assumption_methods_text(main_df, x = "ConditionID", y = "tlx_mental")
```

### 2. Plot with automatic test selection

The `gg*WithPriorNormalityCheck*` wrappers run the normality check and pick the
parametric or non-parametric variant for you. The `Asterisk` versions annotate
significant pairwise comparisons with APA-style stars instead of p-values:

```{r}
plot_within_stats_asterisk(
  data = main_df,
  x = "ConditionID", y = "tlx_mental",
  ylab = "Mental Demand (TLX)",
  xlabels = c("Baseline", "HUD", "LED")
)
```

(Every function also has a snake_case alias -- `plot_within_stats_asterisk()`
is `ggwithinstatsWithPriorNormalityCheckAsterisk()`.)

### 3. Factorial designs: the Aligned Rank Transform

When there is more than one factor and normality is violated, the standard
non-parametric route is the Aligned Rank Transform (ARTool). `reportART()`
turns the ANOVA table into LaTeX sentences, and `reportArtCon()` reports the
pairwise contrasts with rank-biserial effect sizes:

```{r, eval = has_art}
m <- ARTool::art(
  tlx_mental ~ ConditionID + Error(Participant / ConditionID),
  data = main_df
)
reportART(anova(m), dv = "mental demand")
```

```{r, eval = has_art}
ac <- ARTool::art.con(m, ~ ConditionID, adjust = "holm")
reportArtCon(
  ac,
  data = main_df, iv = "ConditionID", dv = "tlx_mental",
  paired = TRUE, id = "Participant"
)
```

### 4. Descriptives

```{r}
reportMeanAndSD(main_df, iv = "ConditionID", dv = "tlx_mental")
```

## Into the manuscript

Every reporter accepts `sink_to = "results/tlx.tex"` to write its sentences to
a file your manuscript can `\input{}` -- re-run the analysis and the paper
updates itself. Figures go through `save_paper_figure()`, which uses
publication presets (ACM-style single-column 3.33 in, full-width 7 in):

```{r}
fig_path <- file.path(tempdir(), "tlx-mental.pdf")
save_paper_figure(res$plot, fig_path, columns = 2)
```

The LaTeX macros used by the reporters (`\F`, `\p`, `\m`, ...) are defined by
`latex_preamble()` or the shipped `colleyRstats.sty`; see
`vignette("overleaf")` for the full R-to-Overleaf pipeline, including
`emit_overleaf()`, which bundles the entire analysis into a folder that
compiles as-is.

## Where to go next

- `vignette("choosing-a-test")` -- how `recommend_test()` picks tests and mixed
  models (GLMM/CLMM) from the data, and how to report them.
- `vignette("overleaf")` -- macros vs. plain LaTeX, `.sty` handling, and the
  one-call Overleaf bundle.
