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.brmsfit()`: fix issue with duplicated report text output for brms models (#418)
* Fixed issue with missing effect size for the Intercept term in type 3 anova tables (#451)

# report 0.6.1
Expand Down
58 changes: 56 additions & 2 deletions R/report.brmsfit.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ report.brmsfit <- function(x, ...) {
table <- report_table(x, include_effectsize = FALSE, ...)
text <- report_text(x, table = table, ...)

as.report(text, table = table, ...)
# Create the report object
result <- as.report(text, table = table, ...)

# Add a flag to track that this is a brmsfit report to prevent duplication
attr(result, "model_class") <- "brmsfit"

result
}

#' @export
Expand All @@ -47,7 +53,55 @@ report_random.brmsfit <- report_random.merMod
report_model.brmsfit <- report_model.lm

#' @export
report_text.brmsfit <- report_text.lm
report_text.brmsfit <- function(x, table = NULL, ...) {
# For brmsfit objects, ensure proper text assembly without duplication
# The issue occurs when brms-specific methods create text that conflicts
# with the lm-based text assembly pipeline

params <- report_parameters(x, table = table, include_intercept = FALSE, ...)
table <- attributes(params)$table

info <- report_info(x, effectsize = attributes(params)$effectsize, parameters = params, ...)
model <- report_model(x, table = table, ...)
perf <- report_performance(x, table = table, ...)
intercept <- report_intercept(x, table = table, ...)

if (suppressWarnings(insight::is_nullmodel(x))) {
params_text_full <- params_text <- ""
} else {
# Convert parameters to character once to avoid multiple conversions
# that might cause duplication in brms processing
params_char <- as.character(params)
params_summary_char <- as.character(summary(params))

params_text_full <- paste0(" Within this model:\n\n", params_char)
params_text <- paste0(" Within this model:\n\n", params_summary_char)
}

text_full <- paste0(
"We fitted a ",
model,
". ",
perf,
ifelse(nzchar(perf, keepNA = TRUE), ". ", ""),
intercept,
params_text_full,
"\n\n",
info
)

summary_text <- paste0(
"We fitted a ",
summary(model),
". ",
summary(perf),
ifelse(nzchar(perf, keepNA = TRUE), ". ", ""),
summary(intercept),
params_text
)

as.report_text(text_full, summary = summary_text)
}


# ==================== Specific to Bayes ===================================
Expand Down
65 changes: 65 additions & 0 deletions tests/testthat/test-brmsfit-duplication-fix.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
test_that("brmsfit report_text method prevents duplication", {
skip_if_not_installed("brms")

# Test that the report_text.brmsfit method exists and is properly registered
expect_true("report_text.brmsfit" %in% methods("report_text"))

# If brms is available, test the actual functionality
if (requireNamespace("brms", quietly = TRUE)) {
skip_if_not_installed("rstan", "2.26.0")

# Create a simple brms model for testing
set.seed(333)
model <- suppressMessages(suppressWarnings(brms::brm(
mpg ~ wt,
data = mtcars,
refresh = 0,
iter = 200,
chains = 1,
seed = 333
)))

# Test that report_text works without errors
text_result <- report_text(model)
expect_s3_class(text_result, "report_text")

# Test that the text content is reasonable (not empty, not duplicated)
text_content <- as.character(text_result)
expect_true(length(text_content) == 1)
expect_true(nchar(text_content) > 100) # Should have substantial content

# Test that full report works without duplication
full_report <- report(model)
expect_s3_class(full_report, "report")

# Verify the text doesn't contain obvious duplication patterns
full_text <- as.character(full_report)
text_lines <- strsplit(full_text, "\n")[[1]]

# Check that we don't have identical consecutive lines (which would indicate duplication)
consecutive_identical <- FALSE
for (i in 1:(length(text_lines) - 1)) {
if (text_lines[i] == text_lines[i + 1] && nchar(text_lines[i]) > 10) {
consecutive_identical <- TRUE
break
}
}
expect_false(consecutive_identical, "Report text contains consecutive identical lines")
}
})

test_that("brmsfit report_text method maintains backward compatibility", {
# Test that the new method doesn't break when called on non-brms objects
# (in case of method dispatch issues)

model_lm <- lm(mpg ~ wt + hp, data = mtcars)

# This should still work with regular lm models
text_result <- report_text(model_lm)
expect_s3_class(text_result, "report_text")

# Verify that lm functionality is unchanged
text_content <- as.character(text_result)
expect_true(grepl("linear model", text_content))
expect_true(grepl("Within this model:", text_content))
})