Estimates P(treated) with a random-forest classifier
(randomForestSRC::rfsrc()) and returns the out-of-bag class
probability as the score, so no patient is scored by trees that saw them.
The result appends the same score columns as ps_logistic(), so it feeds
ps_weight(), ps_match() and sa_overlap() unchanged, and its $data
feeds hvtiPlotR::hv_mirror_hist().
Usage
ps_forest(
formula,
data,
treatment_col = NULL,
id_col = "id",
score_col = "prob_t",
logit_col = "logit_t",
weight_col = "mt_wt",
treated_level = NULL,
ntree = 500L,
seed = NULL,
clip = 0.001,
...
)Arguments
- formula
Two-sided formula,
treatment ~ x1 + x2 + .... A.on the right-hand side expands to the data's other columns, excluding the treatment andid_col; terms the formula subtracts, as in. - x3, are left out of the forest. The forest splits on the raw variables, so a transformation such aslog(age)or an interaction such asage:efcontributesageandefas they are.- data
Data frame with no missing values in the formula variables.
- treatment_col
Treatment column name; defaults to the formula response. Binary, 0/1 or logical.
- id_col
Optional patient identifier column, carried through.
- score_col, logit_col, weight_col
Names of the appended score, logit and matching-weight columns.
- treated_level
Value of
treatment_colthat is "treated" (the score is P(treated)). Defaults to1/TRUE.- ntree
Number of trees.
- seed
NULL(default) or one whole number. With a seed, R's random number stream is set toabs(seed)immediately before the fit andrandomForestSRC::rfsrc()is givenseed = -abs(seed), the sign it requires; the caller's stream is restored afterwards and the seed is kept in$meta$seed. WithNULL,rfsrc()takes its seed from the caller's stream, so the scores depend on whatever drew random numbers earlier in the session.- clip
Scores are clipped to
[clip, 1 - clip]before the logit and weight are computed. Forest probabilities can be exactly 0 or 1.- ...
Further arguments for
randomForestSRC::rfsrc().
Value
A ps_forest / ps_data object. $data is data plus
score_col, logit_col, weight_col, quintile and decile.
weight_col holds the Li-Greene matching weight computed as in
ps_logistic(), min(p, 1 - p) / p for treated patients and
min(p, 1 - p) / (1 - p) for controls, which targets the ATM estimand
(average treatment effect among the matched; Li & Greene, 2013,
doi:10.1515/ijb-2012-0030
); $meta holds formula, treatment_col,
id_col, score_col, logit_col, weight_col, treated_level,
treatment_levels, method ("forest-oob"), ntree, seed (the seed
used, NA when none was given) and n_total; $tables holds
smd and group_counts (group, the value in treatment_col; a logical
treated; n); $models$forest is the fitted forest.
Threads and reproducibility
A seed makes the forest reproducible: seeded this way, fits have matched to
the last digit on a 192-thread OpenMP Linux server and a single-threaded
Mac. randomForestSRC uses every core unless options(rf.cores = ) says
otherwise, and some randomForestSRC procedures have not been stable from
run to run under OpenMP. When two runs with the same seed disagree, set
options(rf.cores = 1L) before calling ps_forest(); it costs speed and
buys a single-threaded, repeatable fit. This function leaves the option
alone.
Examples
# \donttest{
if (requireNamespace("randomForestSRC", quietly = TRUE)) {
op <- options(rf.cores = 2L)
dta <- sample_ps_data(n = 150, seed = 1)[, c("id", "tavr", "age", "ef")]
obj <- ps_forest(tavr ~ age + ef, dta, ntree = 100, seed = 1)
summary(obj$data$prob_t)
options(op)
}
# }