Skip to content

Commit 4eb4b9c

Browse files
committed
improved semtree control documentation
1 parent e6e1413 commit 4eb4b9c

6 files changed

Lines changed: 98 additions & 28 deletions

File tree

.Rbuildignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ cran-comments.md
1919
^\.github$
2020
^\.httr-oauth$
2121
error.log
22-
vignettes/vignette-cache
22+
vignettes/vignette-cache
23+
inst/extdata/cache.rds

R/scoreSplit.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ ScoreSplit <- function(model = NULL, mydata = NULL, control = NULL,
3636
# label scores from lavaan models
3737
# removes duplicate parameter names
3838
if (control$sem.prog == "lavaan") {
39-
unique_par_names <- unique(names(lavaan:::coef(model)))
39+
unique_par_names <- unique(names(lavaan::coef(model)))
4040
colnames(Scores) <- unique_par_names
4141
}
4242

R/semtree.control.R

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,49 +18,51 @@
1818
#'
1919
#'
2020
#' @aliases semtree.control print.semtree.control semtree_control
21-
#' @param method Default: 'naive'. One out of
22-
#' \code{c("score","fair","naive")} for either an unbiased two-step
23-
#' selection algorithm, a naive take-the-best, or a
24-
#' score-based testing scheme.
25-
#' @param min.N Default: 10. Minimum sample size per a node, used to determine
26-
#' whether to continue splitting a tree or establish a terminal node.
27-
#' @param max.depth Default: NA. Maximum levels per a branch. Parameter for
21+
#' @param method Default: 'naive'. One of
22+
#' \code{c("score","fair","naive")} for a score-based testing
23+
#' scheme, an unbiased multi-step selection algorithm, or a naive
24+
#' take-the-best strategy.
25+
#' @param min.N Integer. Default: `NULL` heuristically selects this number based on the number of parameters in the model. Minimum sample size per
26+
#' node used to determine whether splitting can continue. It is recommended to set `min.N` explicitly.
27+
#' @param max.depth Integer. Default: NA. Maximum levels per a branch. Parameter for
2828
#' limiting tree growth.
29-
#' @param alpha Default: 0.05. Significance level for splitting at a given
29+
#' @param alpha Numeric. Default: 0.05. Significance level for splitting at a given
3030
#' node.
31-
#' @param alpha.invariance Default: NA. Significance level for invariance
31+
#' @param Numeric. alpha.invariance Default: NA. Significance level for invariance
3232
#' tests. If NA, the value of alpha is used.
3333
#' @param exclude.heywood Default: TRUE. Reports whether there is an
3434
#' identification problem in the covariance structure of an SEM tested.
35-
#' @param progress.bar Default: NA. Option to disable the progress bar for tree
36-
#' growth.
37-
#' @param verbose Default: FALSE. Option to turn on or off \emph{all} model
35+
#' @param progress.bar Boolean. Default: TRUE. Option to enable or disable the progress
36+
#' bar for tree growth.
37+
#' @param verbose Boolean. Default: FALSE. Option to turn on or off \emph{all} model
3838
#' messages during tree growth.
39-
#' @param bonferroni Default: FALSE. Correct for multiple tests with Bonferroni
39+
#' @param bonferroni Boolean. Default: FALSE. Correct for multiple tests with Bonferroni
4040
#' type correction. p-values are adjusted for the number of variables tested.
41-
#' @param seed Default: NA. Set a random number seed for repeating random fold
42-
#' generation in tree analysis.
41+
#' @param seed Default: `NA`. Set a random-number seed to make randomized parts
42+
#' of tree analysis reproducible (for example, in fair splitting or subsampling
43+
#' procedures).
4344
#' @param custom.stopping.rule Default: NA. Otherwise, this can be a boolean
4445
#' function with a custom stopping rule for tree growing.
4546
#' @param exclude.code Default: NA. NPSOL error code for exclusion from model
4647
#' fit evaluations when finding best split. Default: Models with errors during
4748
#' fitting are retained.
4849
#' @param mtry Default: NA. Number of sample columns to use in SEMforest
4950
#' analysis.
50-
#' @param report.level Default: 0. Values up to 99 can be used to increase the
51-
#' number of onscreen reports for semtree analysis.
52-
#' @param use.all Treatment of missing variables. By default, missing values
51+
#' @param report.level Integer. Default: 0. Values up to 99 increase console reporting
52+
#' detail during tree growth and can help diagnose fitting or split-selection
53+
#' issues.
54+
#' @param use.all Boolean. Treatment of missing variables. By default, missing values
5355
#' stay in a decision node. If TRUE, cases are distributed according to a
5456
#' maximum likelihood principle to the child nodes.
5557
#' @param linear If TRUE (default), the structural equation model is assumed to
5658
#' not contain any nonlinear parameter constraints and scores are computed
5759
#' analytically, resulting in a shorter runtime. Only relevant for models fitted
5860
#' with OpenMx.
59-
#' @param min.bucket Minimum bucket size. This is the minimum size any node
61+
#' @param min.bucket Integer. Minimum bucket size. This is the minimum size any node
6062
#' must have, such that a given split is considered valid. Minimum bucket size
6163
#' is a lower bound to the sample size in the terminal nodes of a tree.
6264
#' @param missing Missing value treatment. Default is ignore
63-
#' @param use.maxlr Use MaxLR statistic for split point selection (as proposed by Arnold et al., 2021). This corrects the bias in the LR statistics incurred by testing multiple split points within one variable.
65+
#' @param use.maxlr Boolean. Use MaxLR statistic for split point selection (as proposed by Arnold et al., 2021). This corrects the bias in the LR statistics incurred by testing multiple split points within one variable.
6466
#' @param strucchange.from Strucchange argument. See their package
6567
#' documentation.
6668
#' @param strucchange.to Strucchange argument. See their package documentation.
@@ -70,14 +72,17 @@
7072
#' provided to \code{\link{semtree}}.
7173
#' @param ctsem_sd If FALSE (default) no standard errors of CT model parameters
7274
#' are computed. Requesting standard errors increases runtime.
73-
#' @param loglik Character. Algorithm to compute log likelihood. The 'default' algorithm
74-
#' depends on the chosen SEM package. It is 'mvn' for lavaan and 'model' for all
75-
#' other packages. 'model'refers to a model-based computation.
76-
#' This is preferable because it is more general. As an alternative, 'mvn' computes
77-
#' the log likelihood based on the
75+
#' @param loglik Character.Character. Algorithm to compute log likelihood. `"default"`
76+
#' depends on the chosen SEM package: `"mvn"` for lavaan and `"model"` for
77+
#' all other packages. `"model"` refers to model-based computation and is more
78+
#' general. `"mvn"` computes likelihood from the multivariate normal density
79+
#' using model-implied means and covariance matrices.
7880
#' multivariate normal density and the model-implied mean and covariance matrix.
7981
#' @param check.convergence Boolean. Should convergence be checked when growing a tree. Default: TRUE
80-
#' @param chunk.random.samples Integer. Default 0 means that
82+
#' @param chunk.random.samples Integer. Controlling split-point subsampling for
83+
#' `method = "naive"`. `0` (default) evaluates all eligible split points.
84+
#' Values `> 0` evaluate random chunks of split points, which can speed up tree
85+
#' growth on very large datasets at the cost of a less exhaustive search.
8186
#' @return A control object containing a list of the above parameters.
8287
#' @author Andreas M. Brandmaier, John J. Prindle, Manuel Arnold
8388
#' @seealso \code{\link{semtree}}

README.Rmd

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,22 @@ Package vignettes (shipped with the package) contain documentation on how to use
5454
browseVignettes("semtree")
5555
```
5656

57+
## Robustness checklist for end users
58+
59+
To make analyses with `semtree` more robust and reproducible, we recommend the following:
60+
61+
1. **Set a seed in `semtree_control(seed = ...)`** before tree growth so randomized split procedures are reproducible.
62+
2. **Set explicit stopping rules** (`min.N`, optionally `min.bucket`, and `max.depth`) instead of relying on defaults.
63+
3. **Choose split method intentionally** (`naive`, `fair`, or `score`) and report the choice in manuscripts.
64+
4. **Use conservative split testing where appropriate** with `bonferroni = TRUE` when many predictors are screened.
65+
5. **Inspect convergence behavior** by keeping `check.convergence = TRUE` and increasing `report.level` for diagnostics.
66+
6. **Handle missing split variables explicitly** (`missing`, `use.all`) and document your choice.
67+
7. **Pick and report likelihood computation** (`loglik = "model"` vs `"mvn"`) especially when comparing engines.
68+
8. **Use pruning for interpretation** to avoid over-reading deep, unstable branches (`prune(tree, max.depth = ...)`).
69+
9. **Validate findings with forests** (`semforest`) to check whether important predictors recur across trees.
70+
10. **Archive session metadata** (at the very least document `sessionInfo()`, package versions, and control settings) alongside analysis outputs, or use packages such as `reproducibleRchunks` or `repro` to improve reproducibility chances.
71+
72+
5773
## References
5874

5975
Theory and method:

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,35 @@ package:
5555

5656
browseVignettes("semtree")
5757

58+
## Robustness checklist for end users
59+
60+
To make analyses with `semtree` more robust and reproducible, we
61+
recommend the following:
62+
63+
1. **Set a seed in `semtree_control(seed = ...)`** before tree growth
64+
so randomized split procedures are reproducible.
65+
2. **Set explicit stopping rules** (`min.N`, optionally `min.bucket`,
66+
and `max.depth`) instead of relying on defaults.
67+
3. **Choose split method intentionally** (`naive`, `fair`, or `score`)
68+
and report the choice in manuscripts.
69+
4. **Use conservative split testing where appropriate** with
70+
`bonferroni = TRUE` when many predictors are screened.
71+
5. **Inspect convergence behavior** by keeping
72+
`check.convergence = TRUE` and increasing `report.level` for
73+
diagnostics.
74+
6. **Handle missing split variables explicitly** (`missing`, `use.all`)
75+
and document your choice.
76+
7. **Pick and report likelihood computation** (`loglik = "model"` vs
77+
`"mvn"`) especially when comparing engines.
78+
8. **Use pruning for interpretation** to avoid over-reading deep,
79+
unstable branches (`prune(tree, max.depth = ...)`).
80+
9. **Validate findings with forests** (`semforest`) to check whether
81+
important predictors recur across trees.
82+
10. **Archive session metadata** (at the very least document
83+
`sessionInfo()`, package versions, and control settings) alongside
84+
analysis outputs, or use packages such as `reproducibleRchunks` or
85+
`repro` to improve reproducibility chances.
86+
5887
## References
5988

6089
Theory and method:

tests/testthat/logfile.R

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
n <- 500
2+
set.seed(233453)
3+
x = rnorm(n)
4+
var_ordered <- ordered( sample(c(1,2,3,4),
5+
size=n, prob=rep(.25,4),
6+
replace = TRUE))
7+
var_ordered_named <- ordered( sample(c(1,2,3,4),
8+
size=n, prob=rep(.25,4),
9+
replace = TRUE),
10+
labels=c("one","two","three","four"))
11+
x <- x * ifelse( (var_ordered_named=="one"), .5, 10)
12+
df <- data.frame(x, var_ordered_named)
13+
model = "x ~~ x"
14+
fitted_model <- lavaan::lavaan(model, df)
15+
tree = semtree(fitted_model, df, control=semtree_control())
16+
17+
forest = semforest(fitted_model, df, control=semforest_control(logfile=FALSE))
18+
forest = semforest(fitted_model, df, control=semforest_control(logfile=TRUE))
19+
forest = semforest(fitted_model, df, control=semforest_control(logfile=))

0 commit comments

Comments
 (0)