Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: parameters
Title: Processing of Model Parameters
Version: 0.28.3.3
Version: 0.28.3.4
Authors@R:
c(person(given = "Daniel",
family = "Lüdecke",
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* Fixed issue where wrong (non-robust) standard errors were calculated for
`coxph` and `svycoxph` objects.

* Fixes issues with Tukey-p-value adjustment for *emmeans* objects.

# parameters 0.28.3

* fixed bug in `standardize_info(<fixest>)` that was preventing
Expand Down
79 changes: 58 additions & 21 deletions R/format_p_adjust.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
format_p_adjust <- function(method) {
method <- tolower(method)

switch(method,
switch(
method,
holm = "Holm (1979)",
hochberg = "Hochberg (1988)",
hommel = "Hommel (1988)",
Expand Down Expand Up @@ -68,13 +69,19 @@
} else if (tolower(p_adjust) == "sidak") {
# sidak adjustment
params$p <- 1 - (1 - params$p)^(nrow(params) / rank_adjust)
} else if (tolower(p_adjust) == "sup-t") {
} else if (tolower(p_adjust) == "sup-t") {
# sup-t adjustment
params <- .p_adjust_supt(model, params)
}

if (isTRUE(all(old_p_vals == params$p)) && !identical(p_adjust, "none") && verbose) {
insight::format_warning(paste0("Could not apply ", p_adjust, "-adjustment to p-values. Either something went wrong, or the non-adjusted p-values were already very large.")) # nolint
if (
isTRUE(all(old_p_vals == params$p)) && !identical(p_adjust, "none") && verbose
) {
insight::format_warning(paste0(
"Could not apply ",
p_adjust,
"-adjustment to p-values. Either something went wrong, or the non-adjusted p-values were already very large."
)) # nolint
}
} else if (verbose) {
insight::format_alert(paste0("`p_adjust` must be one of ", toString(all_methods)))
Expand All @@ -93,7 +100,15 @@
by_vars <- model@misc$by.vars
if (!is.null(by_vars) && by_vars %in% colnames(params)) {
correction <- insight::n_unique(params[[by_vars]])
Comment thread
strengejacke marked this conversation as resolved.
Outdated
} else {
correction <- .safe(prod(vapply(model@model.info$xlev, length, numeric(1))))

Check warning on line 104 in R/format_p_adjust.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/format_p_adjust.R,line=104,col=34,[lengths_linter] Use lengths() to find the length of each element in a list.
correction <- .safe(insight::n_unique(unlist(strsplit(
model@levels$contrast,
" - ",
fixed = TRUE
))))
Comment thread
strengejacke marked this conversation as resolved.
Outdated
Comment thread
strengejacke marked this conversation as resolved.
Outdated
}

correction
},
error = function(e) {
Expand All @@ -106,22 +121,26 @@
# tukey adjustment -----

.p_adjust_tukey <- function(params, stat_column, rank_adjust = 1, verbose = TRUE) {
df_column <- colnames(params)[stats::na.omit(match(c("df", "df_error"), colnames(params)))][1]
df_column <- colnames(params)[stats::na.omit(match(
c("df", "df_error"),
colnames(params)
))][1]
if (!is.na(df_column) && length(stat_column)) {
params$p <- suppressWarnings(stats::ptukey(
sqrt(2) * abs(params[[stat_column]]),
nmeans = nrow(params) / rank_adjust,
nmeans = rank_adjust,
df = params[[df_column]],
lower.tail = FALSE
))
# for specific contrasts, ptukey might fail, and the tukey-adjustement
# could just be simple p-value calculation
if (all(is.na(params$p))) {
params$p <- 2 * stats::pt(
abs(params[[stat_column]]),
df = params[[df_column]],
lower.tail = FALSE
)
params$p <- 2 *
stats::pt(
abs(params[[stat_column]]),
df = params[[df_column]],
lower.tail = FALSE
)
verbose <- FALSE
}
}
Expand All @@ -132,7 +151,10 @@
# scheffe adjustment -----

.p_adjust_scheffe <- function(model, params, stat_column, rank_adjust = 1) {
df_column <- colnames(params)[stats::na.omit(match(c("df", "df_error"), colnames(params)))][1]
df_column <- colnames(params)[stats::na.omit(match(
c("df", "df_error"),
colnames(params)
))][1]
if (!is.na(df_column) && length(stat_column)) {
# 1st try
scheffe_ranks <- try(qr(model@linfct)$rank, silent = TRUE)
Expand All @@ -146,7 +168,8 @@
scheffe_ranks <- nrow(params)
}
scheffe_ranks <- scheffe_ranks / rank_adjust
params$p <- stats::pf(params[[stat_column]]^2 / scheffe_ranks,
params$p <- stats::pf(
params[[stat_column]]^2 / scheffe_ranks,
df1 = scheffe_ranks,
df2 = params[[df_column]],
lower.tail = FALSE
Expand Down Expand Up @@ -182,7 +205,9 @@
# get correlation matrix, based on the covariance matrix
vc <- .safe(stats::cov2cor(insight::get_varcov(model, component = component)))
if (is.null(vc)) {
insight::format_warning("Could not calculate covariance matrix for `sup-t` adjustment.")
insight::format_warning(
"Could not calculate covariance matrix for `sup-t` adjustment."
)
return(params)
}
# get confidence interval level, or set default
Expand All @@ -197,18 +222,30 @@
}
# calculate updated confidence interval level, based on simultaenous
# confidence intervals (https://onlinelibrary.wiley.com/doi/10.1002/jae.2656)
crit <- mvtnorm::qmvt(ci_level, df = params[[df_column]][1], tail = "both.tails", corr = vc)$quantile
crit <- mvtnorm::qmvt(
ci_level,
df = params[[df_column]][1],
tail = "both.tails",
corr = vc
)$quantile
# update confidence intervals
params$CI_low <- params$Coefficient - crit * params$SE
params$CI_high <- params$Coefficient + crit * params$SE
# udpate p-values
for (i in 1:nrow(params)) {

Check warning on line 235 in R/format_p_adjust.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/format_p_adjust.R,line=235,col=13,[seq_linter] Use seq_len(nrow(...)) instead of 1:nrow(...), which is likely to be wrong in the empty edge case.
params$p[i] <- 1 - mvtnorm::pmvt(
lower = rep(-abs(stats::qt(params$p[i] / 2, df = params[[df_column]][i])), nrow(vc)),
upper = rep(abs(stats::qt(params$p[i] / 2, df = params[[df_column]][i])), nrow(vc)),
corr = vc,
df = params[[df_column]][i]
)
params$p[i] <- 1 -
mvtnorm::pmvt(
lower = rep(
-abs(stats::qt(params$p[i] / 2, df = params[[df_column]][i])),
nrow(vc)
),
upper = rep(
abs(stats::qt(params$p[i] / 2, df = params[[df_column]][i])),
nrow(vc)
),
corr = vc,
df = params[[df_column]][i]
)
}
params
}
91 changes: 80 additions & 11 deletions tests/testthat/test-p_adjust.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@
)

expect_message(
mp <- model_parameters(model, include_info = TRUE, keep = c("wt", "hp"), p_adjust = "bonferroni"),
mp <- model_parameters(

Check warning on line 32 in tests/testthat/test-p_adjust.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=tests/testthat/test-p_adjust.R,line=32,col=5,[implicit_assignment_linter] Avoid implicit assignments in function calls. For example, instead of `if (x <- 1L) { ... }`, write `x <- 1L; if (x) { ... }`.
model,
include_info = TRUE,
keep = c("wt", "hp"),
p_adjust = "bonferroni"
),
"more than 1 element"
)
expect_equal(
Expand All @@ -40,7 +45,12 @@
)

expect_message(
mp <- model_parameters(model, include_info = TRUE, keep = c("cyl", "gear"), p_adjust = "bonferroni"),
mp <- model_parameters(

Check warning on line 48 in tests/testthat/test-p_adjust.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=tests/testthat/test-p_adjust.R,line=48,col=5,[implicit_assignment_linter] Avoid implicit assignments in function calls. For example, instead of `if (x <- 1L) { ... }`, write `x <- 1L; if (x) { ... }`.
model,
include_info = TRUE,
keep = c("cyl", "gear"),
p_adjust = "bonferroni"
),
"more than 1 element"
)
expect_equal(
Expand All @@ -58,9 +68,33 @@
mp <- model_parameters(m)
expect_equal(mp$p, as.data.frame(m)$p.value, tolerance = 1e-4)

m <- pairs(emmeans::emmeans(aov(Sepal.Width ~ Species, data = iris), ~Species), adjust = "scheffe")
m <- pairs(
emmeans::emmeans(aov(Sepal.Width ~ Species, data = iris), ~Species),
adjust = "scheffe"
)
mp <- model_parameters(m, p_adjust = "scheffe")
expect_equal(mp$p, as.data.frame(m)$p.value, tolerance = 1e-4)

m <- pairs(
emmeans::emmeans(aov(Sepal.Width ~ Species, data = iris), ~Species),
adjust = "tukey"
)
mp <- model_parameters(m, p_adjust = "tukey")
expect_equal(mp$p, as.data.frame(m)$p.value, tolerance = 1e-4)

data(warpbreaks)
warp.lm <- lm(breaks ~ wool * tension, data = warpbreaks)

myc <- pairs(emmeans::emmeans(warp.lm, ~ wool + tension))
mp <- model_parameters(myc, p_adjust = "tukey")
expect_equal(mp$p, as.data.frame(myc)$p.value, tolerance = 1e-4)

skip_if(getRversion() < "4.5.0")
data(penguins)
m <- lm(bill_len ~ sex * species + island, data = penguins)
emm <- pairs(emmeans::emmeans(m, ~ sex + species))
mp <- model_parameters(emm, p_adjust = "tukey")
expect_equal(mp$p, as.data.frame(emm)$p.value, tolerance = 1e-4)
})


Expand All @@ -84,7 +118,11 @@
set.seed(123)
mp <- model_parameters(model, p_adjust = "sup-t")
expect_equal(mp$p, c(0, 0.27904, 0, 0, NA, NA), tolerance = 1e-3)
expect_equal(mp$CI_low, c(67.70195, -0.48377, -4.66802, -7.51974, 8.42651, 11.50991), tolerance = 1e-3)
expect_equal(
mp$CI_low,
c(67.70195, -0.48377, -4.66802, -7.51974, 8.42651, 11.50991),
tolerance = 1e-3
)

skip_if_not_installed("glmmTMB")
data("Salamanders", package = "glmmTMB")
Expand All @@ -99,18 +137,49 @@
expect_equal(
mp$p,
c(
0.56769, 0.57466, 0.98029, 0.83123, 0.22681, 0.06271, 0.99876,
0.00068, 0.61786, 0.95269, 0.81296, 0.60973, 0.97504, 0.80566,
0.81871, 0.00024, NA, NA
0.56769,
0.57466,
0.98029,
0.83123,
0.22681,
0.06271,
0.99876,
0.00068,
0.61786,
0.95269,
0.81296,
0.60973,
0.97504,
0.80566,
0.81871,
0.00024,
NA,
NA
),
tolerance = 1e-3
)
expect_equal(
mp$CI_low,
c(
-1.6935, -2.6841, -0.45839, -1.30244, -0.14911, -0.01933, -0.76516,
0.4494, -0.77256, -2.41501, -3.08449, -0.87083, -2.50859, -2.91223,
-8.38616, -4.18299, 0.92944, 0.16671
-1.6935,
-2.6841,
-0.45839,
-1.30244,
-0.14911,
-0.01933,
-0.76516,
0.4494,
-0.77256,
-2.41501,
-3.08449,
-0.87083,
-2.50859,
-2.91223,
-8.38616,
-4.18299,
0.92944,
0.16671
),
tolerance = 1e-3)
tolerance = 1e-3
)
})
Loading