## What this package does (and why)

*factorH* provides a simple, single-call workflow for multifactor nonparametric, rank-based ANOVA and publication-ready outputs:

- ANOVA-like tables based on ranks
- rank-based effect sizes computed from H
- Dunn-Bonferroni post hoc comparison matrices
- simple-effects post hocs (pairwise comparisons within levels of conditioning factors)
- compact descriptive tables
- one-call diagnostics for factorial plans
- TSV export for quick formatting
- a Jamovi-ready normalization helper for backend integration

Why? Popular GUI stats tools do not offer a ready-made, user-friendly multifactor rank-based pipeline that mirrors standard H / SRH analyses in a way that is easy for beginners. *factorH* aims to fill that gap with clear R-like formula syntax and a one-command report function.

The package is intentionally small: most users will only ever need:

- `srh.kway.full(...)` to compute the full pipeline
- `write.srh.kway.full.tsv(...)` to export the results into a single tab-separated file

Advanced integrations can additionally use:

- `as_jamovi_srh_full(...)` to normalize `srh.kway.full()` output into a stable Jamovi/backend structure

## Formula syntax at a glance

All high-level functions use standard R model formulas:

    response ~ factorA + factorB + factorC

- `+` lists the main effects.
- Interactions are handled internally, so you do not need to write `A:B` or `A*B`.
- The response (left of `~`) must be numeric (e.g., a Likert score coded as 1 to 5 and stored as numeric).

Examples below use the included dataset `mimicry`.

    library(factorH)
    data(mimicry, package = "factorH")
    str(mimicry)

Predictors should be factors. If they are not, the functions will coerce them to factors internally.

**What is allowed?**

    # One factor (KW-style):
    liking ~ condition

    # Two factors (SRH-style):
    liking ~ gender + condition

    # Three or more factors (k-way):
    liking ~ gender + condition + age_cat

You do not need to write `gender:condition` or `gender*condition`. The package constructs the required interaction terms internally when needed.

## Numeric response (Likert note)

The response must be numeric. For Likert-type responses (e.g., 1 = strongly disagree, ..., 5 = strongly agree), keep the variable numeric. Rank-based procedures can be used with such ordinal-like data.

If your Likert variable has been imported as a factor or character, coerce it safely:

    # if stored as character "1", "2", ...:
    mimicry$liking <- as.numeric(mimicry$liking)

    # if stored as factor with labels "1", "2", ...:
    mimicry$liking <- as.numeric(as.character(mimicry$liking))

## Diagnostics at a glance

Most users can cover assumption checks with a single command:

    diag_out <- plan.diagnostics(response ~ factorA + factorB (+ factorC ...), data = your_data)

**What it does:**

1. Raw normality: Shapiro-Wilk in each subgroup and interaction cell of the specified factors.
2. Residual normality per cell: Shapiro-Wilk on residuals from the corresponding full-factorial ANOVA, tested within each cell.
3. Homogeneity of variances: Levene/Brown-Forsythe across full-plan cells (median by default).
4. Count balance: chi-square homogeneity / independence / log-linear independence across factors.
5. It prints a concise overall summary (share of OK and overall status) and returns all detailed tables in `diag_out$results`, with per-type OK percentages in `diag_out$summary`.

For most workflows, this single command is enough to document design diagnostics alongside rank-based analyses.

## The one-call pipeline

The main function `srh.kway.full()` runs:

1. an ANOVA-like table on ranks
2. a descriptive summary
3. post hoc matrices (`Dunn`; adjusted `P.adj`)
4. simple-effects post hocs

It also supports:
- `type = 2` vs `type = 3`
- `scope = "within"` vs `scope = "global"` for simple-effects Bonferroni
- design diagnostics and warnings stored in `res$meta`

For 2 factors:

    res2 <- srh.kway.full(liking ~ gender + condition, data = mimicry)
    names(res2)
    res2$anova
    head(res2$summary)
    names(res2$posthoc_cells)
    names(res2$posthoc_simple)

For 2 factors with Type III SS:

    res2_t3 <- srh.kway.full(liking ~ gender + condition, data = mimicry, type = 3)
    res2_t3$anova

For 3 factors:

    res3 <- srh.kway.full(liking ~ gender + condition + age_cat, data = mimicry)
    res3$anova

For global simple-effects Bonferroni:

    res3g <- srh.kway.full(
      liking ~ gender + condition + age_cat,
      data = mimicry,
      scope = "global"
    )
    names(res3g$posthoc_simple)

## Export full result to a tab-separated file

    f <- file.path(tempdir(), "result.tsv")
    write.srh.kway.full.tsv(res3, file = f, dec = ".")
    file.exists(f)

If you need a decimal comma:

    f2 <- file.path(tempdir(), "result_comma.tsv")
    write.srh.kway.full.tsv(res3, file = f2, dec = ",")
    file.exists(f2)

The TSV contains clearly separated sections:

- `## SRH: EFFECTS TABLE`
- `## SUMMARY STATS`
- `## POSTHOC CELLS`
- `## SIMPLE EFFECTS`
- `## META`

and can be easily opened in spreadsheet software such as Excel or Google Sheets.

## Jamovi/backend helper

If you want to map the full pipeline into a Jamovi module or another structured frontend, use:

    jam <- as_jamovi_srh_full(res3)
    names(jam)

This helper does not build Jamovi result objects directly. Instead, it normalizes the `srh.kway.full()` output into a predictable list of sections and items that can be consumed by a backend.

## What is in the example dataset?

`mimicry` is a real study on the chameleon effect (Trzmielewska et al., 2025) about how movement conditions affect `liking` of an interlocutor. Potential moderators include `gender` and `age` (with dichotomized `age_cat` and a 3-level `age_cat2`). This makes it a natural playground for multifactor rank-based analyses.

    table(mimicry$condition)
    table(mimicry$gender)
    table(mimicry$age_cat)

## What the functions compute (high level)

- `srh.kway()`: rank-based k-way ANOVA table using Type II SS by default, with an optional switch to Type III SS; p-values are tie-corrected; H is reported with and without the correction factor; effect sizes are computed from unadjusted H.
- `srh.effsize()`: 2-factor SRH table with effect sizes (`eta2H`, `eps2H`) computed from H.
- `nonpar.datatable()`: compact descriptive tables with global mean ranks, medians, quartiles, IQR, etc., for all main effects and interactions.
- `srh.posthocs()`: Dunn-Bonferroni pairwise matrices (`P.adj`) for all effects (main effects and interactions).
- `srh.simple.posthoc()` / `srh.simple.posthocs()`: simple-effects pairwise comparisons within levels of conditioning factors (`scope = "within"` by default).
- `srh.kway.full()`: orchestrates all of the above.
- `write.srh.kway.full.tsv()`: exports everything into one TSV (with a dot or comma decimal mark).
- `as_jamovi_srh_full()`: normalizes full-pipeline results for Jamovi/backend integration.
- `plan.diagnostics()`: one-call diagnostics: raw normality, residuals cellwise normality, Levene (median), and balance chi-square; prints an overall summary and returns full tables.

That is it. For most users, the intro ends here: use `srh.kway.full()` and export with `write.srh.kway.full.tsv()`.