From 36c2f51953114e474c657efa20cfb080353b341a Mon Sep 17 00:00:00 2001 From: Shu Fai Cheung Date: Sat, 2 Nov 2024 15:55:47 +0800 Subject: [PATCH 1/3] 0.3.1: Allow arguments to be passed to autofit Tests, checks, and build_site() passed. --- DESCRIPTION | 4 ++-- NEWS.md | 9 +++++++++ R/as_flextable.cond_indirect_effects.R | 7 +++++-- R/as_flextable.indirect_list.R | 7 +++++-- README.md | 2 +- man/as_flextable.cond_indirect_effects.Rd | 5 ++++- man/as_flextable.indirect_list.Rd | 5 ++++- 7 files changed, 30 insertions(+), 9 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3d5db60..dfe5f5b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: manymome.table Title: Publication-Ready Tables for 'manymome' Results -Version: 0.3.0 +Version: 0.3.1 Authors@R: c(person(given = "Shu Fai", family = "Cheung", @@ -20,7 +20,7 @@ BugReports: https://github.com/sfcheung/manymome.table/issues License: GPL (>= 3) Encoding: UTF-8 Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 Suggests: knitr, rmarkdown, diff --git a/NEWS.md b/NEWS.md index 309dc31..edd9db7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# manymome.table 0.3.1 + +- The optional arguments (`...`) of + `as_flextable.cond_indirect_effects()` + and `as_flextable.indirect_list()` + are now passed to `flextable::autofit()` + when preparing the final output. + (0.3.1) + # manymome.table 0.3.0 - Minor changes to the `README.md` diff --git a/R/as_flextable.cond_indirect_effects.R b/R/as_flextable.cond_indirect_effects.R index ab11488..19edac4 100644 --- a/R/as_flextable.cond_indirect_effects.R +++ b/R/as_flextable.cond_indirect_effects.R @@ -105,7 +105,10 @@ #' #' #' @param ... Additional arguments. -#' Ignored. +#' To be passed to [flextable::autofit()] +#' in preparing the final table. For +#' example, if some lines are too lone +#' and wrapped, try adding `add_w = .2`. #' #' @examples #' @@ -500,6 +503,6 @@ as_flextable.cond_indirect_effects <- function(x, colwidths = flextable::ncol_keys(ft)) } - ft <- flextable::autofit(ft) + ft <- flextable::autofit(ft, ...) ft } diff --git a/R/as_flextable.indirect_list.R b/R/as_flextable.indirect_list.R index 1f9b7f4..17aa5b7 100644 --- a/R/as_flextable.indirect_list.R +++ b/R/as_flextable.indirect_list.R @@ -110,7 +110,10 @@ #' the value of `pcut`. Default is .001. #' #' @param ... Additional arguments. -#' Ignored. +#' To be passed to [flextable::autofit()] +#' in preparing the final table. For +#' example, if some lines are too lone +#' and wrapped, try adding `add_w = .2`. #' #' @examples #' @@ -452,6 +455,6 @@ as_flextable.indirect_list <- function(x, part = "footer") } - ft <- flextable::autofit(ft) + ft <- flextable::autofit(ft, ...) ft } diff --git a/README.md b/README.md index e2d8dbf..d701eed 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![R-CMD-check](https://github.com/sfcheung/manymome.table/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/sfcheung/manymome.table/actions/workflows/R-CMD-check.yaml) -(Version 0.3.0, updated on 2024-03-04, [release history](https://sfcheung.github.io/manymome.table/news/index.html)) +(Version 0.3.1, updated on 2024-11-02, [release history](https://sfcheung.github.io/manymome.table/news/index.html)) # manymome.table diff --git a/man/as_flextable.cond_indirect_effects.Rd b/man/as_flextable.cond_indirect_effects.Rd index 300f63a..174d19b 100644 --- a/man/as_flextable.cond_indirect_effects.Rd +++ b/man/as_flextable.cond_indirect_effects.Rd @@ -113,7 +113,10 @@ Default is \code{TRUE}.} the value of \code{pcut}. Default is .001.} \item{...}{Additional arguments. -Ignored.} +To be passed to \code{\link[flextable:autofit]{flextable::autofit()}} +in preparing the final table. For +example, if some lines are too lone +and wrapped, try adding \code{add_w = .2}.} } \value{ A \code{flextable} object. diff --git a/man/as_flextable.indirect_list.Rd b/man/as_flextable.indirect_list.Rd index 2d1416a..d7ced94 100644 --- a/man/as_flextable.indirect_list.Rd +++ b/man/as_flextable.indirect_list.Rd @@ -120,7 +120,10 @@ to the bottom of the table.} the value of \code{pcut}. Default is .001.} \item{...}{Additional arguments. -Ignored.} +To be passed to \code{\link[flextable:autofit]{flextable::autofit()}} +in preparing the final table. For +example, if some lines are too lone +and wrapped, try adding \code{add_w = .2}.} } \value{ A \code{flextable} object. From 21598f3ba1552c7bde466141eb208996283502bb Mon Sep 17 00:00:00 2001 From: Shu Fai Cheung Date: Sat, 2 Nov 2024 16:13:41 +0800 Subject: [PATCH 2/3] WIP --- inst/tinytest/test_cond_effect.R | 224 +++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 inst/tinytest/test_cond_effect.R diff --git a/inst/tinytest/test_cond_effect.R b/inst/tinytest/test_cond_effect.R new file mode 100644 index 0000000..a5b40b0 --- /dev/null +++ b/inst/tinytest/test_cond_effect.R @@ -0,0 +1,224 @@ +# if (requireNamespace("officer", quietly = TRUE) && +# lengthindirect_effects_from_list(out)(unclass(packageVersion("manymome.table"))[[1]]) == 4) { +if (FALSE) { + +library(tinytest) +library(manymome) +library(officer) +library(flextable) + +dat <- data_med_mod_a +lm_m <- lm(m ~ x*w + c1 + c2, dat) +lm_y <- lm(y ~ m + x + c1 + c2, dat) +fit_lm <- lm2list(lm_m, lm_y) + +out_xm_on_w <- cond_effects(wlevels = "w", + x = "x", + y = "m", + fit = fit_lm) + +full_output <- attr(out_xm_on_w, "full_output") +x_list <- list2indirect_list(full_output) +coef0 <- manymome::indirect_effects_from_list(x_list, + add_sig = FALSE, + pvalue = pvalue, + se = TRUE) + +# tmp1 <- as_flextable(out_xm_on_w, +# var_labels = c(w = "Moderator"), +# se = TRUE, +# pvalue = TRUE, +# digits = 4) +# tmp <- to_html(tmp1) +# expect_equal(ncol_keys(tmp1), 7) +# expect_match(tmp, "[Moderator]") +# expect_match(tmp, "(Moderator)") +# expect_match(tmp, "95% CI") +# expect_match(tmp, "SE") +# expect_match(tmp, formatC(coef(out_xmy_on_w)[1], digits = 3, format = "f")) +# expect_match(tmp, formatC(confint(out_xmy_on_w)[2, 2], digits = 3, format = "f")) + +# tmp1 <- as_flextable(out_xmy_on_w, show_wvalues = FALSE) +# tmp <- to_html(tmp1) +# expect_equal(ncol_keys(tmp1), 5) +# expect_match(tmp, "[w]") +# expect_false(grepl("(w)", tmp, fixed = TRUE)) + +# tmp1 <- as_flextable(std_xmy_on_w) +# tmp <- to_html(tmp1) +# expect_equal(ncol_keys(tmp1), 7) +# expect_match(tmp, "Std. Effect") +# expect_match(tmp, formatC(coef(std_xmy_on_w)[1], digits = 2, format = "f")) +# expect_match(tmp, formatC(coef(out_xmy_on_w)[1], digits = 2, format = "f")) + +# tmp1 <- as_flextable(std_xmy_on_w, indirect_raw = FALSE, pvalue = TRUE, pcut = .10) +# tmp <- to_html(tmp1) +# expect_equal(ncol_keys(tmp1), 7) +# expect_false(grepl(formatC(coef(out_xmy_on_w)[1], digits = 2, format = "f"), tmp, fixed = TRUE)) + +# # From the tests of manymome + +# dat <- modmed_x1m3w4y1 +# n <- nrow(dat) +# set.seed(860314) +# dat$gp <- sample(c("gp1", "gp2", "gp3"), n, replace = TRUE) +# dat$city <- sample(c("alpha", "beta", "gamma", "sigma"), n, replace = TRUE) +# lm_m1 <- lm(m1 ~ x * w1, dat) +# lm_m2 <- lm(m2 ~ m1 + gp + city, dat) +# lm_m3 <- lm(m3 ~ m1 + x * gp, dat) +# lm_y <- lm(y ~ m2 + m3 + x * w4, dat) +# fit <- lm2list(lm_m1, lm_m2, lm_m3, lm_y) + +# # Moderated mediation + +# out_mm_1 <- mod_levels_list("w4", c("gpgp2", "gpgp3"), fit = fit, merge = TRUE) + +# out_1 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit) +# out_2 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, +# standardized_x = TRUE) +# out_3 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, +# standardized_y = TRUE) +# out_4 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, +# standardized_x = TRUE, standardized_y = TRUE) +# out_5 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, +# boot_ci = TRUE, seed = 87415, +# parallel = FALSE, progress = FALSE, +# R = 100) +# out_6 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, +# standardized_x = TRUE, +# boot_ci = TRUE, boot_out = out_5) +# out_7 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, +# standardized_y = TRUE, +# boot_ci = TRUE, boot_out = out_5) +# out_8 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, +# standardized_x = TRUE, standardized_y = TRUE, +# boot_ci = TRUE, boot_out = out_5) + +# # Moderation only + +# outmo_mm_1 <- mod_levels(c("gpgp2", "gpgp3"), fit = fit) + +# outmo_1 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit) +# outmo_2 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, +# standardized_x = TRUE) +# outmo_3 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, +# standardized_y = TRUE) +# outmo_4 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, +# standardized_x = TRUE, standardized_y = TRUE) + +# outmo_5 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, +# boot_ci = TRUE, seed = 87415, +# parallel = FALSE, progress = FALSE, +# R = 100) +# outmo_6 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, +# standardized_x = TRUE, +# boot_ci = TRUE, boot_out = outmo_5) +# outmo_7 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, +# standardized_y = TRUE, +# boot_ci = TRUE, boot_out = outmo_5) +# outmo_8 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, +# standardized_x = TRUE, standardized_y = TRUE, +# boot_ci = TRUE, boot_out = outmo_5) + +# tmp1 <- as_flextable(out_1) +# tmp <- to_html(tmp1) +# expect_equal(ncol_keys(tmp1), 4) +# expect_match(tmp, "[gp]") +# expect_match(tmp, "[gp2]") +# expect_match(tmp, "(w4)") +# expect_false(grepl("gpgp2", tmp, fixed = TRUE)) + +# tmp1 <- as_flextable(out_2) +# tmp <- to_html(tmp1) +# expect_equal(ncol_keys(tmp1), 5) +# expect_match(tmp, "Std. Effect") + +# tmp1 <- as_flextable(out_3) +# tmp <- to_html(tmp1) +# expect_match(tmp, formatC(coef(out_3)[1], digits = 2, format = "f")) +# expect_match(tmp, formatC(coef(out_1)[3], digits = 2, format = "f")) + +# tmp1 <- as_flextable(out_4) +# tmp <- to_html(tmp1) +# expect_match(tmp, formatC(coef(out_4)[1], digits = 2, format = "f")) +# expect_match(tmp, formatC(coef(out_1)[3], digits = 2, format = "f")) + +# tmp1 <- as_flextable(out_5, show_indicators = TRUE) +# tmp <- to_html(tmp1) +# expect_match(tmp, "[gpgp3]") +# expect_match(tmp, formatC(confint(out_5)[3, 2], digits = 2, format = "f")) + +# tmp1 <- as_flextable(out_6, show_wvalues = FALSE) +# tmp <- to_html(tmp1) +# expect_match(tmp, formatC(confint(out_6)[3, 2], digits = 2, format = "f")) +# expect_false(grepl(formatC(confint(out_5)[1, 1], digits = 2, format = "f"), tmp, fixed = TRUE)) + +# tmp1 <- as_flextable(out_7, show_wvalues = FALSE, digits = 4) +# tmp <- to_html(tmp1) +# expect_match(tmp, formatC(confint(out_7)[3, 2], digits = 4, format = "f")) +# expect_match(tmp, formatC(coef(out_5)[2], digits = 4, format = "f")) +# expect_false(grepl("(w4)", tmp, fixed = TRUE)) + +# tmp1 <- as_flextable(out_8, show_wvalues = FALSE, digits = 4, pvalue = TRUE, pval_digits = 5) +# tmp <- to_html(tmp1) +# expect_match(tmp, formatC(confint(out_8)[3, 2], digits = 4, format = "f")) +# tmp2 <- attr(out_8, "full_output") +# class(tmp2) <- c("indirect_list", class(tmp2)) +# tmp3 <- indirect_effects_from_list(tmp2, pvalue = TRUE) +# tmp4 <- formatC(tmp3$pvalue[3], digits = 5, format = "f") +# tmp4 <- gsub("^0.", ".", tmp4) +# expect_match(tmp, tmp4) + + +# tmp1 <- as_flextable(outmo_1, digits = 4) +# tmp <- to_html(tmp1) +# expect_equal(ncol_keys(tmp1), 2) +# expect_match(tmp, "[gp]") +# expect_false(grepl("gpgp2", tmp, fixed = TRUE)) +# expect_match(tmp, formatC(coef(outmo_1)[1], digits = 4, format = "f")) + +# tmp1 <- as_flextable(outmo_2) +# tmp <- to_html(tmp1) +# expect_equal(ncol_keys(tmp1), 3) +# expect_match(tmp, "Std. Effect") +# expect_match(tmp, formatC(coef(outmo_2)[1], digits = 2, format = "f")) +# expect_match(tmp, formatC(coef(outmo_1)[3], digits = 2, format = "f")) + +# tmp1 <- as_flextable(outmo_3) +# tmp <- to_html(tmp1) +# expect_match(tmp, formatC(coef(outmo_3)[1], digits = 2, format = "f")) +# expect_match(tmp, formatC(coef(outmo_1)[3], digits = 2, format = "f")) + +# tmp1 <- as_flextable(outmo_4) +# tmp <- to_html(tmp1) +# expect_match(tmp, formatC(coef(outmo_4)[1], digits = 2, format = "f")) +# expect_match(tmp, formatC(coef(outmo_1)[3], digits = 2, format = "f")) + +# tmp1 <- as_flextable(outmo_5, show_indicators = TRUE) +# tmp <- to_html(tmp1) +# expect_match(tmp, "[gpgp3]") +# expect_match(tmp, formatC(confint(outmo_5)[3, 2], digits = 2, format = "f")) + +# tmp1 <- as_flextable(outmo_6, show_wvalues = FALSE, se = FALSE) +# tmp <- to_html(tmp1) +# expect_match(tmp, formatC(confint(outmo_6)[3, 2], digits = 2, format = "f")) +# expect_false(grepl("S.E.", tmp)) + +# tmp1 <- as_flextable(outmo_7, show_wvalues = FALSE, digits = 4, se = FALSE, pvalue = TRUE) +# tmp <- to_html(tmp1) +# expect_match(tmp, formatC(confint(outmo_7)[3, 2], digits = 4, format = "f")) +# expect_match(tmp, formatC(coef(outmo_5)[2], digits = 4, format = "f")) + +# tmp1 <- as_flextable(outmo_8, show_wvalues = FALSE, digits = 2, pvalue = TRUE, footnote = FALSE, show_path = FALSE, pcut = .400) +# tmp <- to_html(tmp1) +# expect_match(tmp, formatC(confint(outmo_8)[3, 2], digits = 2, format = "f")) +# expect_false(grepl("Path", tmp)) +# expect_false(grepl("Note:", tmp)) +# tmp2 <- attr(outmo_8, "full_output") +# class(tmp2) <- c("indirect_list", class(tmp2)) +# tmp3 <- indirect_effects_from_list(tmp2, pvalue = TRUE) +# tmp4 <- formatC(tmp3$pvalue[3], digits = 3, format = "f") +# tmp4 <- gsub("^0.", ".", tmp4) +# expect_match(tmp, tmp4) + +} From f98c625ff7e4d647c452b38e6fed4807c1d49bf0 Mon Sep 17 00:00:00 2001 From: Shu Fai Cheung Date: Mon, 9 Dec 2024 19:01:55 +0800 Subject: [PATCH 3/3] 0.3.2: Update for SE-based CI and p-value Tests, check, and build_site() passed. --- DESCRIPTION | 2 +- NEWS.md | 7 +- R/as_flextable.cond_indirect_effects.R | 58 +++++- README.md | 2 +- inst/tinytest/test_cond_effect.R | 241 ++++------------------ inst/tinytest/test_cond_ind.R | 5 +- man/as_flextable.cond_indirect_effects.Rd | 10 + 7 files changed, 105 insertions(+), 220 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index dfe5f5b..829306d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: manymome.table Title: Publication-Ready Tables for 'manymome' Results -Version: 0.3.1 +Version: 0.3.2 Authors@R: c(person(given = "Shu Fai", family = "Cheung", diff --git a/NEWS.md b/NEWS.md index edd9db7..05e2c09 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# manymome.table 0.3.1 +# manymome.table 0.3.2 - The optional arguments (`...`) of `as_flextable.cond_indirect_effects()` @@ -7,6 +7,11 @@ when preparing the final output. (0.3.1) +- Updated to print SE-based confidence + intervals and *p*-values when a path + has no mediator and effect not + standardized. (0.3.2) + # manymome.table 0.3.0 - Minor changes to the `README.md` diff --git a/R/as_flextable.cond_indirect_effects.R b/R/as_flextable.cond_indirect_effects.R index 19edac4..011df22 100644 --- a/R/as_flextable.cond_indirect_effects.R +++ b/R/as_flextable.cond_indirect_effects.R @@ -103,6 +103,14 @@ #' `<[pcut]`, `"[pcut]"` replaced by #' the value of `pcut`. Default is .001. #' +#' @param level The level of confidence +#' for the confidence intervals computed +#' from the original standard errors +#' (e.g., the standard errors in +#' [stats::lm()] or `lavaan`). +#' Used only for paths without mediators +#' and both x- and y-variables are not +#' standardized. Default is .95. #' #' @param ... Additional arguments. #' To be passed to [flextable::autofit()] @@ -175,6 +183,7 @@ as_flextable.cond_indirect_effects <- function(x, show_indicators = FALSE, show_path = TRUE, pcut = .001, + level = .95, ...) { # TODO: Remove after an update to manymome indirect_raw_ci <- FALSE @@ -185,15 +194,44 @@ as_flextable.cond_indirect_effects <- function(x, x_i <- full_output[[1]] std_x <- isTRUE(x_i$standardized_x) std_y <- isTRUE(x_i$standardized_y) - - x_list <- list2indirect_list(full_output) - coef0 <- manymome::indirect_effects_from_list(x_list, - add_sig = FALSE, - pvalue = pvalue, - se = se) + # x_list <- list2indirect_list(full_output) + # coef0 <- manymome::indirect_effects_from_list(x_list, + # add_sig = FALSE, + # pvalue = pvalue, + # se = se) + coef0 <- as.data.frame(x, + digits = TRUE, + add_sig = FALSE, + pvalue = pvalue, + pvalue_digits = pval_digits, + se = se, + level = level, + to_string = FALSE) # Fix the column names if (std_x || std_y) { - colnames(coef0)[colnames(coef0) %in% "ind"] <- "std" + coef0 <- coef0[, -which(colnames(coef0) == "ind")] + colnames(coef0)[colnames(coef0) %in% "std"] <- "std" + } + # Remove component path estimates + j <- max(match(c("ind", "std", "CI.lo", "CI.hi", "SE", "pvalue"), + colnames(coef0)), na.rm = TRUE) + if (j < ncol(coef0)) { + coef0 <- coef0[, seq_len(j), drop = FALSE] + } + + # Remove the `Stat` column, for consistency. + # TODO: + # - May keep this column in the future. + j <- match("Stat", colnames(coef0)) + if (!is.na(j)) { + coef0 <- coef0[, -j, drop = FALSE] + } + + # Remove the columns with moderator values. + # Add them using this function, for compatibility. + j <- min(match(c("ind", "std"), colnames(coef0)), na.rm = TRUE) + if (j > 1) { + coef0 <- coef0[, -seq_len(j - 1), drop = FALSE] } x0 <- x_i$x @@ -218,9 +256,10 @@ as_flextable.cond_indirect_effects <- function(x, has_pvalue <- "pvalue" %in% colnames(coef0) has_ci <- "CI.lo" %in% colnames(coef0) has_se <- "SE" %in% colnames(coef0) - if (has_ci) { - level <- x_i$level + if (!is.null(x_i$level)) { + level <- x_i$level + } level_str <- paste0(format(level * 100), "% CI") } else { @@ -292,7 +331,6 @@ as_flextable.cond_indirect_effects <- function(x, w_df <- w_df[, !tmp, drop = FALSE] } coef0 <- cbind(w_df, coef0) - ft <- flextable::flextable(coef0) # Format Cells diff --git a/README.md b/README.md index d701eed..e623354 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![R-CMD-check](https://github.com/sfcheung/manymome.table/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/sfcheung/manymome.table/actions/workflows/R-CMD-check.yaml) -(Version 0.3.1, updated on 2024-11-02, [release history](https://sfcheung.github.io/manymome.table/news/index.html)) +(Version 0.3.2, updated on 2024-12-09, [release history](https://sfcheung.github.io/manymome.table/news/index.html)) # manymome.table diff --git a/inst/tinytest/test_cond_effect.R b/inst/tinytest/test_cond_effect.R index a5b40b0..2048b02 100644 --- a/inst/tinytest/test_cond_effect.R +++ b/inst/tinytest/test_cond_effect.R @@ -1,6 +1,5 @@ -# if (requireNamespace("officer", quietly = TRUE) && -# lengthindirect_effects_from_list(out)(unclass(packageVersion("manymome.table"))[[1]]) == 4) { -if (FALSE) { +if (requireNamespace("officer", quietly = TRUE) && + length(unclass(packageVersion("manymome.table"))[[1]]) == 4) { library(tinytest) library(manymome) @@ -17,208 +16,40 @@ out_xm_on_w <- cond_effects(wlevels = "w", y = "m", fit = fit_lm) -full_output <- attr(out_xm_on_w, "full_output") -x_list <- list2indirect_list(full_output) -coef0 <- manymome::indirect_effects_from_list(x_list, - add_sig = FALSE, - pvalue = pvalue, - se = TRUE) - -# tmp1 <- as_flextable(out_xm_on_w, -# var_labels = c(w = "Moderator"), -# se = TRUE, -# pvalue = TRUE, -# digits = 4) -# tmp <- to_html(tmp1) -# expect_equal(ncol_keys(tmp1), 7) -# expect_match(tmp, "[Moderator]") -# expect_match(tmp, "(Moderator)") -# expect_match(tmp, "95% CI") -# expect_match(tmp, "SE") -# expect_match(tmp, formatC(coef(out_xmy_on_w)[1], digits = 3, format = "f")) -# expect_match(tmp, formatC(confint(out_xmy_on_w)[2, 2], digits = 3, format = "f")) - -# tmp1 <- as_flextable(out_xmy_on_w, show_wvalues = FALSE) -# tmp <- to_html(tmp1) -# expect_equal(ncol_keys(tmp1), 5) -# expect_match(tmp, "[w]") -# expect_false(grepl("(w)", tmp, fixed = TRUE)) - -# tmp1 <- as_flextable(std_xmy_on_w) -# tmp <- to_html(tmp1) -# expect_equal(ncol_keys(tmp1), 7) -# expect_match(tmp, "Std. Effect") -# expect_match(tmp, formatC(coef(std_xmy_on_w)[1], digits = 2, format = "f")) -# expect_match(tmp, formatC(coef(out_xmy_on_w)[1], digits = 2, format = "f")) - -# tmp1 <- as_flextable(std_xmy_on_w, indirect_raw = FALSE, pvalue = TRUE, pcut = .10) -# tmp <- to_html(tmp1) -# expect_equal(ncol_keys(tmp1), 7) -# expect_false(grepl(formatC(coef(out_xmy_on_w)[1], digits = 2, format = "f"), tmp, fixed = TRUE)) - -# # From the tests of manymome - -# dat <- modmed_x1m3w4y1 -# n <- nrow(dat) -# set.seed(860314) -# dat$gp <- sample(c("gp1", "gp2", "gp3"), n, replace = TRUE) -# dat$city <- sample(c("alpha", "beta", "gamma", "sigma"), n, replace = TRUE) -# lm_m1 <- lm(m1 ~ x * w1, dat) -# lm_m2 <- lm(m2 ~ m1 + gp + city, dat) -# lm_m3 <- lm(m3 ~ m1 + x * gp, dat) -# lm_y <- lm(y ~ m2 + m3 + x * w4, dat) -# fit <- lm2list(lm_m1, lm_m2, lm_m3, lm_y) - -# # Moderated mediation - -# out_mm_1 <- mod_levels_list("w4", c("gpgp2", "gpgp3"), fit = fit, merge = TRUE) - -# out_1 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit) -# out_2 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, -# standardized_x = TRUE) -# out_3 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, -# standardized_y = TRUE) -# out_4 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, -# standardized_x = TRUE, standardized_y = TRUE) -# out_5 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, -# boot_ci = TRUE, seed = 87415, -# parallel = FALSE, progress = FALSE, -# R = 100) -# out_6 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, -# standardized_x = TRUE, -# boot_ci = TRUE, boot_out = out_5) -# out_7 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, -# standardized_y = TRUE, -# boot_ci = TRUE, boot_out = out_5) -# out_8 <- cond_indirect_effects(wlevels = out_mm_1, x = "x", y = "y", m = "m3", fit = fit, -# standardized_x = TRUE, standardized_y = TRUE, -# boot_ci = TRUE, boot_out = out_5) - -# # Moderation only - -# outmo_mm_1 <- mod_levels(c("gpgp2", "gpgp3"), fit = fit) - -# outmo_1 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit) -# outmo_2 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, -# standardized_x = TRUE) -# outmo_3 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, -# standardized_y = TRUE) -# outmo_4 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, -# standardized_x = TRUE, standardized_y = TRUE) - -# outmo_5 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, -# boot_ci = TRUE, seed = 87415, -# parallel = FALSE, progress = FALSE, -# R = 100) -# outmo_6 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, -# standardized_x = TRUE, -# boot_ci = TRUE, boot_out = outmo_5) -# outmo_7 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, -# standardized_y = TRUE, -# boot_ci = TRUE, boot_out = outmo_5) -# outmo_8 <- cond_indirect_effects(wlevels = outmo_mm_1, x = "x", y = "m3", fit = fit, -# standardized_x = TRUE, standardized_y = TRUE, -# boot_ci = TRUE, boot_out = outmo_5) - -# tmp1 <- as_flextable(out_1) -# tmp <- to_html(tmp1) -# expect_equal(ncol_keys(tmp1), 4) -# expect_match(tmp, "[gp]") -# expect_match(tmp, "[gp2]") -# expect_match(tmp, "(w4)") -# expect_false(grepl("gpgp2", tmp, fixed = TRUE)) - -# tmp1 <- as_flextable(out_2) -# tmp <- to_html(tmp1) -# expect_equal(ncol_keys(tmp1), 5) -# expect_match(tmp, "Std. Effect") - -# tmp1 <- as_flextable(out_3) -# tmp <- to_html(tmp1) -# expect_match(tmp, formatC(coef(out_3)[1], digits = 2, format = "f")) -# expect_match(tmp, formatC(coef(out_1)[3], digits = 2, format = "f")) - -# tmp1 <- as_flextable(out_4) -# tmp <- to_html(tmp1) -# expect_match(tmp, formatC(coef(out_4)[1], digits = 2, format = "f")) -# expect_match(tmp, formatC(coef(out_1)[3], digits = 2, format = "f")) - -# tmp1 <- as_flextable(out_5, show_indicators = TRUE) -# tmp <- to_html(tmp1) -# expect_match(tmp, "[gpgp3]") -# expect_match(tmp, formatC(confint(out_5)[3, 2], digits = 2, format = "f")) - -# tmp1 <- as_flextable(out_6, show_wvalues = FALSE) -# tmp <- to_html(tmp1) -# expect_match(tmp, formatC(confint(out_6)[3, 2], digits = 2, format = "f")) -# expect_false(grepl(formatC(confint(out_5)[1, 1], digits = 2, format = "f"), tmp, fixed = TRUE)) - -# tmp1 <- as_flextable(out_7, show_wvalues = FALSE, digits = 4) -# tmp <- to_html(tmp1) -# expect_match(tmp, formatC(confint(out_7)[3, 2], digits = 4, format = "f")) -# expect_match(tmp, formatC(coef(out_5)[2], digits = 4, format = "f")) -# expect_false(grepl("(w4)", tmp, fixed = TRUE)) - -# tmp1 <- as_flextable(out_8, show_wvalues = FALSE, digits = 4, pvalue = TRUE, pval_digits = 5) -# tmp <- to_html(tmp1) -# expect_match(tmp, formatC(confint(out_8)[3, 2], digits = 4, format = "f")) -# tmp2 <- attr(out_8, "full_output") -# class(tmp2) <- c("indirect_list", class(tmp2)) -# tmp3 <- indirect_effects_from_list(tmp2, pvalue = TRUE) -# tmp4 <- formatC(tmp3$pvalue[3], digits = 5, format = "f") -# tmp4 <- gsub("^0.", ".", tmp4) -# expect_match(tmp, tmp4) - - -# tmp1 <- as_flextable(outmo_1, digits = 4) -# tmp <- to_html(tmp1) -# expect_equal(ncol_keys(tmp1), 2) -# expect_match(tmp, "[gp]") -# expect_false(grepl("gpgp2", tmp, fixed = TRUE)) -# expect_match(tmp, formatC(coef(outmo_1)[1], digits = 4, format = "f")) - -# tmp1 <- as_flextable(outmo_2) -# tmp <- to_html(tmp1) -# expect_equal(ncol_keys(tmp1), 3) -# expect_match(tmp, "Std. Effect") -# expect_match(tmp, formatC(coef(outmo_2)[1], digits = 2, format = "f")) -# expect_match(tmp, formatC(coef(outmo_1)[3], digits = 2, format = "f")) - -# tmp1 <- as_flextable(outmo_3) -# tmp <- to_html(tmp1) -# expect_match(tmp, formatC(coef(outmo_3)[1], digits = 2, format = "f")) -# expect_match(tmp, formatC(coef(outmo_1)[3], digits = 2, format = "f")) - -# tmp1 <- as_flextable(outmo_4) -# tmp <- to_html(tmp1) -# expect_match(tmp, formatC(coef(outmo_4)[1], digits = 2, format = "f")) -# expect_match(tmp, formatC(coef(outmo_1)[3], digits = 2, format = "f")) - -# tmp1 <- as_flextable(outmo_5, show_indicators = TRUE) -# tmp <- to_html(tmp1) -# expect_match(tmp, "[gpgp3]") -# expect_match(tmp, formatC(confint(outmo_5)[3, 2], digits = 2, format = "f")) - -# tmp1 <- as_flextable(outmo_6, show_wvalues = FALSE, se = FALSE) -# tmp <- to_html(tmp1) -# expect_match(tmp, formatC(confint(outmo_6)[3, 2], digits = 2, format = "f")) -# expect_false(grepl("S.E.", tmp)) - -# tmp1 <- as_flextable(outmo_7, show_wvalues = FALSE, digits = 4, se = FALSE, pvalue = TRUE) -# tmp <- to_html(tmp1) -# expect_match(tmp, formatC(confint(outmo_7)[3, 2], digits = 4, format = "f")) -# expect_match(tmp, formatC(coef(outmo_5)[2], digits = 4, format = "f")) +std_xm_on_w <- cond_effects(wlevels = "w", + x = "x", + y = "m", + standardized_x = TRUE, + fit = fit_lm) -# tmp1 <- as_flextable(outmo_8, show_wvalues = FALSE, digits = 2, pvalue = TRUE, footnote = FALSE, show_path = FALSE, pcut = .400) -# tmp <- to_html(tmp1) -# expect_match(tmp, formatC(confint(outmo_8)[3, 2], digits = 2, format = "f")) -# expect_false(grepl("Path", tmp)) -# expect_false(grepl("Note:", tmp)) -# tmp2 <- attr(outmo_8, "full_output") -# class(tmp2) <- c("indirect_list", class(tmp2)) -# tmp3 <- indirect_effects_from_list(tmp2, pvalue = TRUE) -# tmp4 <- formatC(tmp3$pvalue[3], digits = 3, format = "f") -# tmp4 <- gsub("^0.", ".", tmp4) -# expect_match(tmp, tmp4) +tmp1 <- as_flextable(out_xm_on_w, + var_labels = c(w = "Moderator"), + se = TRUE, + pvalue = TRUE, + digits = 3, + level = .90) + +smp1 <- as_flextable(std_xm_on_w, + var_labels = c(w = "Moderator"), + se = TRUE, + pvalue = TRUE, + digits = 4) + +tmp <- to_html(tmp1) +expect_equal(ncol_keys(tmp1), 7) +expect_match(tmp, "[Moderator]") +expect_match(tmp, "(Moderator)") +expect_match(tmp, "90% CI") +expect_match(tmp, "SE") +expect_match(tmp, formatC(coef(out_xm_on_w)[1], digits = 3, format = "f")) +expect_match(tmp, formatC(confint(out_xm_on_w, level = .90)[2, 2], digits = 3, format = "f")) + +smp <- to_html(smp1) +expect_equal(ncol_keys(smp1), 4) +expect_match(smp, "[Moderator]") +expect_match(smp, "(Moderator)") +expect_false(grepl("90% CI", smp, fixed = TRUE)) +expect_false(grepl("SE", smp, fixed = TRUE)) +expect_match(smp, formatC(coef(std_xm_on_w)[1], digits = 3, format = "f")) } diff --git a/inst/tinytest/test_cond_ind.R b/inst/tinytest/test_cond_ind.R index 2c8397e..73b2a10 100644 --- a/inst/tinytest/test_cond_ind.R +++ b/inst/tinytest/test_cond_ind.R @@ -188,10 +188,11 @@ tmp4 <- formatC(tmp3$pvalue[3], digits = 5, format = "f") tmp4 <- gsub("^0.", ".", tmp4) expect_match(tmp, tmp4) - +# In the latest version of manymome, +# SE-based CI will be included for moderation-only unstandardized paths. tmp1 <- as_flextable(outmo_1, digits = 4) tmp <- to_html(tmp1) -expect_equal(ncol_keys(tmp1), 2) +expect_equal(ncol_keys(tmp1), 5) expect_match(tmp, "[gp]") expect_false(grepl("gpgp2", tmp, fixed = TRUE)) expect_match(tmp, formatC(coef(outmo_1)[1], digits = 4, format = "f")) diff --git a/man/as_flextable.cond_indirect_effects.Rd b/man/as_flextable.cond_indirect_effects.Rd index 174d19b..2810d44 100644 --- a/man/as_flextable.cond_indirect_effects.Rd +++ b/man/as_flextable.cond_indirect_effects.Rd @@ -20,6 +20,7 @@ show_indicators = FALSE, show_path = TRUE, pcut = 0.001, + level = 0.95, ... ) } @@ -112,6 +113,15 @@ Default is \code{TRUE}.} \verb{<[pcut]}, \code{"[pcut]"} replaced by the value of \code{pcut}. Default is .001.} +\item{level}{The level of confidence +for the confidence intervals computed +from the original standard errors +(e.g., the standard errors in +\code{\link[stats:lm]{stats::lm()}} or \code{lavaan}). +Used only for paths without mediators +and both x- and y-variables are not +standardized. Default is .95.} + \item{...}{Additional arguments. To be passed to \code{\link[flextable:autofit]{flextable::autofit()}} in preparing the final table. For