diff --git a/.Rbuildignore b/.Rbuildignore index caf78a1..5c0a1ba 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -7,3 +7,6 @@ ^appveyor\.yml$ ^docs$ ^\.github$ +^CRAN-RELEASE$ +^revdep$ +^codecov\.yml$ diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index abe7119..ca7bae2 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -10,15 +10,72 @@ name: R-CMD-check jobs: R-CMD-check: - runs-on: macOS-latest + runs-on: ${{ matrix.config.os }} + + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + + strategy: + fail-fast: false + matrix: + config: + - {os: windows-latest, r: 'release'} + - {os: macOS-latest, r: 'release'} + - {os: macOS-latest, r: 'devel'} + - {os: ubuntu-20.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"} + + env: + R_REMOTES_NO_ERRORS_FROM_WARNINGS: true + RSPM: ${{ matrix.config.rspm }} + steps: - uses: actions/checkout@v2 + - uses: r-lib/actions/setup-r@master + with: + r-version: ${{ matrix.config.r }} + + - uses: r-lib/actions/setup-pandoc@master + + - name: Query dependencies + run: | + install.packages('remotes') + install.packages(c("vctrs", "broom")) + saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) + writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") + shell: Rscript {0} + + - name: Cache R packages + if: runner.os != 'Windows' + uses: actions/cache@v1 + with: + path: ${{ env.R_LIBS_USER }} + key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} + restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- + + - name: Install system dependencies + if: runner.os == 'Linux' + env: + RHUB_PLATFORM: linux-x86_64-ubuntu-gcc + run: | + Rscript -e "remotes::install_github('r-hub/sysreqs')" + sysreqs=$(Rscript -e "cat(sysreqs::sysreq_commands('DESCRIPTION'))") + sudo -s eval "$sysreqs" + - name: Install dependencies run: | - install.packages(c("remotes", "rcmdcheck", "vctrs")) remotes::install_deps(dependencies = TRUE) + remotes::install_cran("rcmdcheck") shell: Rscript {0} + - name: Check - run: rcmdcheck::rcmdcheck(args = "--no-manual", error_on = "error") + env: + _R_CHECK_CRAN_INCOMING_REMOTE_: false + run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check") shell: Rscript {0} + + - name: Upload check results + if: failure() + uses: actions/upload-artifact@master + with: + name: ${{ runner.os }}-r${{ matrix.config.r }}-results + path: check diff --git a/.gitignore b/.gitignore index 807ea25..b5e8c48 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .Rproj.user .Rhistory .RData +revdep diff --git a/.travis.yml b/.travis.yml index 0ae990f..4c9b0ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,6 @@ r: - release - devel cache: packages -sudo: false warnings_are_errors: true notifications: @@ -16,3 +15,6 @@ notifications: after_failure: - cat /home/travis/build/NikNakk/forestmodel/forestmodel.Rcheck/00install.out + +after_success: + - Rscript -e 'covr::codecov()' diff --git a/DESCRIPTION b/DESCRIPTION index 4dfc902..981cb17 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,9 +2,12 @@ Package: forestmodel Encoding: UTF-8 Type: Package Title: Forest Plots from Regression Models -Version: 0.6.2 -Date: 2020-07-19 -Author: Nick Kennedy +Version: 0.6.4 +Date: 2022-03-10 +Authors@R: c( + person("Nick", "Kennedy", email = "r@nick-kennedy.com", role = c("aut", "cre")), + person("Shixiang", "Wang", email = "w_shixiang@163.com", role = "aut") + ) Maintainer: Nick Kennedy Description: Produces forest plots using 'ggplot2' from models produced by functions such as stats::lm(), stats::glm() and survival::coxph(). @@ -16,7 +19,11 @@ Imports: dplyr (>= 0.8.0), broom (>= 0.5.0), rlang (>= 0.3.0), tibble (>= 1.4.2) -Suggests: survival, +Suggests: + survival, metafor, - labelled -RoxygenNote: 7.1.0 + labelled, + covr, + testthat, + vdiffr +RoxygenNote: 7.1.2 diff --git a/NEWS b/NEWS index a2737dc..621f3bd 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,12 @@ +forestmodel 0.6.4 (2022-03-10) +------------------------------ +* Add code coverage checks +* Add n_logical_true_only option + +forestmodel 0.6.3 (2020-08-08) +------------------------------ +* Improvements to code by @ShixiangWang to add global p value for a model (fixes #31). + forestmodel 0.6.2 (2020-07-17) ------------------------------ * Improvements to code by @ShixiangWang to use `tibble` rather than `data_frame` (fixes #23). diff --git a/R/default_forest_panels.R b/R/default_forest_panels.R index ab02000..b738066 100644 --- a/R/default_forest_panels.R +++ b/R/default_forest_panels.R @@ -56,6 +56,7 @@ default_forest_panels <- function(model = NULL, factor_separate_line = FALSE, me measure <- "Estimate" } } + is_na <- function(x) sapply(x, is.na) panels <- list( forest_panel(width = 0.03), forest_panel(width = 0.1, display = variable, fontface = "bold", heading = "Variable"), @@ -69,13 +70,13 @@ default_forest_panels <- function(model = NULL, factor_separate_line = FALSE, me forest_panel(width = 0.03, item = "vline", hjust = 0.5), forest_panel( width = 0.12, - display = if_else(reference, "Reference", + display = if_else(reference, if_else(is_na(p.value), "Reference", "Reference; Variable logrank:"), sprintf("%0.2f (%0.2f, %0.2f)", trans(estimate), trans(conf.low), trans(conf.high)) ), display_na = NA ), forest_panel( - width = 0.05, display = if_else(reference, "", format.pval(p.value, digits = 1, eps = 1e-3)), display_na = NA, + width = 0.05, display = if_else(reference & is_na(p.value), "", format.pval(p.value, digits = 1, eps = 1e-3)), display_na = NA, hjust = 1, heading = "p" ), forest_panel(width = 0.03) diff --git a/R/forest_model.R b/R/forest_model.R index 38538d8..a1be244 100644 --- a/R/forest_model.R +++ b/R/forest_model.R @@ -24,6 +24,12 @@ #' @param exclude_infinite_cis whether to exclude points and confidence intervals #' that go to positive or negative infinity from plotting. They will still be #' displayed as text. Defaults to \code{TRUE}, since otherwise plot is malformed +#' @param show_global_p Show model global p value, only works for Cox model. +#' - 'none', don't show. +#' - 'bottom', show global p value in the bottom. +#' - 'aside', show global p value along with 'Reference', this is useful when you plot a list of models. +#' @param n_logical_true_only whether to only count TRUE values in n for logical +#' covariates #' #' @return A ggplot ready for display or saving, or (with \code{return_data == TRUE}, #' a \code{list} with the parameters to call \code{\link{panel_forest_plot}} in the @@ -61,8 +67,8 @@ #' #' @examples #' -#' library("survival") -#' library("dplyr") +#' library(survival) +#' library(dplyr) #' pretty_lung <- lung %>% #' transmute(time, #' status, @@ -128,7 +134,10 @@ forest_model <- function(model, theme = theme_forest(), limits = NULL, breaks = NULL, return_data = FALSE, recalculate_width = TRUE, recalculate_height = TRUE, - model_list = NULL, merge_models = FALSE, exclude_infinite_cis = TRUE) { + model_list = NULL, merge_models = FALSE, exclude_infinite_cis = TRUE, + show_global_p = c("none", "bottom", "aside"), + n_logical_true_only = FALSE) { + show_global_p <- match.arg(show_global_p) mapping <- aes(estimate, xmin = conf.low, xmax = conf.high) if (!is.null(model_list)) { if (!is.list(model_list)) { @@ -209,6 +218,7 @@ forest_model <- function(model, level = names(tab), level_no = 1:length(tab), n = as.integer(tab), + total = sum(as.integer(tab)), stringsAsFactors = FALSE ) if (factor_separate_line) { @@ -233,10 +243,14 @@ forest_model <- function(model, } else { out <- data.frame(term_row, level = NA, level_no = NA, n = sum(!is.na(data[, var])), + total = sum(!is.na(data[, var])), stringsAsFactors = FALSE ) if (term_row$class == "logical") { out$term_label <- paste0(term_row$term_label, "TRUE") + if (n_logical_true_only) { + out$n <- sum(data[, var], na.rm = TRUE) + } } } } else { @@ -270,6 +284,22 @@ forest_model <- function(model, forest_terms <- filter(forest_terms, term_label %in% covariates) } + if (show_global_p != "none") { + if (inherits(model, "coxph")) { + p_val <- as.numeric(summary(model)$sctest[3]) + if (show_global_p == "bottom") { + label <- paste("Global p", format.pval(p_val, digits = 1, eps = 1e-3)) + forest_terms <- forest_terms %>% + dplyr::add_row(term_label = "Global p", variable = label) + } else if (show_global_p == "aside") { + if (length(unique(forest_terms$term_label)) > 1) { + warning("It is not recommended to show global p value aside 'reference' if there is more than 1 variable.\nThey share the same p value.", immediate. = TRUE) + } + forest_terms$p.value[forest_terms$reference] <- p_val + } + } + } + forest_terms } diff --git a/R/rma_setlab.R b/R/rma_setlab.R index 7d724f1..78ab85c 100644 --- a/R/rma_setlab.R +++ b/R/rma_setlab.R @@ -9,382 +9,417 @@ # @param gentype type of outcome # # @return name of estimate -rma_setlab <- function(measure, transf.char, atransf.char, gentype) { +rma_setlab <- function(measure, transf.char, atransf.char, gentype, short=FALSE) { if (gentype == 1) { lab <- "Observed Outcome" } if (gentype == 2) { - lab <- "Overall Estimate" + lab <- "Overall Estimate" # for forest.cumul.rma() function } + if (gentype == 3) { + lab <- "Estimate" # for header + } + + if (!is.null(measure)) { - if (measure == "RR") { + + if (is.element(measure, c("RR","MPRR"))) { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Log Relative Risk" - } - else { - lab <- "Transformed Log Relative Risk" - if (atransf.char == "exp" || atransf.char == - "transf.exp.int") { - lab <- "Relative Risk (log scale)" - } - if (transf.char == "exp" || transf.char == "transf.exp.int") { - lab <- "Relative Risk" - } + lab <- ifelse(short, "Log[RR]", "Log Risk Ratio") + } else { + lab <- ifelse(short, lab, "Transformed Log Risk Ratio") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "Risk Ratio", "Risk Ratio (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "Risk Ratio", "Risk Ratio") } } - if (is.element(measure, c( - "OR", "PETO", "D2OR", "D2ORN", - "D2ORL" - ))) { + if (is.element(measure, c("OR","PETO","D2OR","D2ORN","D2ORL","MPOR","MPORC","MPPETO"))) { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Log Odds Ratio" - } - else { - lab <- "Transformed Log Odds Ratio" - if (atransf.char == "exp" || atransf.char == - "transf.exp.int") { - lab <- "Odds Ratio (log scale)" - } - if (transf.char == "exp" || transf.char == "transf.exp.int") { - lab <- "Odds Ratio" - } + lab <- ifelse(short, "Log[OR]", "Log Odds Ratio") + } else { + lab <- ifelse(short, lab, "Transformed Log Odds Ratio") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "Odds Ratio", "Odds Ratio (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "Odds Ratio", "Odds Ratio") } } - if (measure == "RD") { + if (is.element(measure, c("RD","MPRD"))) { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Risk Difference" - } - else { - lab <- "Transformed Risk Difference" + lab <- ifelse(short, "Risk Difference", "Risk Difference") + } else { + lab <- ifelse(short, lab, "Transformed Risk Difference") } } if (measure == "AS") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Arcsine Transformed Risk Difference" - } - else { - lab <- "Transformed Arcsine Transformed Risk Difference" + lab <- ifelse(short, "Arcsine RD", "Arcsine Transformed Risk Difference") + } else { + lab <- ifelse(short, lab, "Transformed Arcsine Transformed Risk Difference") } } if (measure == "PHI") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Phi Coefficient" - } - else { - lab <- "Transformed Phi Coefficient" + lab <- ifelse(short, "Phi", "Phi Coefficient") + } else { + lab <- ifelse(short, lab, "Transformed Phi Coefficient") } } if (measure == "YUQ") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Yule's Q" - } - else { - lab <- "Transformed Yule's Q" + lab <- ifelse(short, "Yule's Q", "Yule's Q") + } else { + lab <- ifelse(short, lab, "Transformed Yule's Q") } } if (measure == "YUY") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Yule's Y" - } - else { - lab <- "Transformed Yule's Y" + lab <- ifelse(short, "Yule's Y", "Yule's Y") + } else { + lab <- ifelse(short, lab, "Transformed Yule's Y") } } + if (measure == "IRR") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Log Incidence Rate Ratio" - } - else { - lab <- "Transformed Log Incidence Relative Risk" - if (atransf.char == "exp" || atransf.char == - "transf.exp.int") { - lab <- "Incidence Rate Ratio (log scale)" - } - if (transf.char == "exp" || transf.char == "transf.exp.int") { - lab <- "Incidence Rate Ratio" - } + lab <- ifelse(short, "Log[IRR]", "Log Incidence Rate Ratio") + } else { + lab <- ifelse(short, lab, "Transformed Log Incidence Rate Ratio") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "Rate Ratio", "Incidence Rate Ratio (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "Rate Ratio", "Incidence Rate Ratio") } } if (measure == "IRD") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Incidence Rate Difference" - } - else { - lab <- "Transformed Incidence Rate Difference" + lab <- ifelse(short, "IRD", "Incidence Rate Difference") + } else { + lab <- ifelse(short, lab, "Transformed Incidence Rate Difference") } } if (measure == "IRSD") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Square-Root Transformed Incidence Rate Difference" - } - else { - lab <- "Transformed Square-Root Transformed Incidence Rate Difference" + lab <- ifelse(short, "IRSD", "Square Root Transformed Incidence Rate Difference") + } else { + lab <- ifelse(short, lab, "Transformed Square Root Transformed Incidence Rate Difference") } } + if (measure == "MD") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Mean Difference" - } - else { - lab <- "Transformed Mean Difference" + lab <- ifelse(short, "MD", "Mean Difference") + } else { + lab <- ifelse(short, lab, "Transformed Mean Difference") } } - if (is.element(measure, c( - "SMD", "SMDH", "PBIT", "OR2D", - "OR2DN", "OR2DL" - ))) { + if (is.element(measure, c("SMD","SMDH","PBIT","OR2D","OR2DN","OR2DL","SMD1"))) { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Standardized Mean Difference" - } - else { - lab <- "Transformed Standardized Mean Difference" + lab <- ifelse(short, "SMD", "Standardized Mean Difference") + } else { + lab <- ifelse(short, lab, "Transformed Standardized Mean Difference") } } if (measure == "ROM") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Log Ratio of Means" - } - else { - lab <- "Transformed Log Ratio of Means" - if (atransf.char == "exp" || atransf.char == - "transf.exp.int") { - lab <- "Ratio of Means (log scale)" - } - if (transf.char == "exp" || transf.char == "transf.exp.int") { - lab <- "Ratio of Means" - } + lab <- ifelse(short, "Log[RoM]", "Log Ratio of Means") + } else { + lab <- ifelse(short, lab, "Transformed Log Ratio of Means") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "Ratio of Means", "Ratio of Means (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "Ratio of Means", "Ratio of Means") } } if (measure == "RPB") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Point-Biserial Correlation" + lab <- ifelse(short, "Correlation", "Point-Biserial Correlation") + } else { + lab <- ifelse(short, lab, "Transformed Point-Biserial Correlation") } - else { - lab <- "Transformed Point-Biserial Correlation" + } + if (measure == "CVR") { + if (transf.char == "FALSE" && atransf.char == "FALSE") { + lab <- ifelse(short, "Log[CVR]", "Log Coefficient of Variation Ratio") + } else { + lab <- ifelse(short, lab, "Transformed Log Coefficient of Variation Ratio") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "CVR", "Coefficient of Variation Ratio (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "CVR", "Coefficient of Variation Ratio") } } - if (is.element(measure, c("COR", "UCOR", "RTET", "RBIS"))) { + if (measure == "VR") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Correlation Coefficient" + lab <- ifelse(short, "Log[VR]", "Log Variability Ratio") + } else { + lab <- ifelse(short, lab, "Transformed Log Variability Ratio") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "VR", "Variability Ratio (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "VR", "Variability Ratio") } - else { - lab <- "Transformed Correlation Coefficient" + } + + if (is.element(measure, c("COR","UCOR","RTET","RBIS"))) { + if (transf.char == "FALSE" && atransf.char == "FALSE") { + lab <- ifelse(short, "Correlation", "Correlation Coefficient") + } else { + lab <- ifelse(short, lab, "Transformed Correlation Coefficient") } } if (measure == "ZCOR") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Fisher's z Transformed Correlation Coefficient" + lab <- ifelse(short, expression('Fisher\'s ' * z[r]), "Fisher's z Transformed Correlation Coefficient") + } else { + lab <- ifelse(short, lab, "Transformed Fisher's z Transformed Correlation Coefficient") + if (atransf.char == "transf.ztor" || atransf.char == "transf.ztor.int") + lab <- ifelse(short, "Correlation", "Correlation Coefficient") + if (transf.char == "transf.ztor" || transf.char == "transf.ztor.int") + lab <- ifelse(short, "Correlation", "Correlation Coefficient") } - else { - lab <- "Transformed Fisher's z Transformed Correlation Coefficient" - if (atransf.char == "transf.ztor" || atransf.char == - "transf.ztor.int") { - lab <- "Correlation Coefficient" - } - if (transf.char == "transf.ztor" || transf.char == - "transf.ztor.int") { - lab <- "Correlation Coefficient" - } + } + + if (measure == "PCOR") { + if (transf.char == "FALSE" && atransf.char == "FALSE") { + lab <- ifelse(short, "Correlation", "Partial Correlation Coefficient") + } else { + lab <- ifelse(short, lab, "Transformed Partial Correlation Coefficient") } } - if (measure == "PR") { + if (measure == "ZPCOR") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Proportion" + lab <- ifelse(short, expression('Fisher\'s ' * z[r]), "Fisher's z Transformed Partial Correlation Coefficient") + } else { + lab <- ifelse(short, lab, "Transformed Fisher's z Transformed Partial Correlation Coefficient") + if (atransf.char == "transf.ztor" || atransf.char == "transf.ztor.int") + lab <- ifelse(short, "Correlation", "Partial Correlation Coefficient") + if (transf.char == "transf.ztor" || transf.char == "transf.ztor.int") + lab <- ifelse(short, "Correlation", "Partial Correlation Coefficient") } - else { - lab <- "Transformed Proportion" + } + if (measure == "SPCOR") { + if (transf.char == "FALSE" && atransf.char == "FALSE") { + lab <- ifelse(short, "Correlation", "Semi-Partial Correlation Coefficient") + } else { + lab <- ifelse(short, lab, "Transformed Semi-Partial Correlation Coefficient") } } - if (measure == "PLN") { + + if (measure == "PR") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Log Proportion" + lab <- ifelse(short, "Proportion", "Proportion") + } else { + lab <- ifelse(short, lab, "Transformed Proportion") } - else { - lab <- "Transformed Log Proportion" - if (atransf.char == "exp" || atransf.char == - "transf.exp.int") { - lab <- "Proportion (log scale)" - } - if (transf.char == "exp" || transf.char == "transf.exp.int") { - lab <- "Proportion" - } + } + if (measure == "PLN") { + if (transf.char == "FALSE" && atransf.char == "FALSE") { + lab <- ifelse(short, "Log[Pr]", "Log Proportion") + } else { + lab <- ifelse(short, lab, "Transformed Log Proportion") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "Proportion", "Proportion (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "Proportion", "Proportion") } } if (measure == "PLO") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Log Odds" - } - else { - lab <- "Transformed Log Odds" - if (atransf.char == "transf.ilogit" || atransf.char == - "transf.ilogit.int" || atransf.char == "plogis") { - lab <- "Proportion (logit scale)" - } - if (transf.char == "transf.ilogit" || transf.char == - "transf.ilogit.int" || transf.char == "plogis") { - lab <- "Proportion" - } - if (atransf.char == "exp" || atransf.char == - "transf.exp.int") { - lab <- "Odds (log scale)" - } - if (transf.char == "exp" || transf.char == "transf.exp.int") { - lab <- "Odds" - } + lab <- ifelse(short, "Log[Odds]", "Log Odds") + } else { + lab <- ifelse(short, lab, "Transformed Log Odds") + if (atransf.char == "transf.ilogit" || atransf.char == "transf.ilogit.int" || atransf.char == "plogis") + lab <- ifelse(short, "Proportion", "Proportion (logit scale)") + if (transf.char == "transf.ilogit" || transf.char == "transf.ilogit.int" || transf.char == "plogis") + lab <- ifelse(short, "Proportion", "Proportion") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "Odds", "Odds (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "Odds", "Odds") } } if (measure == "PAS") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Arcsine Transformed Proportion" - } - else { - lab <- "Transformed Arcsine Transformed Proportion" - if (atransf.char == "transf.iarcsin" || atransf.char == - "transf.iarcsin.int") { - lab <- "Proportion (arcsine scale)" - } - if (transf.char == "transf.iarcsin" || transf.char == - "transf.iarcsin.int") { - lab <- "Proportion" - } + lab <- ifelse(short, expression(arcsin(sqrt(p))), "Arcsine Transformed Proportion") + } else { + lab <- ifelse(short, lab, "Transformed Arcsine Transformed Proportion") + if (atransf.char == "transf.iarcsin" || atransf.char == "transf.iarcsin.int") + lab <- ifelse(short, "Proportion", "Proportion (arcsine scale)") + if (transf.char == "transf.iarcsin" || transf.char == "transf.iarcsin.int") + lab <- ifelse(short, "Proportion", "Proportion") } } if (measure == "PFT") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Double Arcsine Transformed Proportion" - } - else { - lab <- "Transformed Double Arcsine Transformed Proportion" - if (atransf.char == "transf.ift.hm") { - lab <- "Proportion" - } - if (transf.char == "transf.ift.hm") { - lab <- "Proportion" - } + lab <- ifelse(short, "PFT", "Double Arcsine Transformed Proportion") + } else { + lab <- ifelse(short, lab, "Transformed Double Arcsine Transformed Proportion") + if (atransf.char == "transf.ipft.hm") + lab <- ifelse(short, "Proportion", "Proportion") + if (transf.char == "transf.ipft.hm") + lab <- ifelse(short, "Proportion", "Proportion") } } + if (measure == "IR") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Incidence Rate" - } - else { - lab <- "Transformed Incidence Rate" + lab <- ifelse(short, "Rate", "Incidence Rate") + } else { + lab <- ifelse(short, lab, "Transformed Incidence Rate") } } if (measure == "IRLN") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Log Incidence Rate" - } - else { - lab <- "Transformed Log Incidence Rate" - if (atransf.char == "exp" || atransf.char == - "transf.exp.int") { - lab <- "Incidence Rate (log scale)" - } - if (transf.char == "exp" || transf.char == "transf.exp.int") { - lab <- "Incidence Rate" - } + lab <- ifelse(short, "Log[IR]", "Log Incidence Rate") + } else { + lab <- ifelse(short, lab, "Transformed Log Incidence Rate") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "Rate", "Incidence Rate (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "Rate", "Incidence Rate") } } if (measure == "IRS") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Square-Root Transformed Incidence Rate" - } - else { - lab <- "Transformed Square-Root Transformed Incidence Rate" - if (atransf.char == "transf.isqrt" || atransf.char == - "transf.isqrt.int") { - lab <- "Incidence Rate (square-root scale)" - } - if (transf.char == "transf.isqrt" || transf.char == - "transf.isqrt.int") { - lab <- "Incidence Rate" - } + lab <- ifelse(short, "Sqrt[IR]", "Square Root Transformed Incidence Rate") + } else { + lab <- ifelse(short, lab, "Transformed Square Root Transformed Incidence Rate") + if (atransf.char == "transf.isqrt" || atransf.char == "transf.isqrt.int") + lab <- ifelse(short, "Rate", "Incidence Rate (square root scale)") + if (transf.char == "transf.isqrt" || transf.char == "transf.isqrt.int") + lab <- ifelse(short, "Rate", "Incidence Rate") } } if (measure == "IRFT") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Freeman-Tukey Transformed Incidence Rate" - } - else { - lab <- "Transformed Freeman-Tukey Transformed Incidence Rate" + lab <- ifelse(short, "IRFT", "Freeman-Tukey Transformed Incidence Rate") + } else { + lab <- ifelse(short, lab, "Transformed Freeman-Tukey Transformed Incidence Rate") } } + if (measure == "MN") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Mean" + lab <- ifelse(short, "Mean", "Mean") + } else { + lab <- ifelse(short, lab, "Transformed Mean") } - else { - lab <- "Transformed Mean" + } + if (measure == "MNLN") { + if (transf.char == "FALSE" && atransf.char == "FALSE") { + lab <- ifelse(short, "Log[Mean]", "Log Mean") + } else { + lab <- ifelse(short, lab, "Transformed Log Mean") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "Mean", "Mean (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "Mean", "Mean") } } - if (measure == "MC") { + if (measure == "CVLN") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Mean Change" + lab <- ifelse(short, "Log[CV]", "Log Coefficient of Variation") + } else { + lab <- ifelse(short, lab, "Transformed Log Coefficient of Variation") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "CV", "Coefficient of Variation (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "CV", "Coefficient of Variation") } - else { - lab <- "Transformed Mean Change" + } + if (measure == "SDLN") { + if (transf.char == "FALSE" && atransf.char == "FALSE") { + lab <- ifelse(short, "Log[SD]", "Log Standard Deviation") + } else { + lab <- ifelse(short, lab, "Transformed Log Standard Deviation") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "SD", "Standard Deviation (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "SD", "Standard Deviation") } } - if (is.element(measure, c("SMCC", "SMCR", "SMCRH"))) { + + if (measure == "MC") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Standardized Mean Change" + lab <- ifelse(short, "Mean Change", "Mean Change") + } else { + lab <- ifelse(short, lab, "Transformed Mean Change") } - else { - lab <- "Transformed Standardized Mean Change" + } + if (is.element(measure, c("SMCC","SMCR","SMCRH"))) { + if (transf.char == "FALSE" && atransf.char == "FALSE") { + lab <- ifelse(short, "SMC", "Standardized Mean Change") + } else { + lab <- ifelse(short, lab, "Transformed Standardized Mean Change") } } if (measure == "ROMC") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Log Ratio of Means" + lab <- ifelse(short, "Log[RoM]", "Log Ratio of Means") + } else { + lab <- ifelse(short, lab, "Transformed Log Ratio of Means") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "Ratio of Means", "Ratio of Means (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "Ratio of Means", "Ratio of Means") } - else { - lab <- "Transformed Log Ratio of Means" - if (atransf.char == "exp" || atransf.char == - "transf.exp.int") { - lab <- "Ratio of Means (log scale)" - } - if (transf.char == "exp" || transf.char == "transf.exp.int") { - lab <- "Ratio of Means" - } + } + if (measure == "CVRC") { + if (transf.char == "FALSE" && atransf.char == "FALSE") { + lab <- ifelse(short, "Log[CVR]", "Log Coefficient of Variation Ratio") + } else { + lab <- ifelse(short, lab, "Transformed Log Coefficient of Variation Ratio") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "CVR", "Coefficient of Variation Ratio (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "CVR", "Coefficient of Variation Ratio") } } - if (measure == "ARAW") { + if (measure == "VRC") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Coefficient alpha" + lab <- ifelse(short, "Log[VR]", "Log Variability Ratio") + } else { + lab <- ifelse(short, lab, "Transformed Log Variability Ratio") + if (atransf.char == "exp" || atransf.char == "transf.exp.int") + lab <- ifelse(short, "VR", "Variability Ratio (log scale)") + if (transf.char == "exp" || transf.char == "transf.exp.int") + lab <- ifelse(short, "VR", "Variability Ratio") } - else { - lab <- "Transformed Coefficient alpha" + } + + if (measure == "ARAW") { + if (transf.char == "FALSE" && atransf.char == "FALSE") { + lab <- ifelse(short, "Alpha", "Cronbach's alpha") + } else { + lab <- ifelse(short, lab, "Transformed Cronbach's alpha") } } if (measure == "AHW") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Transformed Coefficient alpha" - } - else { - lab <- "Transformed Coefficient alpha" - if (atransf.char == "transf.iahw") { - lab <- "Coefficient alpha" - } - if (transf.char == "transf.iahw") { - lab <- "Coefficient alpha" - } + lab <- ifelse(short, expression('Alpha'[HW]), "Transformed Cronbach's alpha") + } else { + lab <- ifelse(short, lab, "Transformed Cronbach's alpha") + if (atransf.char == "transf.iahw") + lab <- ifelse(short, "Alpha", "Cronbach's alpha") + if (transf.char == "transf.iahw") + lab <- ifelse(short, "Alpha", "Cronbach's alpha") } } if (measure == "ABT") { if (transf.char == "FALSE" && atransf.char == "FALSE") { - lab <- "Transformed Coefficient alpha" - } - else { - lab <- "Transformed Coefficient alpha" - if (atransf.char == "transf.iabt") { - lab <- "Coefficient alpha" - } - if (transf.char == "transf.iabt") { - lab <- "Coefficient alpha" - } + lab <- ifelse(short, expression('Alpha'[B]), "Transformed Cronbach's alpha") + } else { + lab <- ifelse(short, lab, "Transformed Cronbach's alpha") + if (atransf.char == "transf.iabt") + lab <- ifelse(short, "Alpha", "Cronbach's alpha") + if (transf.char == "transf.iabt") + lab <- ifelse(short, "Alpha", "Cronbach's alpha") } } + + } return(lab) } diff --git a/README.Rmd b/README.Rmd index 3606ddf..7821805 100644 --- a/README.Rmd +++ b/README.Rmd @@ -20,6 +20,8 @@ knitr::opts_chunk$set( [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/NikNakk/forestmodel?branch=master&svg=true)](https://ci.appveyor.com/project/NikNakk/forestmodel) [![](http://cranlogs.r-pkg.org/badges/grand-total/forestmodel?color=blue)](https://cran.r-project.org/package=forestmodel) [![R build status](https://github.com/NikNakk/forestmodel/workflows/R-CMD-check/badge.svg)](https://github.com/NikNakk/forestmodel/actions) +[![CRAN status](https://www.r-pkg.org/badges/version/forestmodel)](https://CRAN.R-project.org/package=forestmodel) +[![Codecov test coverage](https://codecov.io/gh/NikNakk/forestmodel/branch/master/graph/badge.svg)](https://codecov.io/gh/NikNakk/forestmodel?branch=master) This is an R package to generate forest plots of the coefficients of models produced diff --git a/README.md b/README.md index f6ca56c..7d572ba 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ Status](https://ci.appveyor.com/api/projects/status/github/NikNakk/forestmodel?b [![](http://cranlogs.r-pkg.org/badges/grand-total/forestmodel?color=blue)](https://cran.r-project.org/package=forestmodel) [![R build status](https://github.com/NikNakk/forestmodel/workflows/R-CMD-check/badge.svg)](https://github.com/NikNakk/forestmodel/actions) +[![CRAN +status](https://www.r-pkg.org/badges/version/forestmodel)](https://CRAN.R-project.org/package=forestmodel) This is an R package to generate forest plots of the coefficients of diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..04c5585 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,14 @@ +comment: false + +coverage: + status: + project: + default: + target: auto + threshold: 1% + informational: true + patch: + default: + target: auto + threshold: 1% + informational: true diff --git a/cran-comments.md b/cran-comments.md index 266c0b5..8dd8745 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,10 +1,15 @@ ## Test environments -* local Windows 7 install, R 3.6.1 -* ubuntu 16.04 (on travis-ci), R 3.6.1, R 3.5.3 and R-devel (2019-12-03 r77506) -* win-builder (R-devel) +* local Windows 10 install, R 4.0.2 +* ubuntu 16.04 (on travis-ci), R 3.6.3, R 4.0.0 and R-devel (2019-07-19 r78874) +* AppVeyor Windows Server 2012, R 4.0.2 +* MacOS X 10.15.5 (on GitHub actions), R 4.0.2 ## R CMD check results There were no ERRORs, WARNINGs or NOTEs. ## Downstream dependencies live +ezcox +metawho + +All were tested using the `revdepcheck` package. Sorry for previous failed submit - I had failed to put revdep in .Rbuildignore. diff --git a/docs/404.html b/docs/404.html index ffd709f..0fd7ff5 100644 --- a/docs/404.html +++ b/docs/404.html @@ -10,23 +10,27 @@ - + - + - + + + + + - - + + - + - - + + @@ -53,7 +57,7 @@ - +
@@ -75,7 +79,7 @@
+ + @@ -115,7 +125,7 @@

Page not found (404)

-

Site built with pkgdown 1.4.1.

+

Site built with pkgdown 1.6.1.

diff --git a/docs/authors.html b/docs/authors.html index db0dfae..36da2c6 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -10,23 +10,27 @@ - + - + - + + + + + - - + + - + - - + + @@ -53,7 +57,7 @@ - +
@@ -75,7 +79,7 @@
-

Site built with pkgdown 1.4.1.

+

Site built with pkgdown 1.6.1.

diff --git a/docs/bootstrap-toc.css b/docs/bootstrap-toc.css new file mode 100644 index 0000000..5a85941 --- /dev/null +++ b/docs/bootstrap-toc.css @@ -0,0 +1,60 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ + +/* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ + +/* All levels of nav */ +nav[data-toggle='toc'] .nav > li > a { + display: block; + padding: 4px 20px; + font-size: 13px; + font-weight: 500; + color: #767676; +} +nav[data-toggle='toc'] .nav > li > a:hover, +nav[data-toggle='toc'] .nav > li > a:focus { + padding-left: 19px; + color: #563d7c; + text-decoration: none; + background-color: transparent; + border-left: 1px solid #563d7c; +} +nav[data-toggle='toc'] .nav > .active > a, +nav[data-toggle='toc'] .nav > .active:hover > a, +nav[data-toggle='toc'] .nav > .active:focus > a { + padding-left: 18px; + font-weight: bold; + color: #563d7c; + background-color: transparent; + border-left: 2px solid #563d7c; +} + +/* Nav: second level (shown on .active) */ +nav[data-toggle='toc'] .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; +} +nav[data-toggle='toc'] .nav .nav > li > a { + padding-top: 1px; + padding-bottom: 1px; + padding-left: 30px; + font-size: 12px; + font-weight: normal; +} +nav[data-toggle='toc'] .nav .nav > li > a:hover, +nav[data-toggle='toc'] .nav .nav > li > a:focus { + padding-left: 29px; +} +nav[data-toggle='toc'] .nav .nav > .active > a, +nav[data-toggle='toc'] .nav .nav > .active:hover > a, +nav[data-toggle='toc'] .nav .nav > .active:focus > a { + padding-left: 28px; + font-weight: 500; +} + +/* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ +nav[data-toggle='toc'] .nav > .active > ul { + display: block; +} diff --git a/docs/bootstrap-toc.js b/docs/bootstrap-toc.js new file mode 100644 index 0000000..1cdd573 --- /dev/null +++ b/docs/bootstrap-toc.js @@ -0,0 +1,159 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ +(function() { + 'use strict'; + + window.Toc = { + helpers: { + // return all matching elements in the set, or their descendants + findOrFilter: function($el, selector) { + // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ + // http://stackoverflow.com/a/12731439/358804 + var $descendants = $el.find(selector); + return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); + }, + + generateUniqueIdBase: function(el) { + var text = $(el).text(); + var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); + return anchor || el.tagName.toLowerCase(); + }, + + generateUniqueId: function(el) { + var anchorBase = this.generateUniqueIdBase(el); + for (var i = 0; ; i++) { + var anchor = anchorBase; + if (i > 0) { + // add suffix + anchor += '-' + i; + } + // check if ID already exists + if (!document.getElementById(anchor)) { + return anchor; + } + } + }, + + generateAnchor: function(el) { + if (el.id) { + return el.id; + } else { + var anchor = this.generateUniqueId(el); + el.id = anchor; + return anchor; + } + }, + + createNavList: function() { + return $(''); + }, + + createChildNavList: function($parent) { + var $childList = this.createNavList(); + $parent.append($childList); + return $childList; + }, + + generateNavEl: function(anchor, text) { + var $a = $(''); + $a.attr('href', '#' + anchor); + $a.text(text); + var $li = $('
  • '); + $li.append($a); + return $li; + }, + + generateNavItem: function(headingEl) { + var anchor = this.generateAnchor(headingEl); + var $heading = $(headingEl); + var text = $heading.data('toc-text') || $heading.text(); + return this.generateNavEl(anchor, text); + }, + + // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). + getTopLevel: function($scope) { + for (var i = 1; i <= 6; i++) { + var $headings = this.findOrFilter($scope, 'h' + i); + if ($headings.length > 1) { + return i; + } + } + + return 1; + }, + + // returns the elements for the top level, and the next below it + getHeadings: function($scope, topLevel) { + var topSelector = 'h' + topLevel; + + var secondaryLevel = topLevel + 1; + var secondarySelector = 'h' + secondaryLevel; + + return this.findOrFilter($scope, topSelector + ',' + secondarySelector); + }, + + getNavLevel: function(el) { + return parseInt(el.tagName.charAt(1), 10); + }, + + populateNav: function($topContext, topLevel, $headings) { + var $context = $topContext; + var $prevNav; + + var helpers = this; + $headings.each(function(i, el) { + var $newNav = helpers.generateNavItem(el); + var navLevel = helpers.getNavLevel(el); + + // determine the proper $context + if (navLevel === topLevel) { + // use top level + $context = $topContext; + } else if ($prevNav && $context === $topContext) { + // create a new level of the tree and switch to it + $context = helpers.createChildNavList($prevNav); + } // else use the current $context + + $context.append($newNav); + + $prevNav = $newNav; + }); + }, + + parseOps: function(arg) { + var opts; + if (arg.jquery) { + opts = { + $nav: arg + }; + } else { + opts = arg; + } + opts.$scope = opts.$scope || $(document.body); + return opts; + } + }, + + // accepts a jQuery object, or an options object + init: function(opts) { + opts = this.helpers.parseOps(opts); + + // ensure that the data attribute is in place for styling + opts.$nav.attr('data-toggle', 'toc'); + + var $topContext = this.helpers.createChildNavList(opts.$nav); + var topLevel = this.helpers.getTopLevel(opts.$scope); + var $headings = this.helpers.getHeadings(opts.$scope, topLevel); + this.helpers.populateNav($topContext, topLevel, $headings); + } + }; + + $(function() { + $('nav[data-toggle="toc"]').each(function(i, el) { + var $nav = $(el); + Toc.init($nav); + }); + }); +})(); diff --git a/docs/index.html b/docs/index.html index 58201ba..68b9ab6 100644 --- a/docs/index.html +++ b/docs/index.html @@ -6,20 +6,20 @@ Forest Plots from Regression Models • forestmodel - - - - + + + + + - - +
    -
    @@ -121,7 +150,7 @@

    Developers

    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/pkgdown.css b/docs/pkgdown.css index 9145958..1273238 100644 --- a/docs/pkgdown.css +++ b/docs/pkgdown.css @@ -17,6 +17,10 @@ html, body { height: 100%; } +body { + position: relative; +} + body > .container { display: flex; height: 100%; @@ -67,6 +71,10 @@ summary { margin-top: calc(-60px + 1em); } +dd { + margin-left: 3em; +} + /* Section anchors ---------------------------------*/ a.anchor { @@ -100,29 +108,132 @@ a.anchor { margin-top: -40px; } +/* Navbar submenu --------------------------*/ + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu>.dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover>.dropdown-menu { + display: block; +} + +.dropdown-submenu>a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #cccccc; + margin-top: 5px; + margin-right: -10px; +} + +.dropdown-submenu:hover>a:after { + border-left-color: #ffffff; +} + +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left>.dropdown-menu { + left: -100%; + margin-left: 10px; + border-radius: 6px 0 6px 6px; +} + /* Sidebar --------------------------*/ -#sidebar { +#pkgdown-sidebar { margin-top: 30px; position: -webkit-sticky; position: sticky; top: 70px; } -#sidebar h2 { + +#pkgdown-sidebar h2 { font-size: 1.5em; margin-top: 1em; } -#sidebar h2:first-child { +#pkgdown-sidebar h2:first-child { margin-top: 0; } -#sidebar .list-unstyled li { +#pkgdown-sidebar .list-unstyled li { margin-bottom: 0.5em; } +/* bootstrap-toc tweaks ------------------------------------------------------*/ + +/* All levels of nav */ + +nav[data-toggle='toc'] .nav > li > a { + padding: 4px 20px 4px 6px; + font-size: 1.5rem; + font-weight: 400; + color: inherit; +} + +nav[data-toggle='toc'] .nav > li > a:hover, +nav[data-toggle='toc'] .nav > li > a:focus { + padding-left: 5px; + color: inherit; + border-left: 1px solid #878787; +} + +nav[data-toggle='toc'] .nav > .active > a, +nav[data-toggle='toc'] .nav > .active:hover > a, +nav[data-toggle='toc'] .nav > .active:focus > a { + padding-left: 5px; + font-size: 1.5rem; + font-weight: 400; + color: inherit; + border-left: 2px solid #878787; +} + +/* Nav: second level (shown on .active) */ + +nav[data-toggle='toc'] .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; +} + +nav[data-toggle='toc'] .nav .nav > li > a { + padding-left: 16px; + font-size: 1.35rem; +} + +nav[data-toggle='toc'] .nav .nav > li > a:hover, +nav[data-toggle='toc'] .nav .nav > li > a:focus { + padding-left: 15px; +} + +nav[data-toggle='toc'] .nav .nav > .active > a, +nav[data-toggle='toc'] .nav .nav > .active:hover > a, +nav[data-toggle='toc'] .nav .nav > .active:focus > a { + padding-left: 15px; + font-weight: 500; + font-size: 1.35rem; +} + +/* orcid ------------------------------------------------------------------- */ + .orcid { - height: 16px; + font-size: 16px; + color: #A6CE39; /* margins are required by official ORCID trademark and display guidelines */ margin-left:4px; margin-right:4px; @@ -133,14 +244,14 @@ a.anchor { .ref-index th {font-weight: normal;} -.ref-index td {vertical-align: top;} +.ref-index td {vertical-align: top; min-width: 100px} .ref-index .icon {width: 40px;} .ref-index .alias {width: 40%;} .ref-index-icons .alias {width: calc(40% - 40px);} .ref-index .title {width: 60%;} .ref-arguments th {text-align: right; padding-right: 10px;} -.ref-arguments th, .ref-arguments td {vertical-align: top;} +.ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} .ref-arguments .name {width: 20%;} .ref-arguments .desc {width: 80%;} diff --git a/docs/pkgdown.js b/docs/pkgdown.js index 087a762..7e7048f 100644 --- a/docs/pkgdown.js +++ b/docs/pkgdown.js @@ -9,11 +9,6 @@ $('body').css('padding-top', $('.navbar').height() + 10); }); - $('body').scrollspy({ - target: '#sidebar', - offset: 60 - }); - $('[data-toggle="tooltip"]').tooltip(); var cur_path = paths(location.pathname); diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml index 8999c6f..437b925 100644 --- a/docs/pkgdown.yml +++ b/docs/pkgdown.yml @@ -1,5 +1,6 @@ -pandoc: 2.3.1 -pkgdown: 1.4.1 +pandoc: 2.11.4 +pkgdown: 1.6.1 pkgdown_sha: ~ -articles: [] +articles: {} +last_built: 2021-08-08T08:42Z diff --git a/docs/reference/Rplot001.png b/docs/reference/Rplot001.png new file mode 100644 index 0000000..7029738 Binary files /dev/null and b/docs/reference/Rplot001.png differ diff --git a/docs/reference/Rplot002.png b/docs/reference/Rplot002.png new file mode 100644 index 0000000..74de60a Binary files /dev/null and b/docs/reference/Rplot002.png differ diff --git a/docs/reference/Rplot003.png b/docs/reference/Rplot003.png new file mode 100644 index 0000000..0fe8465 Binary files /dev/null and b/docs/reference/Rplot003.png differ diff --git a/docs/reference/Rplot004.png b/docs/reference/Rplot004.png new file mode 100644 index 0000000..c7e6d91 Binary files /dev/null and b/docs/reference/Rplot004.png differ diff --git a/docs/reference/default_forest_panels.html b/docs/reference/default_forest_panels.html index 612750a..c3af629 100644 --- a/docs/reference/default_forest_panels.html +++ b/docs/reference/default_forest_panels.html @@ -10,23 +10,27 @@ - + - + - + + + + + - - + + - + - - + + @@ -37,7 +41,6 @@ - @@ -55,7 +58,7 @@ - +
    @@ -77,7 +80,7 @@
    -
    default_forest_panels(model = NULL, factor_separate_line = FALSE,
    -  measure = NULL, trans_char = "I")
    +
    default_forest_panels(
    +  model = NULL,
    +  factor_separate_line = FALSE,
    +  measure = NULL,
    +  trans_char = "I"
    +)

    Arguments

    @@ -139,13 +146,10 @@

    Value

    `list` ready to be passed to `forest_model`

    - @@ -156,7 +160,7 @@

    Contents

    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/figures/README-example-1.png b/docs/reference/figures/README-example-1.png new file mode 100644 index 0000000..382250b Binary files /dev/null and b/docs/reference/figures/README-example-1.png differ diff --git a/docs/reference/figures/README-select_variables-1.png b/docs/reference/figures/README-select_variables-1.png new file mode 100644 index 0000000..e2222dd Binary files /dev/null and b/docs/reference/figures/README-select_variables-1.png differ diff --git a/docs/reference/forest_breaks.html b/docs/reference/forest_breaks.html index 07e1432..5904863 100644 --- a/docs/reference/forest_breaks.html +++ b/docs/reference/forest_breaks.html @@ -10,23 +10,27 @@ - + - + - + + + + + - - + + - + - - + + @@ -38,7 +42,6 @@ - @@ -56,7 +59,7 @@ - +
    @@ -78,7 +81,7 @@
    -
    forest_breaks(limits, trans = I)
    +
    forest_breaks(limits, trans = I)

    Arguments

    @@ -131,13 +134,10 @@

    Value

    a vector with breaks ready to pass to panel_forest_plot

    - @@ -148,7 +148,7 @@

    Contents

    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/forest_model-1.png b/docs/reference/forest_model-1.png index abc9649..1063494 100644 Binary files a/docs/reference/forest_model-1.png and b/docs/reference/forest_model-1.png differ diff --git a/docs/reference/forest_model-2.png b/docs/reference/forest_model-2.png index e791be2..0ce997d 100644 Binary files a/docs/reference/forest_model-2.png and b/docs/reference/forest_model-2.png differ diff --git a/docs/reference/forest_model-3.png b/docs/reference/forest_model-3.png index c249f54..e304665 100644 Binary files a/docs/reference/forest_model-3.png and b/docs/reference/forest_model-3.png differ diff --git a/docs/reference/forest_model-4.png b/docs/reference/forest_model-4.png index 7668635..3f86e9f 100644 Binary files a/docs/reference/forest_model-4.png and b/docs/reference/forest_model-4.png differ diff --git a/docs/reference/forest_model.html b/docs/reference/forest_model.html index 01bd951..572f984 100644 --- a/docs/reference/forest_model.html +++ b/docs/reference/forest_model.html @@ -10,23 +10,27 @@ - + - + - + + + + + - - + + - + - - + + @@ -37,7 +41,6 @@ - @@ -55,7 +58,7 @@ - +
    @@ -77,7 +80,7 @@
    -
    forest_model(model, panels = default_forest_panels(model,
    -  factor_separate_line = factor_separate_line), covariates = NULL,
    -  exponentiate = NULL, funcs = NULL, factor_separate_line = FALSE,
    -  format_options = forest_model_format_options(),
    -  theme = theme_forest(), limits = NULL, breaks = NULL,
    -  return_data = FALSE, recalculate_width = TRUE,
    -  recalculate_height = TRUE, model_list = NULL,
    -  exclude_infinite_cis = TRUE)
    +
    forest_model(
    +  model,
    +  panels = default_forest_panels(model, factor_separate_line = factor_separate_line),
    +  covariates = NULL,
    +  exponentiate = NULL,
    +  funcs = NULL,
    +  factor_separate_line = FALSE,
    +  format_options = forest_model_format_options(),
    +  theme = theme_forest(),
    +  limits = NULL,
    +  breaks = NULL,
    +  return_data = FALSE,
    +  recalculate_width = TRUE,
    +  recalculate_height = TRUE,
    +  model_list = NULL,
    +  merge_models = FALSE,
    +  exclude_infinite_cis = TRUE,
    +  show_global_p = c("none", "bottom", "aside")
    +)

    Arguments

    @@ -183,11 +197,22 @@

    Arg

    + + + + + + + +
    model_list

    list of models to incorporate into a single forest plot

    merge_models

    if `TRUE`, merge all models in one section.

    exclude_infinite_cis

    whether to exclude points and confidence intervals that go to positive or negative infinity from plotting. They will still be displayed as text. Defaults to TRUE, since otherwise plot is malformed

    show_global_p

    Show model global p value, only works for Cox model. +- 'none', don't show. +- 'bottom', show global p value in the bottom. +- 'aside', show global p value along with 'Reference', this is useful when you plot a list of models.

    @@ -200,7 +225,9 @@

    Details

    This function takes the model output from one of the common model functions in R (e.g. lm, glm, - coxph).

    + coxph). If a label attribute was present on any of the + columns in the original data (e.g. from the labelled package), + this label is used in preference to the column name.

    The panels parameter is a list of lists each of which have an element width and, optionally, item, display, display_na, @@ -208,7 +235,7 @@

    Details plot (exactly one required) or "vline" for a vertical line. display indicates which column to display as text. It can be a quoted variable name or a formula. The column display can include the standard ones produced by - tidy and in addition + tidy and in addition variable (the term in the model; for factors this is the bare variable without the level), level (the level of factors), reference (TRUE for the reference level of a factor). For coxph @@ -221,76 +248,76 @@

    Details

    Examples

    -library("survival") -library("dplyr")
    #> -#> 载入程辑包:‘dplyr’
    #> The following objects are masked from ‘package:stats’: +library("survival") +library("dplyr") +
    #> +#> Attaching package: ‘dplyr’
    #> The following objects are masked from ‘package:stats’: #> #> filter, lag
    #> The following objects are masked from ‘package:base’: #> -#> intersect, setdiff, setequal, union
    pretty_lung <- lung %>% - transmute(time, - status, - Age = age, - Sex = factor(sex, labels = c("Male", "Female")), - ECOG = factor(lung$ph.ecog), - `Meal Cal` = meal.cal - ) - -print(forest_model(coxph(Surv(time, status) ~ ., pretty_lung)))
    +#> intersect, setdiff, setequal, union
    pretty_lung <- lung %>% + transmute(time, + status, + Age = age, + Sex = factor(sex, labels = c("Male", "Female")), + ECOG = factor(lung$ph.ecog), + `Meal Cal` = meal.cal + ) + +print(forest_model(coxph(Surv(time, status) ~ ., pretty_lung))) +
    #> Warning: Unable to resize forest panel to be smaller than its heading; consider a smaller text size
    # Example with custom panels -panels <- list( - list(width = 0.03), - list(width = 0.1, display = ~variable, fontface = "bold", heading = "Variable"), - list(width = 0.1, display = ~level), - list(width = 0.05, display = ~n, hjust = 1, heading = "N"), - list(width = 0.05, display = ~n_events, width = 0.05, hjust = 1, heading = "Events"), - list( - width = 0.05, - display = ~ replace(sprintf("%0.1f", person_time / 365.25), is.na(person_time), ""), - heading = "Person-\nYears", hjust = 1 - ), - list(width = 0.03, item = "vline", hjust = 0.5), - list( - width = 0.55, item = "forest", hjust = 0.5, heading = "Hazard ratio", linetype = "dashed", - line_x = 0 - ), - list(width = 0.03, item = "vline", hjust = 0.5), - list(width = 0.12, display = ~ ifelse(reference, "Reference", sprintf( +panels <- list( + list(width = 0.03), + list(width = 0.1, display = ~variable, fontface = "bold", heading = "Variable"), + list(width = 0.1, display = ~level), + list(width = 0.05, display = ~n, hjust = 1, heading = "N"), + list(width = 0.05, display = ~n_events, width = 0.05, hjust = 1, heading = "Events"), + list( + width = 0.05, + display = ~ replace(sprintf("%0.1f", person_time / 365.25), is.na(person_time), ""), + heading = "Person-\nYears", hjust = 1 + ), + list(width = 0.03, item = "vline", hjust = 0.5), + list( + width = 0.55, item = "forest", hjust = 0.5, heading = "Hazard ratio", linetype = "dashed", + line_x = 0 + ), + list(width = 0.03, item = "vline", hjust = 0.5), + list(width = 0.12, display = ~ ifelse(reference, "Reference", sprintf( "%0.2f (%0.2f, %0.2f)", - trans(estimate), trans(conf.low), trans(conf.high) - )), display_na = NA), - list( - width = 0.05, - display = ~ ifelse(reference, "", format.pval(p.value, digits = 1, eps = 0.001)), - display_na = NA, hjust = 1, heading = "p" - ), - list(width = 0.03) -) -forest_model(coxph(Surv(time, status) ~ ., pretty_lung), panels)
    #> Warning: Unable to resize forest panel to be smaller than its heading; consider a smaller text size
    -data_for_lm <- data_frame( - x = rnorm(100, 4), - y = rnorm(100, 3, 0.5), - z = rnorm(100, 2, 2), - outcome = 3 * x - 2 * y + 4 * z + rnorm(100, 0, 0.1) -)
    #> Warning: `data_frame()` is deprecated, use `tibble()`. -#> This warning is displayed once per session.
    -print(forest_model(lm(outcome ~ ., data_for_lm)))
    -data_for_logistic <- data_for_lm %>% mutate( - outcome = (0.5 * (x - 4) * (y - 3) * (z - 2) + rnorm(100, 0, 0.05)) > 0.5 -) - -print(forest_model(glm(outcome ~ ., binomial(), data_for_logistic)))
    + trans(estimate), trans(conf.low), trans(conf.high) + )), display_na = NA), + list( + width = 0.05, + display = ~ ifelse(reference, "", format.pval(p.value, digits = 1, eps = 0.001)), + display_na = NA, hjust = 1, heading = "p" + ), + list(width = 0.03) +) +forest_model(coxph(Surv(time, status) ~ ., pretty_lung), panels) +
    #> Warning: Unable to resize forest panel to be smaller than its heading; consider a smaller text size
    +data_for_lm <- tibble( + x = rnorm(100, 4), + y = rnorm(100, 3, 0.5), + z = rnorm(100, 2, 2), + outcome = 3 * x - 2 * y + 4 * z + rnorm(100, 0, 0.1) +) + +print(forest_model(lm(outcome ~ ., data_for_lm))) +
    +data_for_logistic <- data_for_lm %>% mutate( + outcome = (0.5 * (x - 4) * (y - 3) * (z - 2) + rnorm(100, 0, 0.05)) > 0.5 +) + +print(forest_model(glm(outcome ~ ., binomial(), data_for_logistic))) +
    - @@ -301,7 +328,7 @@

    Contents

    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/forest_model_format_options.html b/docs/reference/forest_model_format_options.html index e9ee706..68018c0 100644 --- a/docs/reference/forest_model_format_options.html +++ b/docs/reference/forest_model_format_options.html @@ -6,27 +6,31 @@ -Create format options for <code>forest_model</code> — forest_model_format_options • forestmodel +Create format options for forest_model — forest_model_format_options • forestmodel - + - + - + + + + + - - + + - + - - + + @@ -35,9 +39,8 @@ - + - @@ -55,7 +58,7 @@ - +
    @@ -77,7 +80,7 @@
    -
    forest_model_format_options(colour = "black", color = NULL,
    -  shape = 15, text_size = 5, banded = TRUE)
    +
    forest_model_format_options(
    +  colour = "black",
    +  color = NULL,
    +  shape = 15,
    +  text_size = 5,
    +  point_size = 5,
    +  banded = TRUE
    +)

    Arguments

    @@ -131,6 +140,10 @@

    Arg

    + + + + @@ -142,13 +155,10 @@

    Value

    list of format options

    - @@ -159,7 +169,7 @@

    Contents

    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/forest_panel.html b/docs/reference/forest_panel.html index 3a084af..d67c62e 100644 --- a/docs/reference/forest_panel.html +++ b/docs/reference/forest_panel.html @@ -6,27 +6,31 @@ -Create definition of a panel for <code>forest_model</code> — forest_panel • forestmodel +Create definition of a panel for forest_model — forest_panel • forestmodel - + - + - + + + + + - - + + - + - - + + @@ -35,9 +39,8 @@ - + - @@ -55,7 +58,7 @@ - +
    @@ -77,7 +80,7 @@
    -
    forest_panel(width, item = c("", "forest", "vline"), display = NULL,
    -  display_na = NULL, hjust = NULL, heading = NULL, fontface = NULL,
    -  linetype = NULL, line_x = NULL, parse = NULL, width_group = NULL)
    +
    forest_panel(
    +  width,
    +  item = c("", "forest", "vline"),
    +  display = NULL,
    +  display_na = NULL,
    +  hjust = NULL,
    +  heading = NULL,
    +  fontface = NULL,
    +  linetype = NULL,
    +  line_x = NULL,
    +  parse = NULL,
    +  width_group = NULL
    +)

    Arguments

    text_size

    text size in mm

    point_size

    point size

    banded

    whether to show light grey bands behind alternate rows

    @@ -167,13 +180,10 @@

    Value

    panel definition as a list

    - @@ -184,7 +194,7 @@

    Contents

    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/forest_panels.html b/docs/reference/forest_panels.html index 548c4ac..75ec57f 100644 --- a/docs/reference/forest_panels.html +++ b/docs/reference/forest_panels.html @@ -10,23 +10,27 @@ - + - + - + + + + + - - + + - + - - + + @@ -37,7 +41,6 @@ - @@ -55,7 +58,7 @@ - +
    @@ -77,7 +80,7 @@
    -
    forest_panels(..., margin = 0.03)
    +
    forest_panels(..., margin = 0.03)

    Arguments

    @@ -129,13 +132,10 @@

    Value

    a panels list ready for forest_model or forest_rma

    - @@ -146,7 +146,7 @@

    Contents

    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/forest_rma-1.png b/docs/reference/forest_rma-1.png index 9a8dec9..e84bae6 100644 Binary files a/docs/reference/forest_rma-1.png and b/docs/reference/forest_rma-1.png differ diff --git a/docs/reference/forest_rma-2.png b/docs/reference/forest_rma-2.png index 3b33f5c..2108e78 100644 Binary files a/docs/reference/forest_rma-2.png and b/docs/reference/forest_rma-2.png differ diff --git a/docs/reference/forest_rma.html b/docs/reference/forest_rma.html index a93dc57..6992f86 100644 --- a/docs/reference/forest_rma.html +++ b/docs/reference/forest_rma.html @@ -10,23 +10,27 @@ - + - + - + + + + + - - + + - + - - + + @@ -37,7 +41,6 @@ - @@ -55,7 +58,7 @@ - +
    @@ -77,7 +80,7 @@
    -
    forest_rma(model, panels = NULL, study_labels = NULL,
    -  additional_data = NULL, point_size = NULL, model_label = NULL,
    -  show_individual_studies = TRUE, show_model = TRUE,
    -  show_stats = list(`I^2` = rlang::quo(sprintf("%0.1f%%", I2)), p =
    -  rlang::quo(format.pval(QEp, digits = 4, eps = 1e-04, scientific = 1))),
    -  trans = I, funcs = NULL, format_options = list(colour = "black",
    -  shape = 15, text_size = 5, banded = TRUE), theme = theme_forest(),
    -  limits = NULL, breaks = NULL, return_data = FALSE,
    -  recalculate_width = TRUE, recalculate_height = TRUE)
    +
    forest_rma(
    +  model,
    +  panels = NULL,
    +  study_labels = NULL,
    +  additional_data = NULL,
    +  point_size = NULL,
    +  model_label = NULL,
    +  show_individual_studies = TRUE,
    +  show_model = TRUE,
    +  show_stats = list(`I^2` = rlang::quo(sprintf("%0.1f%%", I2)), p =
    +    rlang::quo(format.pval(QEp, digits = 4, eps = 1e-04, scientific = 1))),
    +  trans = I,
    +  funcs = NULL,
    +  format_options = forest_model_format_options(),
    +  theme = theme_forest(),
    +  limits = NULL,
    +  breaks = NULL,
    +  return_data = FALSE,
    +  recalculate_width = TRUE,
    +  recalculate_height = TRUE
    +)

    Arguments

    - + @@ -207,41 +222,38 @@

    Value

    plot

    Details

    -

    This produces a forest plot using the rma

    +

    This produces a forest plot using the rma

    Examples

    -
    if (require("metafor")) { - data("dat.bcg") - dat <- escalc(measure = "RR", ai = tpos, bi = tneg, ci = cpos, di = cneg, data = dat.bcg) - model <- rma(yi, vi, data = dat) - - print(forest_rma(model, - study_labels = paste(dat.bcg$author, dat.bcg$year), - trans = exp - )) - - print(forest_rma(model, - panels = forest_panels( - Study = ~study, - N = ~n, ~vline, `Log Relative Risk` = ~ forest(line_x = 0), - ~ spacer(space = 0.10), - ~ sprintf("%0.3f (%0.3f, %0.3f)", estimate, conf.low, conf.high) - ), - study_labels = paste(dat.bcg$author, dat.bcg$year), - trans = exp - )) -}
    #> 载入需要的程辑包:metafor
    #> 载入需要的程辑包:Matrix
    #> Loading 'metafor' package (version 2.1-0). For an overview -#> and introduction to the package please type: help(metafor).
    #> Warning: Unable to resize forest panel to be smaller than its heading; consider a smaller text size
    #> Warning: Unable to resize forest panel to be smaller than its heading; consider a smaller text size
    +
    if (require("metafor")) { + data("dat.bcg") + dat <- escalc(measure = "RR", ai = tpos, bi = tneg, ci = cpos, di = cneg, data = dat.bcg) + model <- rma(yi, vi, data = dat) + + print(forest_rma(model, + study_labels = paste(dat.bcg$author, dat.bcg$year), + trans = exp + )) + + print(forest_rma(model, + panels = forest_panels( + Study = ~study, + N = ~n, ~vline, `Log Relative Risk` = ~ forest(line_x = 0), + ~ spacer(space = 0.10), + ~ sprintf("%0.3f (%0.3f, %0.3f)", estimate, conf.low, conf.high) + ), + study_labels = paste(dat.bcg$author, dat.bcg$year), + trans = exp + )) +} +
    #> Loading required package: metafor
    #> Loading required package: Matrix
    #> +#> Loading the 'metafor' package (version 3.0-2). For an +#> introduction to the package please type: help(metafor)
    #> Warning: Unable to resize forest panel to be smaller than its heading; consider a smaller text size
    #> Warning: Unable to resize forest panel to be smaller than its heading; consider a smaller text size
    - @@ -252,7 +264,7 @@

    Contents

    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/index.html b/docs/reference/index.html index 95ca021..7aa870f 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -10,23 +10,27 @@ - + - + - + + + + + - - + + - + - - + + @@ -53,7 +57,7 @@ - +
    @@ -75,7 +79,7 @@
    + + + + +
    model

    a single rma object or a list of them

    a single rma object or a list of them

    panels
    @@ -175,11 +184,10 @@

    -

    Contents

    -
    + @@ -190,7 +198,7 @@

    Contents

    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/panel_forest_plot.html b/docs/reference/panel_forest_plot.html index 294b3c3..077322e 100644 --- a/docs/reference/panel_forest_plot.html +++ b/docs/reference/panel_forest_plot.html @@ -10,23 +10,27 @@ - + - + - + + + + + - - + + - + - - + + @@ -37,7 +41,6 @@ - @@ -55,7 +58,7 @@ - +
    @@ -77,7 +80,7 @@
    -
    panel_forest_plot(forest_data, mapping = aes(estimate, xmin = conf.low,
    -  xmax = conf.high), panels = default_forest_panels(), trans = I,
    -  funcs = NULL, format_options = list(colour = "black", shape = 15,
    -  banded = TRUE, text_size = 5), theme = theme_forest(), limits = NULL,
    -  breaks = NULL, recalculate_width = TRUE, recalculate_height = TRUE,
    -  exclude_infinite_cis = TRUE)
    +
    panel_forest_plot(
    +  forest_data,
    +  mapping = aes(estimate, xmin = conf.low, xmax = conf.high),
    +  panels = default_forest_panels(),
    +  trans = I,
    +  funcs = NULL,
    +  format_options = list(colour = "black", shape = 15, banded = TRUE, text_size = 5,
    +    point_size = 5),
    +  theme = theme_forest(),
    +  limits = NULL,
    +  breaks = NULL,
    +  recalculate_width = TRUE,
    +  recalculate_height = TRUE,
    +  exclude_infinite_cis = TRUE
    +)

    Arguments

    @@ -125,7 +137,7 @@

    Arg

    - + @@ -180,13 +192,10 @@

    Value

    A ggplot ready for display or saving

    - @@ -197,7 +206,7 @@

    Contents

    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/docs/reference/theme_forest.html b/docs/reference/theme_forest.html index 2a7fff5..3b2a460 100644 --- a/docs/reference/theme_forest.html +++ b/docs/reference/theme_forest.html @@ -10,23 +10,27 @@ - + - + - + + + + + - - + + - + - - + + @@ -37,7 +41,6 @@ - @@ -55,7 +58,7 @@ - +
    @@ -77,7 +80,7 @@
    -
    theme_forest()
    +
    theme_forest()

    Value

    @@ -117,12 +120,10 @@

    Value

    a theme object for use with ggplot2

    - @@ -133,7 +134,7 @@

    Contents

    -

    Site built with pkgdown 1.4.1.

    +

    Site built with pkgdown 1.6.1.

    diff --git a/man/figures/README-example-1.png b/man/figures/README-example-1.png index 695b0cc..382250b 100644 Binary files a/man/figures/README-example-1.png and b/man/figures/README-example-1.png differ diff --git a/man/figures/README-select_variables-1.png b/man/figures/README-select_variables-1.png index 6d7efd6..e2222dd 100644 Binary files a/man/figures/README-select_variables-1.png and b/man/figures/README-select_variables-1.png differ diff --git a/man/forest_model.Rd b/man/forest_model.Rd index b3cd2c3..c828f3d 100644 --- a/man/forest_model.Rd +++ b/man/forest_model.Rd @@ -20,7 +20,9 @@ forest_model( recalculate_height = TRUE, model_list = NULL, merge_models = FALSE, - exclude_infinite_cis = TRUE + exclude_infinite_cis = TRUE, + show_global_p = c("none", "bottom", "aside"), + n_logical_true_only = FALSE ) } \arguments{ @@ -63,6 +65,14 @@ or the desired plot height in inches} \item{exclude_infinite_cis}{whether to exclude points and confidence intervals that go to positive or negative infinity from plotting. They will still be displayed as text. Defaults to \code{TRUE}, since otherwise plot is malformed} + +\item{show_global_p}{Show model global p value, only works for Cox model. +- 'none', don't show. +- 'bottom', show global p value in the bottom. +- 'aside', show global p value along with 'Reference', this is useful when you plot a list of models.} + +\item{n_logical_true_only}{whether to only count TRUE values in n for logical +covariates} } \value{ A ggplot ready for display or saving, or (with \code{return_data == TRUE}, @@ -99,8 +109,8 @@ This function takes the model output from one of the common model functions in } \examples{ -library("survival") -library("dplyr") +library(survival) +library(dplyr) pretty_lung <- lung \%>\% transmute(time, status, diff --git a/tests/figs/deps.txt b/tests/figs/deps.txt new file mode 100644 index 0000000..f4382ba --- /dev/null +++ b/tests/figs/deps.txt @@ -0,0 +1,3 @@ +- vdiffr-svg-engine: 1.0 +- vdiffr: 0.3.2.2 +- freetypeharfbuzz: 0.2.5 diff --git a/tests/figs/sample-forest-model-plot-for-lung.svg b/tests/figs/sample-forest-model-plot-for-lung.svg new file mode 100644 index 0000000..6288905 --- /dev/null +++ b/tests/figs/sample-forest-model-plot-for-lung.svg @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Age +Sex +ECOG +Meal Cal +Male +Female +0 +1 +2 +3 +180 +113 +67 +50 +86 +43 +1 +180 +1.01 (0.99, 1.03) +Reference +0.60 (0.41, 0.88) +Reference +1.32 (0.85, 2.04) +2.19 (1.33, 3.61) +6.00 (0.79, 45.70) +1.00 (1.00, 1.00) +0.467 +0.008 +0.215 +0.002 +0.083 +0.793 +Variable +N +Hazard ratio +p + + + + + + + + + + + + + +0.5 +1 +2 +5 +10 +20 +Sample forest_model plot for lung + diff --git a/tests/figs/sample-forest-rma-plot-for-dat-bcg.svg b/tests/figs/sample-forest-rma-plot-for-dat-bcg.svg new file mode 100644 index 0000000..1aff0d5 --- /dev/null +++ b/tests/figs/sample-forest-rma-plot-for-dat-bcg.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Aronson 1948 +Ferguson & Simes 1949 +Rosenthal et al 1960 +Hart & Sutherland 1977 +Frimodt-Moller et al 1973 +Stein & Aronson 1953 +Vandiviere et al 1973 +TPT Madras 1980 +Coetzee & Berjak 1968 +Rosenthal et al 1961 +Comstock et al 1974 +Comstock & Webster 1969 +Comstock et al 1976 +RE Model +262 +609 +451 +26465 +10877 +2992 +3174 +176782 +14776 +3381 +77972 +4839 +34767 +357347 +-0.889 (-2.008, 0.229) +-1.585 (-2.450, -0.721) +-1.348 (-2.611, -0.085) +-1.442 (-1.719, -1.164) +-0.218 (-0.661, 0.226) +-0.786 (-0.949, -0.623) +-1.621 (-2.546, -0.695) +0.012 (-0.111, 0.135) +-0.469 (-0.935, -0.004) +-1.371 (-1.901, -0.842) +-0.339 (-0.558, -0.121) +0.446 (-0.984, 1.876) +-0.017 (-0.541, 0.506) +-0.715 (-1.067, -0.362) +Study +N +Log Relative Risk + + + + + + + + + + + + + + + + + +0.1 +0.2 +0.5 +1 +2 +5 +Sample forest RMA plot for dat.bcg + diff --git a/tests/testthat.R b/tests/testthat.R new file mode 100644 index 0000000..4b9db0d --- /dev/null +++ b/tests/testthat.R @@ -0,0 +1,6 @@ +library(testthat) +library(forestmodel) +library(survival) +library(vdiffr) + +test_check("forestmodel") diff --git a/tests/testthat/test-forest_model.R b/tests/testthat/test-forest_model.R new file mode 100644 index 0000000..dbb41d5 --- /dev/null +++ b/tests/testthat/test-forest_model.R @@ -0,0 +1,30 @@ +test_that("forest_model function returns expected output", { + pretty_lung <- lung %>% + transmute(time, + status, + Age = age, + Sex = factor(sex, labels = c("Male", "Female")), + ECOG = factor(lung$ph.ecog), + `Meal Cal` = meal.cal + ) + + mdl <- coxph(Surv(time, status) ~ ., pretty_lung) + + panels <- default_forest_panels(mdl) + + fixed_widths <- c(0.03, 0.099, 0.078, 0.041, 0.03, 0.41, 0.03, 0.19, 0.06, 0.03) + for (i in seq_along(fixed_widths)) { + panels[[i]]$width <- fixed_widths[i] + } + + fm <- + forest_model( + mdl, + return_data = TRUE, + panels = panels, + recalculate_width = FALSE, + recalculate_height = FALSE + ) + + vdiffr::expect_doppelganger("Sample forest_model plot for lung", fm$plot) +}) diff --git a/tests/testthat/test-forest_rma.R b/tests/testthat/test-forest_rma.R new file mode 100644 index 0000000..d6eb744 --- /dev/null +++ b/tests/testthat/test-forest_rma.R @@ -0,0 +1,27 @@ +test_that("forest_rma works", { + if (require("metafor")) { + data("dat.bcg") + dat <- escalc(measure = "RR", ai = tpos, bi = tneg, ci = cpos, di = cneg, data = dat.bcg) + model <- rma(yi, vi, data = dat) + panels <- forest_panels( + Study = ~study, + N = ~n, ~vline, `Log Relative Risk` = ~ forest(line_x = 0), + ~ spacer(space = 0.10), + ~ sprintf("%0.3f (%0.3f, %0.3f)", estimate, conf.low, conf.high) + ) + fixed_widths <- c(0.03, 0.335, 0.095, 0.03, 0.239, 0.1, 0.284, 0.03) + for (i in seq_along(fixed_widths)) { + panels[[i]]$width <- fixed_widths[i] + } + + fr <- forest_rma(model, + panels = panels, + study_labels = paste(dat.bcg$author, dat.bcg$year), + trans = exp, + recalculate_width = FALSE, + recalculate_height = FALSE + ) + + vdiffr::expect_doppelganger("Sample forest RMA plot for dat.bcg", fr) + } +})
    mapping

    mapping aesthetic created using aes or aes_string

    mapping aesthetic created using aes

    panels