Performs stepwise covariate modeling by forward addition
(emax_scm_forward()), backward elimination (emax_scm_backward()), or
both in sequence. Use emax_scm_history() to retrieve the history of all
models tested during the procedure.
Usage
emax_scm_forward(mod, candidates, threshold = 0.01, seed = NULL)
emax_scm_backward(mod, candidates, threshold = 0.001, seed = NULL)
emax_scm_history(mod)Details
The candidates argument must be a named list whose names correspond to
structural parameters (e.g. E0, Emax) and whose values are character
vectors of covariate names to consider. See the examples for an
illustration.
At present, covariate selection uses p-values as the criterion: a term is
added if its p-value falls below threshold (forward) or removed if its
p-value exceeds threshold (backward). Selection on AIC or other criteria
may be supported in future.
The seed argument controls the RNG state for any stochastic components of
the procedure. It is currently experimental and may be removed in future
releases.
Every model tested during the procedure is stored internally in the returned
object. Use emax_scm_history() to extract this record.
Examples
base_model <- emax_nls(
structural_model = rsp_1 ~ exp_1,
covariate_model = list(E0 ~ 1, Emax ~ 1, logEC50 ~ 1),
data = emax_df,
opts = emax_nls_options(max_time = 10)
)
covariate_list <- list(
E0 = c("cnt_a", "cnt_b", "cnt_c", "bin_d", "bin_e"),
Emax = c("cnt_a", "cnt_b", "cnt_c", "bin_d", "bin_e")
)
# add covariates to the base model using forward addition
forward_model <- emax_scm_forward(
mod = base_model,
candidates = covariate_list,
threshold = .01
)
#> Warning: `nls()` did not converge
forward_model
#> Structural model:
#>
#> Exposure: exp_1
#> Response: rsp_1
#> Emax type: hyperbolic
#> Response type: continuous
#>
#> Covariate model:
#>
#> E0: E0 ~ 1 + cnt_a
#> Emax: Emax ~ 1
#> logEC50: logEC50 ~ 1
#>
#> Model fit:
#>
#> Observations: 400
#> Residual df: 396
#> Residual std. error: 0.5108
#> AIC: 603.6431
#>
#> Coefficients (95% CI):
#>
#> label estimate std_error lower upper
#> 1 E0_cnt_a 0.486 0.0116 0.463 0.509
#> 2 E0_Intercept 5.05 0.0759 4.91 5.20
#> 3 Emax_Intercept 9.97 0.112 9.75 10.2
#> 4 logEC50_Intercept 8.27 0.0394 8.19 8.35
#>
#> Use summary() for hypothesis tests.
# remove covariates from the forward model using backward deletion
final_model <- emax_scm_backward(
mod = forward_model,
candidates = covariate_list,
threshold = .001
)
final_model
#> Structural model:
#>
#> Exposure: exp_1
#> Response: rsp_1
#> Emax type: hyperbolic
#> Response type: continuous
#>
#> Covariate model:
#>
#> E0: E0 ~ 1 + cnt_a
#> Emax: Emax ~ 1
#> logEC50: logEC50 ~ 1
#>
#> Model fit:
#>
#> Observations: 400
#> Residual df: 396
#> Residual std. error: 0.5108
#> AIC: 603.6431
#>
#> Coefficients (95% CI):
#>
#> label estimate std_error lower upper
#> 1 E0_cnt_a 0.486 0.0116 0.463 0.509
#> 2 E0_Intercept 5.05 0.0759 4.91 5.20
#> 3 Emax_Intercept 9.97 0.112 9.75 10.2
#> 4 logEC50_Intercept 8.27 0.0394 8.19 8.35
#>
#> Use summary() for hypothesis tests.
# show the history of all models tested during the forward addition
# step and the backward deletion step
emax_scm_history(final_model)
#> # A tibble: 22 × 11
#> iteration attempt step action term_tested model_tested model_converged
#> <int> <int> <chr> <chr> <chr> <chr> <lgl>
#> 1 0 0 base model NA NA E0 ~ 1, Ema… TRUE
#> 2 1 1 forward add E0 ~ cnt_b E0 ~ 1 + cn… TRUE
#> 3 1 2 forward add E0 ~ bin_e E0 ~ 1 + bi… TRUE
#> 4 1 3 forward add Emax ~ cnt_b E0 ~ 1, Ema… TRUE
#> 5 1 4 forward add E0 ~ cnt_c E0 ~ 1 + cn… TRUE
#> 6 1 5 forward add E0 ~ cnt_a E0 ~ 1 + cn… TRUE
#> 7 1 6 forward add E0 ~ bin_d E0 ~ 1 + bi… TRUE
#> 8 1 7 forward add Emax ~ cnt_c E0 ~ 1, Ema… TRUE
#> 9 1 8 forward add Emax ~ bin_d E0 ~ 1, Ema… TRUE
#> 10 1 9 forward add Emax ~ bin_e E0 ~ 1, Ema… TRUE
#> # ℹ 12 more rows
#> # ℹ 4 more variables: term_p_value <dbl>, model_aic <dbl>, model_bic <dbl>,
#> # model_updated <lgl>
# example using binary outcomes
base_model_logistic <- emax_nls(
structural_model = rsp_2 ~ exp_1,
covariate_model = list(E0 ~ 1, Emax ~ 1, logEC50 ~ 1),
data = emax_df,
opts = emax_nls_options(max_time = 10)
)
forward_model_logistic <- emax_scm_forward(
mod = base_model_logistic,
candidates = covariate_list,
threshold = .01
)
final_model_logistic <- emax_scm_backward(
mod = forward_model_logistic,
candidates = covariate_list,
threshold = .001
)
final_model_logistic
#> Structural model:
#>
#> Exposure: exp_1
#> Response: rsp_2
#> Emax type: hyperbolic
#> Response type: continuous
#>
#> Covariate model:
#>
#> E0: E0 ~ 1 + cnt_a + bin_d
#> Emax: Emax ~ 1
#> logEC50: logEC50 ~ 1
#>
#> Model fit:
#>
#> Observations: 400
#> Residual df: 395
#> Residual std. error: 0.3696
#> AIC: 345.9516
#>
#> Coefficients (95% CI):
#>
#> label estimate std_error lower upper
#> 1 E0_cnt_a 0.0932 0.00836 0.0767 0.110
#> 2 E0_bin_d 0.145 0.0373 0.0713 0.218
#> 3 E0_Intercept -0.293 0.0566 -0.404 -0.182
#> 4 Emax_Intercept 0.930 0.145 0.707 1.29
#> 5 logEC50_Intercept 9.27 0.381 8.60 10.0
#>
#> Use summary() for hypothesis tests.
emax_scm_history(final_model_logistic)
#> # A tibble: 31 × 11
#> iteration attempt step action term_tested model_tested model_converged
#> <int> <int> <chr> <chr> <chr> <chr> <lgl>
#> 1 0 0 base model NA NA E0 ~ 1, Ema… TRUE
#> 2 1 1 forward add E0 ~ cnt_c E0 ~ 1 + cn… TRUE
#> 3 1 2 forward add Emax ~ bin_e E0 ~ 1, Ema… TRUE
#> 4 1 3 forward add Emax ~ cnt_c E0 ~ 1, Ema… TRUE
#> 5 1 4 forward add E0 ~ cnt_a E0 ~ 1 + cn… TRUE
#> 6 1 5 forward add E0 ~ cnt_b E0 ~ 1 + cn… TRUE
#> 7 1 6 forward add E0 ~ bin_d E0 ~ 1 + bi… TRUE
#> 8 1 7 forward add Emax ~ cnt_b E0 ~ 1, Ema… TRUE
#> 9 1 8 forward add Emax ~ bin_d E0 ~ 1, Ema… TRUE
#> 10 1 9 forward add E0 ~ bin_e E0 ~ 1 + bi… TRUE
#> # ℹ 21 more rows
#> # ℹ 4 more variables: term_p_value <dbl>, model_aic <dbl>, model_bic <dbl>,
#> # model_updated <lgl>