---
title: "Extending the package"
author: "Muhammad Yaseen"
date: last-modified
format:
  html:
    self-contained: true
    number-sections: true
    toc: true
    toc-depth: 3
    highlight-style: pygments
    code-tools: true
    html-math-method: mathjax
vignette: >
  %\VignetteIndexEntry{Extending the package}
  %\VignetteEngine{quarto::html}
  %\VignetteEncoding{UTF-8}
execute:
  echo: true
  warning: false
  message: false
---

{{< include _DiallelAnalysisR-macros.txt >}}

```{r setup, include = FALSE}
knitr::opts_chunk$set(collapse = FALSE, comment = "", fig.width = 7, fig.height = 4.2,
                      dev = if (knitr::is_latex_output()) "cairo_pdf" else
                        if (requireNamespace("svglite", quietly = TRUE)) "svglite" else "png")
if (requireNamespace("DiallelAnalysisR", quietly = TRUE)) library(DiallelAnalysisR) else
  pkgload::load_all(export_all = FALSE, helpers = FALSE, quiet = TRUE)
```

# Abstract

How a new analysis is added to DiallelAnalysisR so that it fits the rest of the package: a computational core, an
exported function, a result with methods, a help page, tests and a vignette section.

# The parts of an analysis

1. **Core**: an internal function `.da_<analysis>_core()` that takes the table of cell means (or the plot data) and
   returns the named list of results; no printing, no options.
2. **Exported function**: checks the arguments (`.da_check_data()`, `.da_column()` for column arguments,
   `.da_check_number()` for codes), calls the core, and wraps the result with `.da_result()`, which adds the class
   `c("da_<analysis>", "da_result", "list")`.
3. **Plot**: an internal `.da_plot_<analysis>()`; `plot()` finds it by the class.
4. **Help page**: the model and every formula in LaTeX, every argument, every component of the result, references,
   examples with every argument written out.
5. **Tests**: closed forms against an independent calculation; input errors; methods.
6. **Vignette**: a section or a vignette in this series.

# Building blocks available

```{r blocks}
cd <- DiallelAnalysisR:::.da_cell_data(
    y      = GriffingData1$Yield
  , p1     = GriffingData1$Cross1
  , p2     = GriffingData1$Cross2
  , rep    = GriffingData1$Rep
  , method = 1L
  , fn     = "example"
  )
names(cd)
round(x = cd$M[1:3, 1:3], digits = 2)
cd$anova
```

`.da_cell_data()` gives the table of cell means, the error mean square and its degrees of freedom for any of
Griffing's layouts; a new analysis starts from it.

# Example: heterosis over the mid-parent

The heterosis of `Heterosis()` was built from these blocks. Its first step, by hand:

```{r heterosis}
cd2 <- DiallelAnalysisR:::.da_cell_data(
    y      = GriffingData2$Yield
  , p1     = GriffingData2$Cross1
  , p2     = GriffingData2$Cross2
  , rep    = GriffingData2$Rep
  , method = 2L
  , fn     = "example"
  )
M <- cd2$M
mid <- outer(X = diag(M), Y = diag(M), FUN = "+") / 2
het <- 100 * (M - mid) / mid
diag(het) <- NA
round(x = het[1:4, 1:4], digits = 1)
```

The exported function adds the argument checks, the better-parent and standard heterosis, the $t$ tests with the
standard error of each difference from $MS_E$, a classed result, a plot method, tables for `da_export()` and tests:

```{r heterosis-fn}
h <-
  Heterosis(
      y      = Yield
    , Rep    = Rep
    , Cross1 = Cross1
    , Cross2 = Cross2
    , data   = GriffingData2
    , Check  = NULL
    , Better = c("higher", "lower")[1]
    )
all.equal(target = h$Heterosis$MP[1:3], current = het[1, 2:4], check.attributes = FALSE)
```

# Summary

Every analysis of the package follows the same pattern; a new one reuses the cell-means table, the error mean square,
the result class, the plot theme and the test helpers.
