From 111f13be7e4835a9284bfd1ad63d97ed7e7ba8d3 Mon Sep 17 00:00:00 2001 From: kss2k Date: Thu, 25 Jun 2026 19:13:07 +0200 Subject: [PATCH] Give Mplus files unique IDs, and add optional cleanup --- R/modsem_mplus.R | 70 ++++++++++++++++++++++++++++++++++++++----- R/utils.R | 6 ++++ man/modsem-package.Rd | 5 ---- man/modsem_mplus.Rd | 5 ++++ 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/R/modsem_mplus.R b/R/modsem_mplus.R index c68d19c9..bc15bced 100644 --- a/R/modsem_mplus.R +++ b/R/modsem_mplus.R @@ -23,6 +23,10 @@ #' #' @param output.std Should \code{STANDARDIZED} be added to \code{OUTPUT}? #' +#' @param cleanup Should the \code{Mplus} files (\code{.inp}, \code{.dat} and \code{.out}) +#' created during estimation be deleted when \code{modsem_mplus()} exits? Default is +#' \code{FALSE}, meaning the files are kept in the working directory. +#' #' @param ... arguments passed to other functions #' #' @return modsem_mplus object @@ -64,6 +68,7 @@ modsem_mplus <- function(model.syntax, rcs.scale.corrected = TRUE, output.std = TRUE, categorical = NULL, + cleanup = FALSE, ...) { if (!requireNamespace("MplusAutomation", quietly = TRUE)) stop("modsem_mplus() requires the 'MplusAutomation' package; please install it.") @@ -172,15 +177,26 @@ modsem_mplus <- function(model.syntax, rdata = data[usevariables], ) - results <- MplusAutomation::mplusModeler(model, - modelout = "mplusResults.inp", - run = 1L) + fprefix <- getMplusFilePrefix() + if (cleanup) + on.exit(cleanupMplusFiles(fprefix), add = TRUE) + + results <- MplusAutomation::mplusModeler( + model, + modelout = paste0(fprefix, ".inp"), + run = 1L, + writeData = "always", + hashfilename = FALSE + ) + coefsTable <- coef(results) - mplusParTable <- mplusTableToParTable(coefsTable, - intTerms = intTerms, - intTermsMplus = intTermsMplus, - indicators = indicators, - parTable.in = parTable) + mplusParTable <- mplusTableToParTable( + coefsTable, + intTerms = intTerms, + intTermsMplus = intTermsMplus, + indicators = indicators, + parTable.in = parTable + ) # coef and vcov TECH1 <- MplusAutomation::get_results(results, element = "tech1") @@ -693,3 +709,41 @@ cbind0 <- function(...) { cbind(...) } + + +mplusFilePrefixExists <- function(fprefix) { + inp <- paste0(fprefix, ".inp") + dat <- paste0(fprefix, ".dat") + out <- paste0(fprefix, ".out") + file.exists(inp) || file.exists(dat) || file.exists(out) +} + + +cleanupMplusFiles <- function(fprefix) { + files <- paste0(fprefix, c(".inp", ".dat", ".out")) + unlink(files[file.exists(files)]) +} + + +getMplusFilePrefix <- function(max.iter = 20) { + randid <- generateRandomCharId(n=12) + fprefix <- paste0("mplusResults", randid) + + if (!mplusFilePrefixExists(fprefix)) + return(fprefix) + + for (i in seq_len(max.iter)) { + id <- generateRandomCharId(2) + fprefix <- paste0(fprefix, id) + + if (!mplusFilePrefixExists(fprefix)) + return(fprefix) + } + + mod_msg_warn( + "Unable to create a unique name for Mplus files!", + "Previous results might get overwritten..." + ) + + fprefix +} diff --git a/R/utils.R b/R/utils.R index 89768740..bedf3c0f 100644 --- a/R/utils.R +++ b/R/utils.R @@ -848,3 +848,9 @@ std1 <- function(v) { (v - mu) / sigma } + + +generateRandomCharId <- function(n = 36) { + chars <- c(letters, LETTERS, as.character(0:9)) + paste0(sample(chars, size = n, replace = TRUE), collapse = "") +} diff --git a/man/modsem-package.Rd b/man/modsem-package.Rd index a6d36e14..684c0ed3 100644 --- a/man/modsem-package.Rd +++ b/man/modsem-package.Rd @@ -18,11 +18,6 @@ Useful links: \author{ \strong{Maintainer}: Kjell Solem Slupphaug \email{slupphaugkjell@gmail.com} (\href{https://orcid.org/0009-0005-8324-2834}{ORCID}) -Authors: -\itemize{ - \item Kjell Solem Slupphaug \email{slupphaugkjell@gmail.com} (\href{https://orcid.org/0009-0005-8324-2834}{ORCID}) -} - Other contributors: \itemize{ \item Mehmet Mehmetoglu \email{mehmetm@ntnu.no} (\href{https://orcid.org/0000-0002-6092-8551}{ORCID}) [contributor] diff --git a/man/modsem_mplus.Rd b/man/modsem_mplus.Rd index 0bdc8f63..4d6d9566 100644 --- a/man/modsem_mplus.Rd +++ b/man/modsem_mplus.Rd @@ -18,6 +18,7 @@ modsem_mplus( rcs.scale.corrected = TRUE, output.std = TRUE, categorical = NULL, + cleanup = FALSE, ... ) } @@ -53,6 +54,10 @@ the items. Default is \code{TRUE}.} \item{categorical}{categorical argument passed to \code{Mplus}.} +\item{cleanup}{Should the \code{Mplus} files (\code{.inp}, \code{.dat} and \code{.out}) +created during estimation be deleted when \code{modsem_mplus()} exits? Default is +\code{FALSE}, meaning the files are kept in the working directory.} + \item{...}{arguments passed to other functions} } \value{