Skip to content

Commit

Permalink
Merge pull request #369 from easystats/OR_to_RR-from-GLM
Browse files Browse the repository at this point in the history
OR_to_RR for GLM
  • Loading branch information
mattansb authored Aug 19, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
2 parents c256e63 + 212d155 commit ac97345
Showing 8 changed files with 81 additions and 9 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: effectsize
Title: Indices of Effect Size and Standardized Parameters
Version: 0.5-1
Version: 0.5-2
Authors@R:
c(person(given = "Mattan S.",
family = "Ben-Shachar",
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -21,6 +21,8 @@ S3method(interpret,performance_lavaan)
S3method(interpret_parameters,lm)
S3method(odds_to_probs,data.frame)
S3method(odds_to_probs,numeric)
S3method(oddsratio_to_riskratio,default)
S3method(oddsratio_to_riskratio,glm)
S3method(plot,effectsize_table)
S3method(plot,equivalence_test_effectsize)
S3method(print,effectsize_anova)
@@ -215,6 +217,7 @@ importFrom(stats,aov)
importFrom(stats,as.formula)
importFrom(stats,ave)
importFrom(stats,chisq.test)
importFrom(stats,coef)
importFrom(stats,complete.cases)
importFrom(stats,contrasts)
importFrom(stats,delete.response)
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@

## New features

- `oddsratio_to_riskratio()` can now convert OR coefficients to RR coefficients from a logistic GLM.
- All effect-size functions gain an `alternative` argument which can be used to make one- or two-sided CIs.
- `interpret()` now accepts as input the results from `cohens_d()`, `eta_squared()`, `rank_biserial()`, etc.
- `interpret_pd()` for the interpretation of the [*Probability of Direction*](https://easystats.github.io/bayestestR/reference/p_direction.html).
53 changes: 50 additions & 3 deletions R/convert_between_OR_to_RR.R
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#' Convert between Odds ratios and Risk ratios
#'
#' @param OR,RR Risk ratio of `p1/p0` or Odds ratio of `odds(p1)/odds(p0)`,
#' possibly log-ed.
#' possibly log-ed. `OR` can also be a logistic regression model.
#' @param p0 Baseline risk
#' @param ... Arguments passed to and from other methods.
#' @inheritParams oddsratio_to_d
#'
#' @return Converted index.
#' @return Converted index, or if `OR` is a logistic regression model, a
#' parameter table with the converted indices.
#'
#' @family convert between effect sizes
#'
@@ -18,14 +20,23 @@
#'
#' riskratio_to_oddsratio(RR, p0 = p0)
#' oddsratio_to_riskratio(OR, p0 = p0)
#'
#' m <- glm(am ~ factor(cyl), data = mtcars,
#' family = binomial())
#' oddsratio_to_riskratio(m)
#' @references
#'
#' Grant, R. L. (2014). Converting an odds ratio to a range of plausible
#' relative risks for better communication of research findings. Bmj, 348,
#' f7450.
#'
#' @export
oddsratio_to_riskratio <- function(OR, p0, log = FALSE) {
oddsratio_to_riskratio <- function(OR, p0, log = FALSE, ...) {
UseMethod("oddsratio_to_riskratio")
}

#' @export
oddsratio_to_riskratio.default <- function(OR, p0, log = FALSE, ...) {
if (log) OR <- exp(OR)

RR <- OR / (1 - p0 + (p0 * OR))
@@ -34,6 +45,41 @@ oddsratio_to_riskratio <- function(OR, p0, log = FALSE) {
return(RR)
}

#' @export
#' @importFrom stats coef
oddsratio_to_riskratio.glm <- function(OR, p0, log = FALSE, ...) {
mi <- insight::model_info(OR)
if (!mi$is_binomial || !mi$is_logit) stop("Model must a binomial model with logit-link (logistic regression)")

if (used_intercept <- missing(p0)) {
p0 <- plogis(stats::coef(OR)["(Intercept)"])
warning("'p0' not provided.",
"RR is relative to the intercept (p0 = ",
insight::format_value(p0),
") - make sure your intercept is meaningful.")
}

RR <- parameters::model_parameters(OR, exponentiate = !log, ...)
RR$SE <- NULL
RR$z <- NULL
RR$df_error <- NULL
RR$p <- NULL

RR[,colnames(RR) %in% c("Coefficient", "CI_low", "CI_high")] <-
lapply(RR[,colnames(RR) %in% c("Coefficient", "CI_low", "CI_high")],
oddsratio_to_riskratio, p0 = p0, log = log)

RR[RR$Parameter=="(Intercept)", "Coefficient"] <- p0
RR[RR$Parameter=="(Intercept)", c("CI_low", "CI_high")] <- NA

if (!used_intercept) {
RR[RR$Parameter=="(Intercept)", "Parameter"] <- "(p0)"
}

attr(RR, "coefficient_name") <- if (log) "Log-RR" else "Risk Ratio"
return(RR)
}



#' @rdname oddsratio_to_riskratio
@@ -46,3 +92,4 @@ riskratio_to_oddsratio <- function(RR, p0, log = FALSE) {
if (log) OR <- log(OR)
return(OR)
}

2 changes: 1 addition & 1 deletion man/format_standardize.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions man/oddsratio_to_riskratio.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/print.effectsize_table.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions tests/testthat/test-convert_between.R
Original file line number Diff line number Diff line change
@@ -28,6 +28,20 @@ if (require("testthat") && require("effectsize")) {

expect_equal(riskratio_to_oddsratio(log(RR), p0 = p0, log = TRUE), log(OR))
expect_equal(oddsratio_to_riskratio(log(OR), p0 = p0, log = TRUE), log(RR))


m <- glm(am ~ factor(cyl), data = mtcars,
family = binomial())

expect_warning(RR <- oddsratio_to_riskratio(m))
expect_true("(Intercept)" %in% RR$Parameter)
expect_false("(p0)" %in% RR$Parameter)
expect_equal(RR$Coefficient, c(0.7272, 0.5892, 0.1964), tolerance = 0.001)

RR <- oddsratio_to_riskratio(m, p0 = 0.05)
expect_true("(p0)" %in% RR$Parameter)
expect_false("(Intercept)" %in% RR$Parameter)
expect_equal(RR$Coefficient, c(0.05, 0.29173, 0.06557), tolerance = 0.001)
})

test_that("odds_to_probs", {

0 comments on commit ac97345

Please sign in to comment.