Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: report
Type: Package
Title: Automated Reporting of Results and Statistical Models
Version: 0.6.1.2
Version: 0.6.1.3
Authors@R:
c(person(given = "Dominique",
family = "Makowski",
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Bug fixes

* `report()`: fix failure when reporting Kruskal-Wallis tests with degenerate cases (one observation per group) (#454)
* Fixed issue with missing effect size for the Intercept term in type 3 anova tables (#451)

# report 0.6.1
Expand Down
46 changes: 39 additions & 7 deletions R/report_htest_kruskal.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,29 @@

.report_effectsize_kruskal <- function(x, table, dot_args, rules = "funder2019") {
args <- c(list(x), dot_args)
table <- do.call(effectsize::effectsize, args)

# Try to calculate effect size with confidence intervals
table <- tryCatch(
{
do.call(effectsize::effectsize, args)
},
error = function(e) {
# If CI calculation fails (e.g., degenerate cases), fallback to no CI
if (grepl("confidence intervals", e$message, ignore.case = TRUE) ||
grepl("differing number of rows", e$message)) {
args_no_ci <- c(list(x), dot_args, list(ci = NULL))
do.call(effectsize::effectsize, args_no_ci)
} else if (grepl("Unable to retrieve data", e$message)) {
# Data retrieval failed - this happens with certain htest object forms
# For now, we'll let this error propagate as the user should use the formula interface
# or provide data manually as suggested in the main report.htest function
stop(e)
} else {
stop(e)
}
}
)

ci <- attributes(table)$ci
estimate <- names(table)[1]

Expand All @@ -22,13 +44,23 @@
rules <- .text_effectsize(attr(attr(interpretation, "rules"), "rule_name"))

main <- paste0("Epsilon squared (rank) = ", insight::format_value(table$rank_epsilon_squared))
statistics <- paste0(
main,
", ",
insight::format_ci(table$CI_low, table$CI_high, ci)
)

table <- table[names(table)[-2]]
# Handle cases where CI calculation failed and CI columns are missing
if (all(c("CI_low", "CI_high") %in% names(table))) {
statistics <- paste0(
main,
", ",
insight::format_ci(table$CI_low, table$CI_high, ci)
)
} else {
# No CI available - report only the effect size
statistics <- main
}

# Remove CI_lower column if present (original code logic)
if (ncol(table) > 1) {
table <- table[names(table)[-2]]
}

list(
table = table, statistics = statistics, interpretation = interpretation,
Expand Down
45 changes: 45 additions & 0 deletions tests/testthat/_snaps/windows/report.lmer.new.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# report-lmer

Code
report(m1)
Output
We fitted a linear mixed model (estimated using REML and nloptwrap optimizer)
to predict Reaction with Days (formula: Reaction ~ Days). The model included
Days as random effects (formula: ~1 + Days | Subject). The model's total
explanatory power is substantial (conditional R2 = 0.80) and the part related
to the fixed effects alone (marginal R2) is of 0.28. The model's intercept,
corresponding to Days = 0, is at 251.41 (95% CI [237.94, 264.87], t(174) =
36.84, p < .001). Within this model:

- The effect of Days is statistically significant and positive (beta = 10.47,
95% CI [7.42, 13.52], t(174) = 6.77, p < .001; Std. beta = 0.54, 95% CI [0.38,
0.69])

Standardized parameters were obtained by fitting the model on a standardized
version of the dataset. 95% Confidence Intervals (CIs) and p-values were
computed using a Wald t-distribution approximation.

---

Code
report(m2)
Message
boundary (singular) fit: see help('isSingular')
boundary (singular) fit: see help('isSingular')
Output
We fitted a linear mixed model (estimated using REML and nloptwrap optimizer)
to predict Reaction with Days (formula: Reaction ~ Days). The model included
mysubgrp as random effects (formula: list(~1 | mysubgrp:mygrp, ~1 | mygrp, ~1 |
Subject)). The model's total explanatory power is substantial (conditional R2 =
0.71) and the part related to the fixed effects alone (marginal R2) is of 0.28.
The model's intercept, corresponding to Days = 0, is at 252.09 (95% CI [232.50,
271.69], t(174) = 25.39, p < .001). Within this model:

- The effect of Days is statistically significant and positive (beta = 10.35,
95% CI [8.78, 11.93], t(174) = 12.95, p < .001; Std. beta = 0.53, 95% CI [0.45,
0.61])

Standardized parameters were obtained by fitting the model on a standardized
version of the dataset. 95% Confidence Intervals (CIs) and p-values were
computed using a Wald t-distribution approximation.

20 changes: 20 additions & 0 deletions tests/testthat/test-report.htest-kruskal.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,23 @@ test_that("report.htest-kruskal report", {
report(x, verbose = FALSE)
)
})

test_that("report.htest-kruskal degenerate case (one observation per group)", {
# Test case from issue #454: one observation per group causes CI calculation to fail
n <- 10
set.seed(123)
df <- data.frame(a = as.factor(1:n), b = rnorm(n))
# Use the formula interface to allow effectsize to retrieve data
test <- kruskal.test(b ~ a, data = df)

# Should not fail and should complete quickly - provide data manually
expect_no_error({
result <- report(test, data = df, verbose = FALSE)
})

# Result should contain effect size but no CI due to degenerate case
result <- report(test, data = df, verbose = FALSE)
result_text <- as.character(result)
expect_true(grepl("Epsilon squared \\(rank\\) = 1\\.00", result_text))
expect_false(grepl("95% CI", result_text)) # No CI should be present
})