Skip to content

Commit 3545cd1

Browse files
authored
Prepare CRAN release (#369)
* Prepare CRAN release * styler * structure code * comment code, simplify code * minor print * Update get_marginalmeans.R * fix issues with latest marginaleffects, update tests * Update get_marginaltrends.R * update readme * update test * fix johnson neymann * update tests * update readme * update readme * fix * Update DESCRIPTION * styler * remotes * rename marginalization -> estimate * "average" -> "sample" * Update WORDLIST * Update get_marginalcontrasts.R * update snapshots * update snapshots * update * Fix #377 * fix test * fix * harmonize order of arguments * typoe * styler * add ATT/ATU/ATE options * more informative error for g-computation * minor * lintr * add test * add test
1 parent d90ac3b commit 3545cd1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1053
-552
lines changed

DESCRIPTION

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Type: Package
22
Package: modelbased
33
Title: Estimation of Model-Based Predictions, Contrasts and Means
4-
Version: 0.8.9.107
4+
Version: 0.9.0
55
Authors@R:
66
c(person(given = "Dominique",
77
family = "Makowski",
@@ -63,8 +63,9 @@ Suggests:
6363
lmerTest,
6464
logspline,
6565
MASS,
66-
marginaleffects,
66+
marginaleffects (>= 0.25.0),
6767
mgcv,
68+
nanoparquet,
6869
performance (>= 0.13.0),
6970
patchwork,
7071
pbkrtest,
@@ -89,4 +90,3 @@ Roxygen: list(markdown = TRUE)
8990
Config/Needs/check: stan-dev/cmdstanr
9091
Config/Needs/website: easystats/easystatstemplate
9192
LazyData: true
92-
Remotes: vincentarelbundock/marginaleffects

NEWS.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
- Argument `fixed` has been removed, as you can fix predictor at certain values
1414
using the `by` argument.
1515

16-
- Argument `transform` is deprecated. Please use `predict` instead.
16+
- Argument `transform` is no longer used to determine the scale of the predictions.
17+
Please use `predict` instead.
18+
19+
- Argument `transform` is now used to (back-) transform predictions and confidence
20+
intervals.
1721

1822
- Argument `method` in `estimate_contrasts()` was renamed into `comparison`.
1923

@@ -35,8 +39,8 @@
3539
predictions should be on the response scale, link scale, etc.). It can also
3640
be used to predict auxiliary (distributional) parameters.
3741

38-
- `estimate_means()` and `estimate_contrasts()` get a `marginalize` argument,
39-
to specify how to marginalize over non-focal terms. This results in slightly
42+
- `estimate_means()` and `estimate_contrasts()` get a `estimate` argument,
43+
to specify how to estimate over non-focal terms. This results in slightly
4044
different predicted values, each approach answering a different question.
4145

4246
- `estimate_contrasts()` gains a `backend` argument. This defaults to

R/estimate_contrasts.R

+6-11
Original file line numberDiff line numberDiff line change
@@ -104,19 +104,13 @@ estimate_contrasts.default <- function(model,
104104
by = NULL,
105105
predict = NULL,
106106
ci = 0.95,
107-
p_adjust = "none",
108107
comparison = "pairwise",
109-
marginalize = "average",
110-
backend = getOption("modelbased_backend", "marginaleffects"),
108+
estimate = "average",
109+
p_adjust = "none",
111110
transform = NULL,
111+
backend = getOption("modelbased_backend", "marginaleffects"),
112112
verbose = TRUE,
113113
...) {
114-
## TODO: remove deprecation warning later
115-
if (!is.null(transform)) {
116-
insight::format_warning("Argument `transform` is deprecated. Please use `predict` instead.")
117-
predict <- transform
118-
}
119-
120114
if (backend == "emmeans") {
121115
# Emmeans ------------------------------------------------------------------
122116
estimated <- get_emcontrasts(model,
@@ -138,7 +132,8 @@ estimate_contrasts.default <- function(model,
138132
comparison = comparison,
139133
p_adjust = p_adjust,
140134
ci = ci,
141-
marginalize = marginalize,
135+
estimate = estimate,
136+
transform = transform,
142137
verbose = verbose,
143138
...
144139
)
@@ -150,7 +145,7 @@ estimate_contrasts.default <- function(model,
150145

151146
# Table formatting
152147
attr(out, "table_title") <- c(ifelse(
153-
marginalize == "specific",
148+
estimate == "specific",
154149
"Model-based Contrasts Analysis",
155150
"Marginal Contrasts Analysis"
156151
), "blue")

R/estimate_means.R

+43-26
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,20 @@
4141
#' packages), for instance when using complex formulae in `brms` models, the
4242
#' `predict` argument can take the value of the parameter you want to estimate,
4343
#' for instance `"sigma"`, `"kappa"`, etc.
44-
#' @param marginalize Character string, indicating the type of marginalization.
45-
#' This dictates how the predictions are "averaged" over the non-focal predictors,
46-
#' i.e. those variables that are not specified in `by` or `contrast`.
44+
#' @param estimate Character string, indicating the type of target population
45+
#' predictions refer to. This dictates how the predictions are "averaged" over
46+
#' the non-focal predictors, i.e. those variables that are not specified in
47+
#' `by` or `contrast`.
4748
#' - `"average"` (default): Takes the mean value for non-focal numeric
4849
#' predictors and marginalizes over the factor levels of non-focal terms,
4950
#' which computes a kind of "weighted average" for the values at which these
5051
#' terms are hold constant. These predictions are a good representation of the
5152
#' sample, because all possible values and levels of the non-focal predictors
5253
#' are considered. It answers the question, "What is the predicted value for
53-
#' an 'average' observation in *my data*?". It refers to randomly picking a
54-
#' subject of your sample and the result you get on average. This approach is
55-
#' the one taken by default in the `emmeans` package.
54+
#' an 'average' observation in *my data*?". Cum grano salis, it refers to
55+
#' randomly picking a subject of your sample and the result you get on
56+
#' average. This approach is the one taken by default in the `emmeans`
57+
#' package.
5658
#' - `"population"`: Non-focal predictors are marginalized over the observations
5759
#' in the sample, where the sample is replicated multiple times to produce
5860
#' "counterfactuals" and then takes the average of these predicted values
@@ -65,15 +67,15 @@
6567
#' your observed sample, but also "what would be if" we had more data, or if
6668
#' we had data from a different sample.
6769
#'
68-
#' In other words, the distinction between marginalization types resides in whether
70+
#' In other words, the distinction between estimate types resides in whether
6971
#' the prediction are made for:
7072
#' - A specific "individual" from the sample (i.e., a specific combination of
7173
#' predictor values): this is what is obtained when using [`estimate_relation()`]
7274
#' and the other prediction functions.
7375
#' - An average individual from the sample: obtained with
74-
#' `estimate_means(..., marginalize = "average")`
76+
#' `estimate_means(..., estimate = "average")`
7577
#' - The broader, hypothetical target population: obtained with
76-
#' `estimate_means(..., marginalize = "population")`
78+
#' `estimate_means(..., estimate = "population")`
7779
#' @param backend Whether to use `"emmeans"` or `"marginaleffects"` as a backend.
7880
#' Results are usually very similar. The major difference will be found for mixed
7981
#' models, where `backend = "marginaleffects"` will also average across random
@@ -84,7 +86,13 @@
8486
#' `options(modelbased_backend = "emmeans")` to use the **emmeans** package or
8587
#' `options(modelbased_backend = "marginaleffects")` to set **marginaleffects**
8688
#' as default backend.
87-
#' @param transform Deprecated, please use `predict` instead.
89+
#' @param transform A function applied to predictions and confidence intervals
90+
#' to (back-) transform results, which can be useful in case the regression
91+
#' model has a transformed response variable (e.g., `lm(log(y) ~ x)`). For
92+
#' Bayesian models, this function is applied to individual draws from the
93+
#' posterior distribution, before computing summaries. Can also be `TRUE`, in
94+
#' which case `insight::get_transformation()` is called to determine the
95+
#' appropriate transformation-function.
8896
#' @param verbose Use `FALSE` to silence messages and warnings.
8997
#' @param ... Other arguments passed, for instance, to [insight::get_datagrid()],
9098
#' to functions from the **emmeans** or **marginaleffects** package, or to process
@@ -93,8 +101,8 @@
93101
#' to control the (number of) representative values.
94102
#' - **marginaleffects**: Internally used functions are `avg_predictions()` for
95103
#' means and contrasts, and `avg_slope()` for slopes. Therefore, arguments
96-
#' for instance like `vcov`, `transform`, `equivalence` or `slope` can be
97-
#' passed to those functions.
104+
#' for instance like `vcov`, `transform`, `equivalence`, `slope` or even
105+
#' `newdata` can be passed to those functions.
98106
#' - **emmeans**: Internally used functions are `emmeans()` and `emtrends()`.
99107
#' Additional arguments can be passed to these functions.
100108
#' - Bayesian models: For Bayesian models, parameters are cleaned using
@@ -172,30 +180,39 @@ estimate_means <- function(model,
172180
by = "auto",
173181
predict = NULL,
174182
ci = 0.95,
175-
marginalize = "average",
176-
backend = getOption("modelbased_backend", "marginaleffects"),
183+
estimate = "average",
177184
transform = NULL,
185+
backend = getOption("modelbased_backend", "marginaleffects"),
178186
verbose = TRUE,
179187
...) {
180-
## TODO: remove deprecation warning later
181-
if (!is.null(transform)) {
182-
insight::format_warning("Argument `transform` is deprecated. Please use `predict` instead.")
183-
predict <- transform
184-
}
185-
186188
# validate input
187-
marginalize <- insight::validate_argument(
188-
marginalize,
189+
estimate <- insight::validate_argument(
190+
estimate,
189191
c("average", "population", "specific")
190192
)
191193

192194
if (backend == "emmeans") {
193195
# Emmeans ------------------------------------------------------------------
194-
estimated <- get_emmeans(model, by = by, predict = predict, verbose = verbose, ...)
196+
estimated <- get_emmeans(
197+
model,
198+
by = by,
199+
predict = predict,
200+
verbose = verbose,
201+
...
202+
)
195203
means <- .format_emmeans_means(estimated, model, ci = ci, verbose = verbose, ...)
196204
} else {
197205
# Marginalmeans ------------------------------------------------------------
198-
estimated <- get_marginalmeans(model, by = by, predict = predict, ci = ci, marginalize = marginalize, verbose = verbose, ...) # nolint
206+
estimated <- get_marginalmeans(
207+
model,
208+
by = by,
209+
predict = predict,
210+
ci = ci,
211+
estimate = estimate,
212+
transform = transform,
213+
verbose = verbose,
214+
...
215+
)
199216
means <- format(estimated, model, ...)
200217
}
201218

@@ -204,13 +221,13 @@ estimate_means <- function(model,
204221

205222
# Table formatting
206223
attr(means, "table_title") <- c(ifelse(
207-
marginalize == "specific",
224+
estimate == "specific",
208225
"Model-based Predictions",
209226
"Estimated Marginal Means"
210227
), "blue")
211228
attr(means, "table_footer") <- .table_footer(
212229
means,
213-
type = ifelse(marginalize == "specific", "predictions", "means"),
230+
type = ifelse(estimate == "specific", "predictions", "means"),
214231
by = info$by,
215232
model = model,
216233
info = info

R/estimate_predicted.R

+25
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@
173173
#' you are directly predicting the value of some distributional parameter), and
174174
#' the corresponding functions will then only differ in the default value of
175175
#' their `data` argument.
176+
#' @param transform A function applied to predictions and confidence intervals
177+
#' to (back-) transform results, which can be useful in case the regression
178+
#' model has a transformed response variable (e.g., `lm(log(y) ~ x)`). Can also
179+
#' be `TRUE`, in which case `insight::get_transformation()` is called to
180+
#' determine the appropriate transformation-function. **Note:** Standard errors
181+
#' are not (back-) transformed!
176182
#' @param ... You can add all the additional control arguments from
177183
#' [insight::get_datagrid()] (used when `data = "grid"`) and
178184
#' [insight::get_predicted()].
@@ -228,6 +234,7 @@ estimate_expectation <- function(model,
228234
by = NULL,
229235
predict = "expectation",
230236
ci = 0.95,
237+
transform = NULL,
231238
keep_iterations = FALSE,
232239
...) {
233240
.estimate_predicted(
@@ -237,6 +244,7 @@ estimate_expectation <- function(model,
237244
ci = ci,
238245
keep_iterations = keep_iterations,
239246
predict = predict,
247+
transform = transform,
240248
...
241249
)
242250
}
@@ -249,6 +257,7 @@ estimate_link <- function(model,
249257
by = NULL,
250258
predict = "link",
251259
ci = 0.95,
260+
transform = NULL,
252261
keep_iterations = FALSE,
253262
...) {
254263
# reset to NULL if only "by" was specified
@@ -263,6 +272,7 @@ estimate_link <- function(model,
263272
ci = ci,
264273
keep_iterations = keep_iterations,
265274
predict = predict,
275+
transform = transform,
266276
...
267277
)
268278
}
@@ -274,6 +284,7 @@ estimate_prediction <- function(model,
274284
by = NULL,
275285
predict = "prediction",
276286
ci = 0.95,
287+
transform = NULL,
277288
keep_iterations = FALSE,
278289
...) {
279290
.estimate_predicted(
@@ -283,6 +294,7 @@ estimate_prediction <- function(model,
283294
ci = ci,
284295
keep_iterations = keep_iterations,
285296
predict = predict,
297+
transform = transform,
286298
...
287299
)
288300
}
@@ -294,6 +306,7 @@ estimate_relation <- function(model,
294306
by = NULL,
295307
predict = "expectation",
296308
ci = 0.95,
309+
transform = NULL,
297310
keep_iterations = FALSE,
298311
...) {
299312
# reset to NULL if only "by" was specified
@@ -308,6 +321,7 @@ estimate_relation <- function(model,
308321
ci = ci,
309322
keep_iterations = keep_iterations,
310323
predict = predict,
324+
transform = transform,
311325
...
312326
)
313327
}
@@ -321,6 +335,7 @@ estimate_relation <- function(model,
321335
by = NULL,
322336
predict = "expectation",
323337
ci = 0.95,
338+
transform = NULL,
324339
keep_iterations = FALSE,
325340
...) {
326341
# only "by" or "data", but not both
@@ -445,6 +460,16 @@ estimate_relation <- function(model,
445460
out$Residuals <- response - out$Predicted
446461
}
447462

463+
# transform reponse?
464+
if (isTRUE(transform)) {
465+
transform <- insight::get_transformation(model, verbose = FALSE)$inverse
466+
}
467+
if (!is.null(transform)) {
468+
out$Predicted <- transform(out$Predicted)
469+
out$CI_low <- transform(out$CI_low)
470+
out$CI_high <- transform(out$CI_high)
471+
}
472+
448473
# Store relevant information
449474
attr(out, "ci") <- ci
450475
attr(out, "keep_iterations") <- keep_iterations

0 commit comments

Comments
 (0)