Skip to content

Commit 3b26440

Browse files
authored
Speed up large gam with random effects (#1196)
* Speed up large `gam` with random effects easystats/insight#1169 * docs * update snaps * add test * news * formatting * formatting * news
1 parent 3a9c8f2 commit 3b26440

File tree

10 files changed

+245
-102
lines changed

10 files changed

+245
-102
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Type: Package
22
Package: parameters
33
Title: Processing of Model Parameters
4-
Version: 0.28.3.6
4+
Version: 0.28.3.7
55
Authors@R:
66
c(person(given = "Daniel",
77
family = "Lüdecke",

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212

1313
* `model_parameters()` now supports objects from the *lavaan.mi* package.
1414

15+
* Improved performance of `model_parameters()` for large `mgcv::gam()` models
16+
that include random effects when using the new `re_test` argument (e.g.,
17+
setting `re_test = FALSE` to skip expensive random-effect tests). Default
18+
behavior (with `re_test = TRUE`) is unchanged.
19+
1520
## Bug fixes
1621

1722
* Fixed issue where wrong (non-robust) standard errors were calculated for

R/1_model_parameters.R

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -634,17 +634,21 @@ model_parameters.default <- function(
634634
if (length(out) == 1 && isTRUE(is.na(out))) {
635635
insight::format_error(
636636
paste0(
637-
"Sorry, `model_parameters()` failed with the following error (possible class `",
638-
class(model)[1],
639-
"` not supported):\n"
637+
"Sorry, ",
638+
sQuote("model_parameters()"),
639+
" failed with the following error (possible class ",
640+
sQuote(class(model)[1]),
641+
" not supported):\n"
640642
),
641643
attr(out, "error")
642644
)
643645
} else if (is.null(out)) {
644646
insight::format_error(paste0(
645-
"Sorry, `model_parameters()` does not currently work for objects of class `",
646-
class(model)[1],
647-
"`."
647+
"Sorry, ",
648+
sQuote("model_parameters()"),
649+
" does not currently work for objects of class ",
650+
sQuote(class(model)[1]),
651+
"."
648652
))
649653
}
650654
}

R/extract_parameters.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
component = component,
5858
verbose = FALSE
5959
)
60-
statistic <- insight::get_statistic(model, component = component)
60+
statistic <- insight::get_statistic(model, component = component, ...)
6161

6262
# check if all estimates are non-NA
6363
parameters <- .check_rank_deficiency(model, parameters)

R/methods_gam.R

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
# classes: .gam, .list
22

3-
43
#################### .gam ------
54

6-
75
#' @export
86
model_parameters.gam <- model_parameters.cgam
97

@@ -14,10 +12,16 @@ ci.gam <- function(x, ci = 0.95, method = NULL, ...) {
1412
}
1513

1614

15+
#' @param re_test Logical, if `TRUE` (default), tests for random effects terms
16+
#' are performed. Only applies to `mgcv::gam()` model. For large models these
17+
#' tests can be computationally expensive, in which case it is recommended to
18+
#' set this argument to `FALSE`.
19+
#' @rdname standard_error
1720
#' @export
18-
standard_error.gam <- function(model, ...) {
19-
p.table <- summary(model)$p.table
20-
s.table <- summary(model)$s.table
21+
standard_error.gam <- function(model, re_test = TRUE, ...) {
22+
summ <- summary(model, re.test = re_test)
23+
p.table <- summ$p.table
24+
s.table <- summ$s.table
2125
d1 <- d2 <- NULL
2226

2327
if (!is.null(p.table)) {
@@ -28,22 +32,21 @@ standard_error.gam <- function(model, ...) {
2832
)
2933
}
3034

31-
if (!is.null(s.table)) {
32-
d2 <- .data_frame(
33-
Parameter = rownames(s.table),
34-
SE = NA,
35-
Component = "smooth_terms"
36-
)
35+
if (!is.null(s.table) && nrow(s.table) > 0) {
36+
d2 <- .data_frame(Parameter = rownames(s.table), SE = NA, Component = "smooth_terms")
3737
}
3838

3939
insight::text_remove_backticks(rbind(d1, d2), verbose = FALSE)
4040
}
4141

4242

43+
#' @inheritParams standard_error.gam
44+
#' @rdname p_value
4345
#' @export
44-
p_value.gam <- function(model, ...) {
45-
p.table <- summary(model)$p.table
46-
s.table <- summary(model)$s.table
46+
p_value.gam <- function(model, re_test = TRUE, ...) {
47+
summ <- summary(model, re.test = re_test)
48+
p.table <- summ$p.table
49+
s.table <- summ$s.table
4750
d1 <- d2 <- NULL
4851

4952
if (!is.null(p.table)) {
@@ -54,7 +57,7 @@ p_value.gam <- function(model, ...) {
5457
)
5558
}
5659

57-
if (!is.null(s.table)) {
60+
if (!is.null(s.table) && nrow(s.table) > 0) {
5861
d2 <- .data_frame(
5962
Parameter = rownames(s.table),
6063
p = as.vector(s.table[, 4]),
@@ -68,7 +71,9 @@ p_value.gam <- function(model, ...) {
6871

6972
#' @export
7073
simulate_model.gam <- function(model, iterations = 1000, ...) {
71-
if (is.null(iterations)) iterations <- 1000
74+
if (is.null(iterations)) {
75+
iterations <- 1000
76+
}
7277

7378
beta <- stats::coef(model)
7479
varcov <- insight::get_varcov(model, component = "all", ...)
@@ -83,7 +88,6 @@ simulate_model.gam <- function(model, iterations = 1000, ...) {
8388

8489
#################### .list ------
8590

86-
8791
#' @export
8892
model_parameters.list <- function(model, ...) {
8993
if ("gam" %in% names(model)) {
@@ -94,7 +98,9 @@ model_parameters.list <- function(model, ...) {
9498
model <- model$pamobject
9599
model_parameters(model, ...)
96100
} else {
97-
insight::format_error("We don't recognize this object of class `list`. Please raise an issue.")
101+
insight::format_error(
102+
"We don't recognize this object of class `list`. Please raise an issue."
103+
)
98104
}
99105
}
100106

0 commit comments

Comments
 (0)