ANOVA
Structure
(lm() +
anova()) |
Sums of squares |
Sequential (Type I). Four separate lm() fits are used and the required rows are read off each: a main-plot fit for A, B and A×B; a whole-plot fit carrying L, L×A, L×B, L×A×B and Error(a); a fully crossed Y ~ A * B * C * L fit for C and every effect involving C; and a block-first fit whose Residuals row supplies Error(b) |
| Error(a) - main-plot stratum |
The L:Block:A term, fitted last in Y ~ L + Block + L:Block + A + B + A:B + L:A + L:B + L:A:B + L:Block:A. Because Block:A is absent from the model, this term absorbs both Block:A and L:Block:A, giving df = Locations × (Blocks − 1) × (A levels − 1). Tests Block, A, B, A×B, L×A, L×B and L×A×B |
| Error(b) - sub-plot stratum |
The Residuals row of Y ~ Block + L + L:Block + AB + L:AB + L:Block:AB + C + AB:C + L:AB:C, i.e. the L:Block:AB pooling, giving df = Locations × A × B × (Blocks − 1) × (C levels − 1). Tests the Location main effect, C, and every effect involving C |
| Where Location is tested |
Note the asymmetry. The Location main effect is tested against Error(b), while Location's interactions with the main-plot factors (L×A, L×B, L×A×B) are tested against Error(a). The post-hoc comparison for Location is likewise called with DFerror = gl.b, MSerror = Eb, and its Cohen's f uses the Error(b) sum of squares. This is a deliberate choice in the source, matching the pooled split-plot (1,1) module, and must be reproduced to obtain the same p-values |
| Reported sources |
18 rows in fixed order: Block, L, A, B, A×B, L×A, L×B, L×A×B, Error(a), C, A×C, B×C, A×B×C, L×C, L×A×C, L×B×C, L×A×B×C, Error(b) |
Homogeneity
& Pooling
(bartlett.test()) |
Test performed |
Run per character, on a list of per-Location lm models. Two tests are performed: one on the main-plot models (Y ~ Block + FactorA*FactorB, fitted to cell means averaged over FactorC) giving chisq_Ea / pval_Ea, and one on the sub-plot models (Y ~ Block + FactorA*FactorB*FactorC) giving chisq_Eb / pval_Eb |
| Minimum data requirement |
A Location contributes only if it has ≥ 2 levels each of Block, FactorA, FactorB and FactorC and positive residual df in both models. Fewer than 2 valid Locations ⇒ Bartlett's test is reported as NA and no Aitken transformation is applied |
| Trigger for Aitken transformation |
Hardcoded at p ≤ 0.05 - independent of the user's selected significance level α. The transformation fires if either pval_Ea or pval_Eb is significant |
| Aitken transformation applied |
Within each Location, every observation of the affected character is divided by sqrt(MSE_b) for that Location, where MSE_b = sum(resid(m_b)^2) / df.residual(m_b). Note the sub-plot MSE is used as the divisor even when only Error(a) was heterogeneous |
User
Transformation
(optional) |
Default |
Off. Enabled by the "Click for Transformation" toggle; each response variable can then be assigned to at most one of log / square-root / arcsine (the three pickers are mutually exclusive) |
| Log |
log10(x) when all values > 0; otherwise the column is shifted first: log10(x - min(x) + 1) |
| Square root |
sqrt(x) when all values > 0; sqrt(x + 0.5) when any value equals 0; refused with a warning if any value is negative |
| Arcsine |
asin(sqrt(x)), requiring proportions in [0, 1]; exact 0 and 1 are first replaced by 1/(4n) and 1 - 1/(4n) respectively, where n is the number of rows. Refused entirely if any value falls outside [0, 1] |
Reporting of
transformed data |
Table presentation |
ANOVA, CD/HSD and letter grouping are computed on the transformed scale. Result tables show the untransformed mean ± SD first, with the transformed mean in parentheses beneath it |
Multiple
Comparison
(agricolae) |
Procedure |
selectInput(choices = c("LSD","TUKEY","DMRT"), selected = "LSD") ⇒ LSD is the shipped default |
| Significance level α |
Choices are 0.05 and 0.01. The selected = argument is set to a value not present in the choice list, so the control falls back to its first entry - the effective default is 0.05 |
| Error term passed to each test |
Explicitly supplied per effect, never inferred: DFerror = gl.a, MSerror = Ea for A, B, A×B, L×A, L×B and L×A×B; DFerror = gl.b, MSerror = Eb for Location, C, and every effect involving C |
| Critical difference reported |
One CD value per effect, taken from the statistics component of the corresponding agricolae call (column 6 for LSD/DMRT, column 5 for Tukey's HSD). The in-app information modals describe a second, Satterthwaite-approximated CD for mixed-stratum comparisons such as CD[C(A)]; that second value is not computed in this version - the vectors reserved for it are never populated |
| CD suppression |
CD is displayed only when the corresponding ANOVA F-test is significant; otherwise a - is shown |
DMRT
Tables |
Availability |
Produced only when the multiple comparison procedure is DMRT. Under LSD or Tukey the tables are not rendered at all |
| Content |
Two tables per effect, taken from duncan.test()$duncan: column 1 gives the tabulated (studentized range) values and column 2 the critical range values. Row names indicate rank separation between means |
Effect Size
(Cohen's f) |
Formula |
eta_sq = SS_effect / (SS_effect + SS_error), then Cohen's f = sqrt(eta_sq / (1 - eta_sq)) - a partial η² using only the effect's own error stratum in the denominator |
| Error stratum used |
SS of Error(a) (row 9 of the ANOVA table) for the main-plot effects; SS of Error(b) (row 18) for the Location main effect and for every effect involving C - the same split used for the F-tests |
Precision &
Presentation |
Decimal places |
numericInput("split_digit", value = 2, min = 1, max = 4) ⇒ 2 decimal places; applied to every rounded quantity via split_roundvalue |
| Table font |
selected = "cambria" from a 9-font list; affects kableExtra rendering only, not computation |
Principal
Component
Analysis
(prcomp()) |
Input matrix |
Response-variable means per L×A×B×C treatment combination, row-ordered by gtools::mixedorder(). PCA is computed on demand - it is not part of the main analysis run |
| Scaling |
prcomp(center = TRUE, scale = TRUE) ⇒ correlation-matrix PCA via SVD. Scaling is required because response variables are measured on different units and scales; without it a large-variance trait would dominate PC1 purely through its unit of measurement |
| Sign convention |
Both $x and $rotation are multiplied by −1 after fitting. This is a presentation choice only - PC signs are arbitrary in PCA - but it must be reproduced to match the app's loadings and index scores exactly |
| Index scores |
Index 1 = PC1 scores; Index 2 = PC2 scores. Each is reported both raw and rescaled to [0, 1] with scales::rescale(). The index plots classify a treatment combination as Selected above (or below) a user cutoff, default 0.75 |
Correlation &
Normality |
Correlation |
stats::cor(use = "pairwise.complete.obs"), Pearson, rounded to the selected decimal places. The correlation chart uses PerformanceAnalytics::chart.Correlation(histogram = TRUE, pch = 19) |
| Normality (Q-Q panel) |
Optional annotations: Shapiro-Wilk (3 ≤ n ≤ 5000), Anderson-Darling (nortest::ad.test(), n ≥ 7), Kolmogorov-Smirnov against a fitted normal (n ≥ 2). All require non-zero variance; each is skipped with an explanatory label otherwise |