-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
functions to plot individual parameters when using definition variabl…
…es in algebras (e.g., mnlfa)
- Loading branch information
Showing
10 changed files
with
795 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#' get_individual_algebra_results | ||
#' | ||
#' evaluates algebras for each subject in the data set. This function is | ||
#' useful if you have algebras with definition variables (e.g., in mnlfa). | ||
#' @param mxModel mxModel with algebras | ||
#' @param algebra_names optional: Only compute individual algebras for a subset | ||
#' of the parameters | ||
#' @param progress_bar should a progress bar be shown? | ||
#' @returns a list of data frames. The list contains data frames for each of the algebras. | ||
#' The data frames contain the individual specific algebra results as well as all | ||
#' definition variables used to predict said algebra | ||
#' @export | ||
#' @importFrom utils txtProgressBar | ||
#' @importFrom utils setTxtProgressBar | ||
#' @examples | ||
#' library(mxsem) | ||
#' | ||
#' set.seed(123) | ||
#' dataset <- simulate_moderated_nonlinear_factor_analysis(N = 50) | ||
#' | ||
#' model <- " | ||
#' xi =~ x1 + x2 + x3 | ||
#' eta =~ y1 + y2 + y3 | ||
#' eta ~ {a := a0 + data.k*a1}*xi | ||
#' " | ||
#' fit <- mxsem(model = model, | ||
#' data = dataset) |> | ||
#' mxTryHard() | ||
#' | ||
#' algebra_results <- get_individual_algebra_results(mxModel = fit, | ||
#' progress_bar = FALSE) | ||
#' | ||
#' # the following plot will only show two data points because there is only | ||
#' # two values for the definition variable k (0 or 1). | ||
#' | ||
#' plot(x = algebra_results[["a"]]$k, | ||
#' y = algebra_results[["a"]]$algebra_result) | ||
get_individual_algebra_results <- function(mxModel, | ||
algebra_names = NULL, | ||
progress_bar = TRUE){ | ||
n_subjects <- mxModel$data$numObs | ||
if(is.null(algebra_names)){ | ||
algebra_names <- names(mxModel$algebras) | ||
}else{ | ||
if(any(! algebra_names %in% names(mxModel$algebras))) | ||
stop("Could not find the following algebra(s) in your model: ", | ||
paste0(algebra_names[! algebra_names %in% names(mxModel$algebras)], collapse = ", "), | ||
". The algebras are: ", | ||
paste0(names(mxModel$algebras), collapse = ", "), ".") | ||
} | ||
|
||
if(is.null(algebra_names) | (length(algebra_names) == 0)) | ||
stop("Could not find any algebras in your OpenMx model.") | ||
|
||
|
||
algebra_results <- vector("list", length(algebra_names)) | ||
names(algebra_results) <- algebra_names | ||
|
||
if(progress_bar) | ||
pb <- utils::txtProgressBar(min = 0, | ||
max = length(algebra_names) * n_subjects, | ||
initial = 0, | ||
style = 3) | ||
|
||
it <- 0 | ||
|
||
for(algebra_name in algebra_names){ | ||
|
||
# find definition variables used in this algebra | ||
algebra_elements <- extract_algebra_elements(mxAlgebra_formula = mxModel$algebras[[algebra_name]]$formula) | ||
definition_variables <- algebra_elements[grepl("^data\\.", x = algebra_elements)] |> | ||
gsub(pattern = "data\\.", replacement = "", x = _) | ||
|
||
algebra_result <- data.frame(person = 1:n_subjects, | ||
mxModel$data$observed[,definition_variables, drop = FALSE], | ||
algebra_result = NA) | ||
|
||
for(i in 1:n_subjects){ | ||
it <- it + 1 | ||
if(progress_bar) | ||
utils::setTxtProgressBar(pb = pb, | ||
value = it) | ||
|
||
algebra_result_i <- mxEvalByName(name = algebra_name, | ||
model = mxModel, | ||
compute = TRUE, | ||
defvar.row = i) | ||
if((nrow(algebra_result_i) != 1) | | ||
(ncol(algebra_result_i) != 1)) | ||
stop("This function cannot handle algebras with non-scalar outcomes.") | ||
|
||
algebra_result$algebra_result[i] <- algebra_result_i[1,1] | ||
} | ||
|
||
algebra_results[[algebra_name]] <- algebra_result | ||
} | ||
|
||
return(algebra_results) | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
test_that("testing individual algebras", { | ||
set.seed(123) | ||
dataset <- simulate_moderated_nonlinear_factor_analysis(N = 50) | ||
|
||
model <- " | ||
xi =~ x1 + x2 + x3 | ||
eta =~ y1 + y2 + y3 | ||
eta ~ a*xi | ||
!a0 | ||
!a1 | ||
a := a0 + data.k*a1 | ||
" | ||
|
||
mod <- mxsem(model = model, | ||
data = dataset) |> | ||
mxTryHard() | ||
|
||
ind_alg <- get_individual_algebra_results(mxModel = mod) | ||
|
||
testthat::expect_true(length(ind_alg) == 1) | ||
testthat::expect_true(names(ind_alg) == c("a")) | ||
testthat::expect_true(all(colnames(ind_alg$a) == c("person", "k", "algebra_result"))) | ||
|
||
testthat::expect_error(get_individual_algebra_results(mxModel = mod, | ||
algebra_names = "b")) | ||
|
||
model <- " | ||
xi =~ x1 + x2 + x3 | ||
eta =~ y1 + y2 + y3 | ||
eta ~ {a := a0 + data.k*a1}*xi | ||
" | ||
|
||
mod2 <- mxsem(model = model, | ||
data = dataset) |> | ||
mxTryHard() | ||
|
||
ind_alg <- get_individual_algebra_results(mxModel = mod2) | ||
|
||
testthat::expect_true(length(ind_alg) == 1) | ||
testthat::expect_true(names(ind_alg) == c("a")) | ||
testthat::expect_true(all(colnames(ind_alg$a) == c("person", "k", "algebra_result"))) | ||
|
||
testthat::expect_error(get_individual_algebra_results(mxModel = mod2, | ||
algebra_names = "b")) | ||
|
||
model <- " | ||
xi =~ x1 + x2 + x3 | ||
eta =~ y1 + y2 + y3 | ||
eta ~ xi | ||
" | ||
mod3 <- mxsem(model = model, | ||
data = dataset) |> | ||
mxTryHard() | ||
|
||
testthat::expect_error(get_individual_algebra_results(mxModel = mod3)) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.