File: bootstrap_parameters.R

package info (click to toggle)
r-cran-parameters 0.24.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,852 kB
  • sloc: sh: 16; makefile: 2
file content (150 lines) | stat: -rw-r--r-- 5,472 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#' Parameters bootstrapping
#'
#' Compute bootstrapped parameters and their related indices such as Confidence Intervals (CI) and p-values.
#'
#'
#' @param test The indices to compute. Character (vector) with one or more of
#' these options: `"p-value"` (or `"p"`), `"p_direction"` (or `"pd"`), `"rope"`,
#' `"p_map"`, `"equivalence_test"` (or `"equitest"`), `"bayesfactor"` (or `"bf"`)
#' or `"all"` to compute all tests. For each "test", the corresponding
#' **bayestestR** function is called (e.g. [bayestestR::rope()] or
#' [bayestestR::p_direction()]) and its results included in the summary output.
#' @param ... Arguments passed to other methods, like [`bootstrap_model()`] or
#' [`bayestestR::describe_posterior()`].
#' @inheritParams bootstrap_model
#' @inheritParams bayestestR::describe_posterior
#'
#' @return A data frame summarizing the bootstrapped parameters.
#'
#' @inheritSection bootstrap_model Using with **emmeans**
#'
#' @references
#' Davison, A. C., & Hinkley, D. V. (1997). Bootstrap methods and their
#' application (Vol. 1). Cambridge university press.
#'
#' @seealso [`bootstrap_model()`], [`simulate_parameters()`], [`simulate_model()`]
#'
#' @details This function first calls [`bootstrap_model()`] to generate
#'   bootstrapped coefficients. The resulting replicated for each coefficient
#'   are treated as "distribution", and is passed to [`bayestestR::describe_posterior()`]
#'   to calculate the related indices defined in the `"test"` argument.
#'
#'   Note that that p-values returned here are estimated under the assumption of
#'   *translation equivariance*: that shape of the sampling distribution is
#'   unaffected by the null being true or not. If this assumption does not hold,
#'   p-values can be biased, and it is suggested to use proper permutation tests
#'   to obtain non-parametric p-values.
#'
#' @examplesIf require("boot", quietly = TRUE) && require("emmeans", quietly = TRUE)
#' \donttest{
#' set.seed(2)
#' model <- lm(Sepal.Length ~ Species * Petal.Width, data = iris)
#' b <- bootstrap_parameters(model)
#' print(b)
#'
#' # different type of bootstrapping
#' set.seed(2)
#' b <- bootstrap_parameters(model, type = "balanced")
#' print(b)
#'
#' est <- emmeans::emmeans(b, trt.vs.ctrl ~ Species)
#' print(model_parameters(est))
#' }
#' @export
bootstrap_parameters <- function(model, ...) {
  UseMethod("bootstrap_parameters")
}


# methods ----------------------------------------------------------------------

#' @rdname bootstrap_parameters
#' @export
bootstrap_parameters.default <- function(model,
                                         iterations = 1000,
                                         centrality = "median",
                                         ci = 0.95,
                                         ci_method = "quantile",
                                         test = "p-value",
                                         ...) {
  boot_data <- bootstrap_model(model, iterations = iterations, ...)
  bootstrap_parameters(boot_data, centrality = centrality, ci = ci, ci_method = ci_method, test = test, ...)
}


#' @export
bootstrap_parameters.bootstrap_model <- function(model,
                                                 centrality = "median",
                                                 ci = 0.95,
                                                 ci_method = "quantile",
                                                 test = "p-value",
                                                 ...) {
  out <- .summary_bootstrap(
    data = model,
    test = test,
    centrality = centrality,
    ci = ci,
    ci_method = ci_method,
    ...
  )

  class(out) <- c("bootstrap_parameters", "parameters_model", class(out))
  attr(out, "boot_samples") <- model
  out
}


#' @export
model_parameters.bootstrap_model <- bootstrap_parameters.bootstrap_model


# utilities --------------------------------------------------------------------

#' @keywords internal
.summary_bootstrap <- function(data, test, centrality, ci, ci_method, ...) {
  # Is the p-value requested?
  if (any(test %in% c("p-value", "p", "pval"))) {
    p_value <- TRUE
    test <- setdiff(test, c("p-value", "p", "pval"))
    if (length(test) == 0) test <- NULL
  } else {
    p_value <- FALSE
  }

  parameters <- bayestestR::describe_posterior(
    data,
    centrality = centrality,
    ci = ci,
    ci_method = ci_method,
    test = test,
    ...
  )

  # Remove unnecessary columns
  if ("CI" %in% names(parameters) && insight::n_unique(parameters$CI) == 1) {
    parameters$CI <- NULL
  } else if ("CI" %in% names(parameters) && insight::n_unique(parameters$CI) > 1) {
    parameters <- datawizard::reshape_ci(parameters)
  }

  # Coef
  if (length(centrality) == 1) {
    names(parameters)[names(parameters) == insight::format_capitalize(centrality)] <- "Coefficient"
  }

  # p-value
  if (p_value) {
    parameters$.row_order <- seq_len(nrow(parameters))
    # calculate probability of direction, then convert to p.
    p <- bayestestR::p_direction(data, null = 0, ...)
    p$p <- as.numeric(bayestestR::pd_to_p(p$pd))
    p$pd <- NULL
    parameters <- merge(parameters, p, all = TRUE)
    parameters <- parameters[order(parameters$.row_order), ]
    parameters$.row_order <- NULL
  }

  rownames(parameters) <- NULL
  attr(parameters, "ci") <- ci
  parameters
}