Author: Kazuki Yoshida
Date: 2026-03-06

# Using bootstrapping with regemedint

#### Kazuki Yoshida

#### 2026-03-06

## Bootstrapping support

The `regmedint` function itself does not contain a bootstrap standard error option, which may be perferred in some settings. However, it is relatively easy to implmement in R using the `regmedint()` function and the corresponding `coef()` point estimate extraction method.

    set.seed(138087069)
    library(regmedint)
    library(tidyverse)
    ## Prepare dataset
    data(vv2015)
    ## Main fit
    regmedint_obj <- regmedint(data = vv2015,
                               ## Variables
                               yvar = "y",
                               avar = "x",
                               mvar = "m",
                               cvar = c("c"),
                               eventvar = "event",
                               ## Values at which effects are evaluated
                               a0 = 0,
                               a1 = 1,
                               m_cde = 1,
                               c_cond = 0.5,
                               ## Model types
                               mreg = "logistic",
                               yreg = "survAFT_weibull",
                               ## Additional specification
                               interaction = TRUE,
                               casecontrol = FALSE)
    coef(summary(regmedint_obj))

    ##              est         se         Z          p       lower      upper
    ## cde  0.541070807 0.29422958 1.8389409 0.06592388 -0.03560858 1.11775019
    ## pnde 0.488930417 0.21049248 2.3227928 0.02019028  0.07637274 0.90148809
    ## tnie 0.018240025 0.03706111 0.4921608 0.62260566 -0.05439841 0.09087846
    ## tnde 0.498503455 0.21209540 2.3503737 0.01875457  0.08280410 0.91420281
    ## pnie 0.008666987 0.02730994 0.3173565 0.75097309 -0.04485951 0.06219348
    ## te   0.507170442 0.21090051 2.4047853 0.01618197  0.09381303 0.92052785
    ## pm   0.045436278 0.09119614 0.4982259 0.61832484 -0.13330488 0.22417743

## `boot` package

The `boot` package is the classical way to perform bootstrapping in R. It requires defining a wrapper function.

    library(boot)
    ## Define a wrapper function
    regmedint_boot <- function(data, ind)  {
        ## Note the change in the data argument.
        regmedint_obj <- regmedint(data = data[ind,],
                                   ## Variables
                                   yvar = "y",
                                   avar = "x",
                                   mvar = "m",
                                   cvar = c("c"),
                                   eventvar = "event",
                                   ## Values at which effects are evaluated
                                   a0 = 0,
                                   a1 = 1,
                                   m_cde = 1,
                                   c_cond = 0.5,
                                   ## Model types
                                   mreg = "logistic",
                                   yreg = "survAFT_weibull",
                                   ## Additional specification
                                   interaction = TRUE,
                                   casecontrol = FALSE)
        coef(regmedint_obj)
    }
    ## Run bootstrapping
    ncpus <- 1
    ## For parallization, use the following instead.
    ## ncpus <- parallel::detectCores()
    boot_obj <- boot(data = vv2015, statistic = regmedint_boot, R = 1000,
                     ## For palatalization
                     ## See https://cran.r-project.org/package=boot
                     parallel = "multicore",
                     ncpus = ncpus)
    ## Confidence interval for the pm
    boot.ci(boot_obj, type = "basic", index = 7)

    ## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
    ## Based on 1000 bootstrap replicates
    ##
    ## CALL :
    ## boot.ci(boot.out = boot_obj, type = "basic", index = 7)
    ##
    ## Intervals :
    ## Level      Basic
    ## 95%   (-0.4322,  0.4106 )
    ## Calculations and Intervals on Original Scale

## `modelr` package

In the tidyverse ecosystem, the `modelr` package can be used to provide a potentially more flexible workflow in some settings.

    library(modelr)

    library(future)
    future::plan(sequential)
    ## For parallization, use the following instead.
    ## future::plan(multiprocess)
    library(furrr)

    ## Bootstrapping
    tib_obj <- vv2015 %>%
        modelr::bootstrap(n = 1000) %>%
        ## Resampled data objects are in the list column named strap.
        mutate(boot_fit = future_map(strap, function(strap) {
            ## Note the change in the data argument.
            regmedint_obj <- regmedint(data = as_tibble(strap),
                                       ## Variables
                                       yvar = "y",
                                       avar = "x",
                                       mvar = "m",
                                       cvar = c("c"),
                                       eventvar = "event",
                                       ## Values at which effects are evaluated
                                       a0 = 0,
                                       a1 = 1,
                                       m_cde = 1,
                                       c_cond = 0.5,
                                       ## Model types
                                       mreg = "logistic",
                                       yreg = "survAFT_weibull",
                                       ## Additional specification
                                       interaction = TRUE,
                                       casecontrol = FALSE)
            ## Trick to return a row tibble
            mat <- t(matrix(coef(regmedint_obj)))
            colnames(mat) <- names(coef(regmedint_obj))
            as_tibble(mat)
        })) %>%
        select(-strap) %>%
        unnest(cols = c(boot_fit))

    tib_obj2 <- tib_obj %>%
        pivot_longer(-.id) %>%
        mutate(name = factor(name, levels = names(coef(regmedint_obj)))) %>%
        group_by(name) %>%
        summarize(lower_boot = quantile(value, probs = 0.025),
                  upper_boot = quantile(value, probs = 0.975))
    tib_obj2

    ## # A tibble: 7 × 3
    ##   name  lower_boot upper_boot
    ##   <fct>      <dbl>      <dbl>
    ## 1 cde      -0.0968     1.17
    ## 2 pnde      0.0339     0.962
    ## 3 tnie     -0.0800     0.144
    ## 4 tnde      0.0425     0.971
    ## 5 pnie     -0.0655     0.0936
    ## 6 te        0.0519     0.984
    ## 7 pm       -0.298      0.413

## Comparison to the delta method confidence intervals

    tib_obj2 %>%
        mutate(lower_delta = confint(regmedint_obj)[,"lower"],
               upper_delta = confint(regmedint_obj)[,"upper"])

    ## # A tibble: 7 × 5
    ##   name  lower_boot upper_boot lower_delta upper_delta
    ##   <fct>      <dbl>      <dbl>       <dbl>       <dbl>
    ## 1 cde      -0.0968     1.17       -0.0356      1.12
    ## 2 pnde      0.0339     0.962       0.0764      0.901
    ## 3 tnie     -0.0800     0.144      -0.0544      0.0909
    ## 4 tnde      0.0425     0.971       0.0828      0.914
    ## 5 pnie     -0.0655     0.0936     -0.0449      0.0622
    ## 6 te        0.0519     0.984       0.0938      0.921
    ## 7 pm       -0.298      0.413      -0.133       0.224