diff --git a/DESCRIPTION b/DESCRIPTION index 9c593636..5680bc2d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: emmeans Type: Package Title: Estimated Marginal Means, aka Least-Squares Means -Version: 2.0.0 -Date: 2025-10-24 +Version: 2.0.1 +Date: 2025-12-10 Authors@R: c(person("Russell V.", "Lenth", role = c("aut", "cph"), email = "russell-lenth@uiowa.edu"), person("Julia", "Piaskowski", role = c("cre", "aut"), diff --git a/NEWS.md b/NEWS.md index 42851158..daff4197 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,21 @@ title: "NEWS for the emmeans package" --- +## emmeans 2.0.1 + + * Fix to `.parse_nest()` to handle nested factors with spaces in their name (#562) + * `col` was not handled properly in `emmip()` (#565) + * In `emmip()`, changed default for `facetlab` to `"label_both"`. This just + seems like a better choice. + * Added a `facetlab` argument to `plot.emmGrid()` -- badly needed when we have + several `by` groups + * Added the `pval.digits` option to specify the desired P-value precision (#567). + It defaults to 4, which was the only precision available in past versions. + * Note that the above change corrects a slight bug in past versions: + a P value smaller than 0.0001 that rounded *up* to 0.0001 was printed as `0.0001` + rather than `<.0001`. + + ## emmeans 2.0.0 We have a new major version number, with a new graphics look and a new maintainer, Julia Piaskowski (however, Russ is still very much involved). diff --git a/R/emmGrid-methods.R b/R/emmGrid-methods.R index d5db8c76..2f4a5b91 100644 --- a/R/emmGrid-methods.R +++ b/R/emmGrid-methods.R @@ -585,6 +585,10 @@ update.emmGrid = function(object, ..., silent = FALSE) { #' displayed is just enough to reasonably distinguish estimates from the ends #' of their confidence intervals; but always at least 3 digits. If #' \code{FALSE}, the system value \code{getOption("digits")} is used.} +#' \item{\code{pval.digits}}{An integer indicating the precision with which +#' p-values are printed. Integers between \code{2} and \code{6} are acceptable; the default is +#' \code{4}. Floating point numbers are truncated. If a number outside the accepted range is +#' used, the nearest acceptable integer will be used instead. Non-numeric arguments are ignored.} #' \item{\code{back.bias.adj}}{A logical value controlling whether we #' try to adjust bias when back-transforming. If \code{FALSE}, we use naive #' back transformation. If \code{TRUE} \emph{and \code{sigma} is available and valid}, a @@ -767,7 +771,8 @@ emm_defaults = list ( estble.tol = 1e-8, # tolerance for estimability checks simplify.names = TRUE, # simplify names like data$x to just "x" back.bias.adj = FALSE, # Try to bias-adjust back-transformations? - opt.digits = TRUE, # optimize displayed digits? + opt.digits = TRUE, # optimize displayed digits for estimates and CI's? + pval.digits = 4L, # how many digits to list for p-values enable.submodel = TRUE, # enable saving extra info for submodel rg.limit = 10000, # limit on number of rows in a reference grid lmer.df = "kenward-roger", # Use Kenward-Roger for df diff --git a/R/emmip.R b/R/emmip.R index 5fccd6e3..a97ec374 100644 --- a/R/emmip.R +++ b/R/emmip.R @@ -137,7 +137,7 @@ emmip = function(object, formula, ...) { #' # Create a black-and-white version of above with different linetypes #' # (Let the linetypes and symbols default to the palette) #' emmip(noise.lm, type ~ side * size, CIs = TRUE, col = "black", -#' linearg = list(), dotarg = list(size = 2), CIarg = list(alpha = 1)) + +#' linearg = list(), dotarg = list(size = 4), CIarg = list(alpha = 1)) + #' ggplot2::theme_bw() #' #' # One interaction plot using combinations of type and side as the trace factor @@ -305,11 +305,11 @@ emmip.default = function(object, formula, type, CIs = FALSE, PIs = FALSE, #' axis, and traces (the different curves), respectively. The \code{emmip} #' function generates these automatically and provides therm via the \code{labs} #' attribute, but the user may override these if desired. -#' @param facetlab Labeller for facets (when by variables are in play). -#' Use \code{"label_value"} to show just the factor levels, or \code{"label_both"} -#' to show both the factor names and factor levels. The default of -#' \code{"label_context"} decides which based on how many \code{by} factors there are. -#' See the documentation for \code{ggplot2::label_context}. +#' @param facetlab Labeller for facets (when by variables are in play). Use +#' \code{"label_value"} to show just the factor levels, or \code{"label_both"} +#' to show both the factor names and factor levels; \code{"label_context"} +#' decides which based on how many \code{by} factors there are. See the +#' documentation for \code{ggplot2::labellers}. #' @param scale If not missing, an object of class \code{scales::trans} specifying #' a (usually) nonlinear scaling for the vertical axis. For example, #' \code{scales = scales::log_trans()} specifies a logarithmic scale. For @@ -361,18 +361,20 @@ emmip.default = function(object, formula, type, CIs = FALSE, PIs = FALSE, #' @importFrom rlang .data emmip_ggplot = function(emms, style = "factor", dodge = .2, xlab = labs$xlab, ylab = labs$ylab, tlab = labs$tlab, - facetlab = "label_context", + facetlab = "label_both", scale, dotarg = list(shape = "circle"), linearg = list(linetype = "solid"), CIarg = list(alpha = .40), PIarg = list(alpha = .25), + col = NULL, ...) { thm = theme_emm() # Depends on gg.theme option labs = attr(emms, "labs") vars = attr(emms, "vars") + ngrps = ifelse(is.null(emms$tvar), 1, length(unique(emms$tvar))) shape.pal = linetype.pal = NULL # we use these to store shape and linetype specs in dotarg and linearg @@ -386,42 +388,35 @@ emmip_ggplot = function(emms, style = "factor", dodge = .2, dotarg$position = pos if(is.null(dotarg$size)) dotarg$size = 3 - if(!is.null(dotarg$shape) && length(dotarg$shape) > 1) { # treat as a shape palette - shape.pal = dotarg$shape - dotarg$shape = NULL - } - - linearg$mapping = ggplot2::aes(group = .data$tvar) - linearg$position = pos - if(is.null(linearg$linewidth)) - linearg$linewidth = 0.8 - if(!is.null(linearg$linetype) && length(linearg$linetype) > 1) { # treat as a linetype palette - linetype.pal = linearg$linetype - linearg$linetype = NULL - } - if (length(vars$tvars) > 0) { - labarg = list(x = xlab, y = ylab, color = tlab) - grobj = ggplot2::ggplot(emms, ggplot2::aes(x = .data$xvar, y = .data$yvar, color = .data$tvar)) - - if(!is.null(dotarg$shape) && length(dotarg$shape) > 1) { - grobj = grobj + ggplot2::aes(shape = .data$tvar) - labarg$shape = tlab + if (ngrps > 1) { + if(!is.null(dotarg$shape) && length(dotarg$shape) > 1) { # treat as a shape palette + shape.pal = dotarg$shape + dotarg$shape = NULL } - if(!is.null(linearg$linetype) && length(linearg$linetype) > 1) { - grobj = grobj + ggplot2::aes(linetype = .data$tvar) - labarg$linetype = tlab + + linearg$mapping = ggplot2::aes(x = as.numeric(.data$xvar), linetype = .data[[tlab]]) + dotarg$mapping = ggplot2::aes(shape = .data[[tlab]]) + + linearg$position = pos + if(is.null(linearg$linewidth)) + linearg$linewidth = 0.8 + if(!is.null(linearg$linetype) && length(linearg$linetype) > 1) { # treat as a linetype palette + linetype.pal = linearg$linetype + linearg$linetype = NULL } - if (style == "factor") + emms[[tlab]] = emms$tvar # make the trace column have same name as its label + + grobj = ggplot2::ggplot(emms, ggplot2::aes(x = .data$xvar, y = .data$yvar, group = .data[[tlab]], + color = .data[[tlab]])) + + if (style == "factor") { grobj = grobj + do.call(ggplot2::geom_point, dotarg) + - do.call(ggplot2::geom_line, linearg) + - do.call(ggplot2::labs, labarg) + ggplot2::scale_x_discrete(expand = ggplot2::expansion(mult = 0.1)) - else - grobj = grobj + - do.call(ggplot2::geom_line, linearg) + - do.call(ggplot2::labs, labarg) + } + grobj = grobj + + do.call(ggplot2::geom_line, linearg) # handle any custom shapes or linetypes if(!is.null(shape.pal)) @@ -430,23 +425,20 @@ emmip_ggplot = function(emms, style = "factor", dodge = .2, grobj = grobj + ggplot2::scale_linetype_manual(values = linetype.pal) } else { # just one trace per plot - if(is.null(linearg$color) && is.null(linearg$colour)) - linearg$color = .emm_palette[1] - if(is.null(dotarg$color) && is.null(dotarg$colour)) - dotarg$color = .emm_palette[1] - if(is.null(CIarg$color) && is.null(CIarg$colour)) - CIarg$color = .emm_palette[1] - if(is.null(PIarg$color) && is.null(PIarg$colour)) - PIarg$color = .emm_palette[1] + if(is.null(col)) + col = .emm_palette[1] + linearg$color = dotarg$color = CIarg$color = PIarg$color = col + col = NULL grobj = ggplot2::ggplot(emms, ggplot2::aes(x = .data$xvar, y = .data$yvar)) if (style == "factor") grobj = grobj + do.call(ggplot2::geom_point, dotarg) + ggplot2::scale_x_discrete(expand = ggplot2::expansion(mult = 0.1)) + linearg$mapping = ggplot2::aes(x = as.numeric(.data$xvar)) grobj = grobj + - do.call(ggplot2::geom_line, linearg) + - ggplot2::labs(x = xlab, y = ylab) + do.call(ggplot2::geom_line, linearg) } + grobj = grobj + ggplot2::labs(x = xlab, y = ylab) if (PIs) { PIarg$mapping = ggplot2::aes(ymin = .data$LPL, ymax = .data$UPL) PIarg$position = pos @@ -478,6 +470,9 @@ emmip_ggplot = function(emms, style = "factor", dodge = .2, if (style == "factor") grobj = grobj + do.call(ggplot2::geom_point, dotarg) + if(!is.null(col)) + grobj = grobj + ggplot2::scale_color_manual(values = rep(col, ngrps)) + grobj + thm } diff --git a/R/nested.R b/R/nested.R index aec92e84..9741eaee 100644 --- a/R/nested.R +++ b/R/nested.R @@ -385,8 +385,9 @@ force_regular = function(object) { spec = trimws(unlist(strsplit(spec, ","))) for (s in spec) { parts = strsplit(s, "[ ]+%in%[ ]+")[[1]] + trm = .all.vars(stats::reformulate(parts[1])) grp = .all.vars(stats::reformulate(parts[2])) - result[[parts[[1]]]] = grp + result[[trm]] = grp } if(length(result) == 0) result = NULL diff --git a/R/plot.emm.R b/R/plot.emm.R index 6fd5a696..682e3d2f 100644 --- a/R/plot.emm.R +++ b/R/plot.emm.R @@ -110,6 +110,12 @@ plot.emmGrid = function(x, y, type, CIs = TRUE, PIs = FALSE, comparisons = FALSE #' plotted horizontally or vertically #' @param xlab Character label for horizontal axis #' @param ylab Character label for vertical axis +#' @param facetlab Character or function method used to label facets in a +#' multi-panel plot (with the \code{ggplot} engine). +#' Default is \code{"label_both"}, meaning that both factor names and levels are shown, +#' You can use \code{"label_value"} to save space, or \code{"label_context"} +#' to decide automatically (often wrongly). See the help page for +#' \code{ggplot2::labellers} #' @param layout Numeric value passed to \code{\link[lattice:xyplot]{dotplot}} #' when \code{engine == "lattice"}. #' @param type Character value specifying the type of prediction desired @@ -215,32 +221,34 @@ plot.emmGrid = function(x, y, type, CIs = TRUE, PIs = FALSE, comparisons = FALSE #' plot(warp.emm, by = NULL, comparisons = TRUE, adjust = "none", #' horizontal = FALSE, colors = "blue") #' -#' ### Using a transformed scale +#' ### Using a transformed scale (also demonstrating 'facetlab' argument) #' pigs.lm <- lm(log(conc + 2) ~ source * factor(percent), data = pigs) #' pigs.emm <- emmeans(pigs.lm, ~ percent | source) -#' plot(pigs.emm, type = "scale", breaks = seq(20, 100, by = 10)) +#' plot(pigs.emm, type = "scale", breaks = seq(20, 100, by = 10), +#' facetlab = "label_value") #' #' # Based on a summary. #' # To get a transformed axis, must specify 'scale'; but it does not necessarily #' # have to be the same as the actual response transformation #' pigs.ci <- confint(pigs.emm, type = "response") -#' plot(pigs.ci, scale = scales::log10_trans()) +#' plot(pigs.ci, scale = scales::log10_trans(), +#' facetlab = \(x) ggplot2::label_both(x, sep = " = ")) plot.summary_emm = function(x, y, horizontal = TRUE, CIs = TRUE, - xlab, ylab, layout, scale = NULL, + xlab, ylab, facetlab = "label_both", layout, scale = NULL, colors, intervals, plotit = TRUE, ...) { if(!missing(intervals)) CIs = intervals if(attr(x, "type") != "response") # disable scale when no response transformation scale = NULL - .plot.srg (x, y, horizontal, xlab, ylab, layout, scale = scale, + .plot.srg (x, y, horizontal, xlab, ylab, facetlab = facetlab, layout, scale = scale, CIs = CIs, colors = colors, plotit = plotit, ...) } # Workhorse for plot.summary_emm #' @importFrom grDevices col2rgb hcl rgb rgb2hsv .plot.srg = function(x, y, - horizontal = TRUE, xlab, ylab, layout, colors, + horizontal = TRUE, xlab, ylab, facetlab = "label_both", layout, colors, engine = get_emm_option("graphics.engine"), CIs = TRUE, PIs = FALSE, extra = NULL, plotit = TRUE, backtran = FALSE, link, scale = NULL, ...) { @@ -582,7 +590,7 @@ plot.summary_emm = function(x, y, horizontal = TRUE, CIs = TRUE, } if (length(byv) > 0) grobj = grobj + ggplot2::facet_grid(as.formula(paste(paste(byv, collapse = "+"), " ~ .")), - labeller = "label_both") + labeller = facetlab) grobj = grobj + ggplot2::geom_point(color = dot.col, size = 4, shape = 18) if(!is.null(scale)) { diff --git a/R/summary.R b/R/summary.R index fe180433..54a63f11 100644 --- a/R/summary.R +++ b/R/summary.R @@ -1354,6 +1354,13 @@ print.summary_emm = function(x, ..., digits=NULL, quote=FALSE, right=TRUE, expor if(!is.null(attr(x, "digits"))) digits = attr(x, "digits") + pval.digits = suppressWarnings(as.integer(get_emm_option("pval.digits")))[1] + if(is.na(pval.digits) || (pval.digits < 2) || (pval.digits > 6)) { + pval.digits = ifelse(is.na(pval.digits), emm_defaults$pval.digits, pval.digits) + pval.digits = max(2, min(6, pval.digits)) + emm_options(pval.digits = pval.digits) + } + test.stat.names = c("t.ratio", "z.ratio", "F.ratio", "T.square") # format these w 3 dec places x.save = x if(export) x.save = list() @@ -1368,8 +1375,10 @@ print.summary_emm = function(x, ..., digits=NULL, quote=FALSE, right=TRUE, expor if(!is.null(x[[nm]])) x[[nm]] = format(round(x[[nm]], 3), nsmall = 3, sci = FALSE) if (!is.null(x$p.value)) { - fp = x$p.value = format(round(x$p.value, 4), nsmall = 4, sci = FALSE) - x$p.value[fp=="0.0000"] = "<.0001" + pval_min = 10^-(pval.digits) + pval_min_display = format(pval_min, nsmall = pval.digits, sci = FALSE) + x$p.value = ifelse(x$p.value < pval_min, paste0("<", pval_min_display), + format(round(x$p.value, pval.digits), nsmall = pval.digits, sci = FALSE)) } est = x[[estn]] diff --git a/maintainer-notes/cheatsheet.R b/maintainer-notes/cheatsheet.R new file mode 100644 index 00000000..696b7959 --- /dev/null +++ b/maintainer-notes/cheatsheet.R @@ -0,0 +1,15 @@ + +# to load all functions into an R session +devtools::load_all() + +# to rebuild documentation: +roxygen2::roxygenise() + +# to run all unit tests +testthat::test_dir("tests/testthat") + +# to build the entire package +devtools::build() + +# required check +devtools::check() \ No newline at end of file diff --git a/maintainer-notes/devel-notes.txt b/maintainer-notes/devel-notes.txt new file mode 100644 index 00000000..0562c8eb --- /dev/null +++ b/maintainer-notes/devel-notes.txt @@ -0,0 +1,5 @@ +## emmeans devel branch + +currently at 2.0.1 + + diff --git a/maintainer-notes/emm-prep-details.md b/maintainer-notes/emm-prep-details.md index 7ee3f033..674c4f36 100644 --- a/maintainer-notes/emm-prep-details.md +++ b/maintainer-notes/emm-prep-details.md @@ -47,12 +47,15 @@ Then check to make sure there are no errors. I always do this in a DOS window (o ``` R CMD check --as-cran emmeans-xxx.tar.gz ``` + Obviously, you need to correct any errors that are found. *Note:* This creates a directory `emmeans.Rcheck/` at the same level as `emmeans/`. Sometimes I get errors if this directory already exists, because my system sometimes thinks I have an open file in there somewhere. So I manually delete that directory before checking. + + ### Doing a thorough check of related packages Installs all reverse dependencies and checks functionality of updated package. @@ -98,6 +101,10 @@ If there is a problem, contact the package developer. These issues need to be re ### build a TarBall +In an R session: +``` +devtools::build() +``` ### Check against R-Devel Go to the [Win-Builder site](https://win-builder.r-project.org/upload.aspx) diff --git a/maintainer-notes/md b/maintainer-notes/md deleted file mode 100644 index e69de29b..00000000 diff --git a/man/emm_options.Rd b/man/emm_options.Rd index 2cf5300f..19b83d1e 100644 --- a/man/emm_options.Rd +++ b/man/emm_options.Rd @@ -8,7 +8,7 @@ \alias{emm_defaults} \title{Set or change emmeans options} \format{ -An object of class \code{list} of length 24. +An object of class \code{list} of length 25. } \usage{ emm_options(..., disable) @@ -121,6 +121,10 @@ object.} displayed is just enough to reasonably distinguish estimates from the ends of their confidence intervals; but always at least 3 digits. If \code{FALSE}, the system value \code{getOption("digits")} is used.} +\item{\code{pval.digits}}{An integer indicating the precision with which + p-values are printed. Integers between \code{2} and \code{6} are acceptable; the default is +\code{4}. Floating point numbers are truncated. If a number outside the accepted range is +used, the nearest acceptable integer will be used instead. Non-numeric arguments are ignored.} \item{\code{back.bias.adj}}{A logical value controlling whether we try to adjust bias when back-transforming. If \code{FALSE}, we use naive back transformation. If \code{TRUE} \emph{and \code{sigma} is available and valid}, a diff --git a/man/emmip.Rd b/man/emmip.Rd index c8f10858..0835c461 100644 --- a/man/emmip.Rd +++ b/man/emmip.Rd @@ -14,9 +14,9 @@ emmip(object, formula, ...) nesting.order = FALSE, ...) emmip_ggplot(emms, style = "factor", dodge = 0.2, xlab = labs$xlab, - ylab = labs$ylab, tlab = labs$tlab, facetlab = "label_context", scale, + ylab = labs$ylab, tlab = labs$tlab, facetlab = "label_both", scale, dotarg = list(shape = "circle"), linearg = list(linetype = "solid"), - CIarg = list(alpha = 0.4), PIarg = list(alpha = 0.25), ...) + CIarg = list(alpha = 0.4), PIarg = list(alpha = 0.25), col = NULL, ...) emmip_lattice(emms, style = "factor", xlab = labs$xlab, ylab = labs$ylab, tlab = labs$tlab, pch = c(1, 2, 6, 7, 9, 10, 15:20), lty = 1, @@ -96,11 +96,11 @@ axis, and traces (the different curves), respectively. The \code{emmip} function generates these automatically and provides therm via the \code{labs} attribute, but the user may override these if desired.} -\item{facetlab}{Labeller for facets (when by variables are in play). -Use \code{"label_value"} to show just the factor levels, or \code{"label_both"} -to show both the factor names and factor levels. The default of -\code{"label_context"} decides which based on how many \code{by} factors there are. -See the documentation for \code{ggplot2::label_context}.} +\item{facetlab}{Labeller for facets (when by variables are in play). Use +\code{"label_value"} to show just the factor levels, or \code{"label_both"} +to show both the factor names and factor levels; \code{"label_context"} +decides which based on how many \code{by} factors there are. See the +documentation for \code{ggplot2::labellers}.} \item{scale}{If not missing, an object of class \code{scales::trans} specifying a (usually) nonlinear scaling for the vertical axis. For example, @@ -122,17 +122,17 @@ it is interpreted as a linetype.} of arguments passed to \code{geom_linerange} to customize appearance of intervals. (Note: the \code{linetype} aesthetic defaults to \code{"solid"} under the hood)} -\item{pch}{(Lattice only) The plotting characters to use for each group (i.e., levels of -\code{trace.factors}). They are recycled as needed.} - -\item{lty}{(Lattice only) The line types to use for each group. Recycled as needed.} - \item{col}{With \code{emmip_ggplot}, this adds \code{color = col} (not \code{colour}) to all of the \code{*arg} lists. This is intended for setting a common color for everything, such as a black-and-white plot. With \code{emmip_lattice}, \code{col} specifies the colors to use for each group, recycled as needed. If not specified, the default trellis colors are used.} + +\item{pch}{(Lattice only) The plotting characters to use for each group (i.e., levels of +\code{trace.factors}). They are recycled as needed.} + +\item{lty}{(Lattice only) The line types to use for each group. Recycled as needed.} } \value{ If \code{plotit = FALSE}, a \code{data.frame} (actually, a @@ -206,7 +206,7 @@ with_emm_options(gg.theme = 1, # Create a black-and-white version of above with different linetypes # (Let the linetypes and symbols default to the palette) emmip(noise.lm, type ~ side * size, CIs = TRUE, col = "black", - linearg = list(), dotarg = list(size = 2), CIarg = list(alpha = 1)) + + linearg = list(), dotarg = list(size = 4), CIarg = list(alpha = 1)) + ggplot2::theme_bw() # One interaction plot using combinations of type and side as the trace factor diff --git a/man/plot.Rd b/man/plot.Rd index 57f054cb..695a40ee 100644 --- a/man/plot.Rd +++ b/man/plot.Rd @@ -10,7 +10,8 @@ int.adjust = "none", intervals, ...) \method{plot}{summary_emm}(x, y, horizontal = TRUE, CIs = TRUE, xlab, ylab, - layout, scale = NULL, colors, intervals, plotit = TRUE, ...) + facetlab = "label_both", layout, scale = NULL, colors, intervals, + plotit = TRUE, ...) } \arguments{ \item{x}{Object of class \code{emmGrid} or \code{summary_emm}} @@ -74,6 +75,13 @@ plotted horizontally or vertically} \item{ylab}{Character label for vertical axis} +\item{facetlab}{Character or function method used to label facets in a +multi-panel plot (with the \code{ggplot} engine). +Default is \code{"label_both"}, meaning that both factor names and levels are shown, +You can use \code{"label_value"} to save space, or \code{"label_context"} +to decide automatically (often wrongly). See the help page for +\code{ggplot2::labellers}} + \item{layout}{Numeric value passed to \code{\link[lattice:xyplot]{dotplot}} when \code{engine == "lattice"}.} @@ -143,14 +151,16 @@ with_emm_options(gg.theme = ggplot2::theme_dark(), plot(warp.emm, by = NULL, comparisons = TRUE, adjust = "none", horizontal = FALSE, colors = "blue") -### Using a transformed scale +### Using a transformed scale (also demonstrating 'facetlab' argument) pigs.lm <- lm(log(conc + 2) ~ source * factor(percent), data = pigs) pigs.emm <- emmeans(pigs.lm, ~ percent | source) -plot(pigs.emm, type = "scale", breaks = seq(20, 100, by = 10)) +plot(pigs.emm, type = "scale", breaks = seq(20, 100, by = 10), + facetlab = "label_value") # Based on a summary. # To get a transformed axis, must specify 'scale'; but it does not necessarily # have to be the same as the actual response transformation pigs.ci <- confint(pigs.emm, type = "response") -plot(pigs.ci, scale = scales::log10_trans()) +plot(pigs.ci, scale = scales::log10_trans(), + facetlab = \(x) ggplot2::label_both(x, sep = " = ")) } diff --git a/tests/testthat/test-utility_functions.R b/tests/testthat/test-utility_functions.R new file mode 100644 index 00000000..be1fc945 --- /dev/null +++ b/tests/testthat/test-utility_functions.R @@ -0,0 +1,23 @@ +context("utility functionality") + +m1 <- lm(breaks ~ wool*tension, data = warpbreaks) +em1 <- emmeans(m1, ~ wool | tension) + +emm_options(pval.digits = 8); invisible(capture.output(joint_tests(em1))) +pdig_1 = get_emm_option("pval.digits") + +emm_options(pval.digits = "eight"); invisible(capture.output(joint_tests(em1))) +pdig_2 = get_emm_option("pval.digits") + +emm_options(pval.digits = 1); invisible(capture.output(joint_tests(em1))) +pdig_3 = get_emm_option("pval.digits") + +emm_options(pval.digits = c(3, 6)); invisible(capture.output(joint_tests(em1))) +pdig_4 = get_emm_option("pval.digits")[1] + +test_that("digits for p-values process", { + expect_equal(pdig_1, 6) + expect_equal(pdig_2, 4) + expect_equal(pdig_3, 2) + expect_equal(pdig_4, 3) +}) \ No newline at end of file