for-loop in R

296 views
Skip to first unread message

Angelo Moretti

unread,
Apr 22, 2015, 5:45:14 AM4/22/15
to mplusau...@googlegroups.com
Hello, 

I'm doing a simulation study and I'm selecting 500 samples from a population. I'd like to run an MPlus model (two-level factor model) on these samples. I'm interested in the factor scores. Do you have any idea if the MPlus automation allows that? So, if it's possibile to run the model in the loop, and then obtain the factor scores for each sample?
Thanks.

Angelo

Joshua Wiley

unread,
Apr 22, 2015, 4:13:19 PM4/22/15
to Angelo Moretti, mplusau...@googlegroups.com
Hi Angelo,

Yes, you definitely can!  Attached is an HTML file with a complete example, some descriptions, and output.

Let me know if you have questions!

Best,

Josh



--
You received this message because you are subscribed to the Google Groups "MplusAutomation" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mplusautomati...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Joshua F. Wiley
---
Postdoctoral Research Fellow
Mary MacKillop Institute for Health Research
Australian Catholic University
---
Senior Analyst, Elkhart Group Ltd.
http://elkhartgroup.com
Office: 260.673.5518
example.html

Joshua Wiley

unread,
Apr 22, 2015, 4:14:18 PM4/22/15
to Angelo Moretti, mplusau...@googlegroups.com
P.S. That will look much prettier if you save and open it in a browser and allot all the content to run --- there's embedded code that does syntax highlighting, etc. from the rmarkdown package.

Angelo Moretti

unread,
Apr 24, 2015, 8:10:17 AM4/24/15
to mplusau...@googlegroups.com, moret...@gmail.com
Hello, thanks a lot about that. I'll have at this immediately! 

Cheers,
Angelo

Angelo Moretti

unread,
Apr 30, 2015, 7:13:52 AM4/30/15
to mplusau...@googlegroups.com, moret...@gmail.com
Hello Josh, I'm trying to work on the codes you posted (so useful! thanks about that). However, I'm experiencing some problems. This is my MPlus model:

model_a_s <- mplusObject(
  TITLE = "model_a",
  VARIABLE="CLUSTER=areas;
            ",
  ANALYSIS = "
      TYPE=twolevel;",
  MODEL = "
    %WITHIN%
       fw BY y1_a y2_a y3_a
       
       %BETWEEN%
       fb BY y1_a y2_a y3_a
    ",
  
  
  usevariables= c("ID_unit","areas","y1_a", "y2_a", "y3_a"),
  
  
  
  SAVEDATA = "
      file is scores_a_e.dat;
      save = fscores;
    ")

and I'd like to run it on 500 random samples selected from a 'population'. So my condition might be something like condition_ex<- expand.grid(Nsize=c(rep(1000,500)) ) (I'll set the seed at the beginning of the codes). 

results_ex <- lapply(1:nrow(conditions_ex), function(i) {
sampdata_ex <- population[sample(1:nrow(population), size = conditions$Nsize[i]), ]
mplusModeler(update(model_a_s, rdata = sampdata_ex),
             dataout = paste0("run_sample_", i, ".dat"),
             run = 1)
})

In that I've the warning 'In runModels(filefilter = modelout) :
                                      Mplus returned error code: 1, for model:'    
                                      The file ‘run_sample_(file number).dat’ currently exists and will be overwritten.
I don't know what's going on - maybe I'm making some mistakes. Do you have any idea about that kind of error?

I've tried to use a if-loop but I've an error related to the number of dimension in my rdata. 

Thanks.

Cheers,
Angelo

Joshua Wiley

unread,
Apr 30, 2015, 10:06:54 PM4/30/15
to Angelo Moretti, mplusau...@googlegroups.com
Hi Angelo,

Hmm, I'm not quite sure --- you seem to generally be on the right track.  The below worked for me.  If you're still having trouble, perhaps you could forward your code to me (either on list or privately)?

Cheers,

Josh


#######################################################
library(MplusAutomation)

# simulation stuff start
library(MASS)
set.seed(1234)
rmat.w <- matrix(.7, ncol = 3, nrow = 3)
diag(rmat.w) <- 1

rmat.b <- matrix(.4, ncol = 3, nrow = 3)
diag(rmat.b) <- 1

# 500 subjects
pop.b <- mvrnorm(n = 500, mu = c(0, 0, 0), Sigma = rmat.b)
# 20 observations each
pop.all <- do.call(rbind, lapply(1:nrow(pop.b), function(i) {
                                       cbind(i, mvrnorm(n = 20, mu = c(0, 0, 0), Sigma = rmat.w) +
                                         do.call(rbind, rep(list(pop.b[i, ]), 20)))
                                     }))
colnames(pop.all) <- c("areas", "y1_a", "y2_a", "y3_a")

population <- as.data.frame(pop.all)
# simulation stuff end

model_a_s <- mplusObject(
  TITLE = "model_a",
  VARIABLE="CLUSTER=areas;
            ",
  ANALYSIS = "
      TYPE=twolevel;",
  MODEL = "
    %WITHIN%
       fw BY y1_a y2_a y3_a;

       %BETWEEN%
       fb BY y1_a y2_a y3_a;
    ",
  usevariables= c("areas","y1_a", "y2_a", "y3_a"),
  rdata = population,
  SAVEDATA = "
      file is scores_a_e.dat;
      save = fscores;
    ")

conditions <- expand.grid(Nsize=c(rep(1000,500)))

results_ex <- lapply(1:2, function(i) {
  sampdata_ex <- population[sample(1:nrow(population), size = conditions$Nsize[i]), ]
  mplusModeler(update(model_a_s, rdata = sampdata_ex),
             dataout = paste0("run_sample_", i, ".dat"),
             run = 1)
})

SummaryTable(results_ex,
             keepCols = c("Title", "LL", "Parameters", "AIC", "BIC", "SRMR.Within", "SRMR.Between"))

##      Title        LL Parameters      AIC      BIC SRMR.Within SRMR.Between
## 1  model_a -4322.903         15 8675.807 8749.423           0            0
## 2  model_a -4371.830         15 8773.660 8847.276           0            0
#######################################################


Yannick Diehl

unread,
Nov 4, 2021, 11:49:46 AM11/4/21
to MplusAutomation
Hey,

I have a similar question. However, my data is based on cross-sectional data, which I have saved in a list after years using group_split () - 'splitData'. In the second step I created an mplusObject and would like to run this over the 12 dataframes in the list. Since they are cross-sectional data, they logically do not have the same length. As a result, the option of multiple imputation is excluded. (?) Unfortunately, my code for the for-loop doesn't work either ... Does anyone have an idea? If this approach doesn't work, is there a way to iterate over all .dat files in a folder with just one mplusObject? The data files can be easily created using prepareMplusData.

library(tidyverse)

splitData <- df %>% 
  group_split(year) 

modelObject  <- mplusObject(
  TITLE = "CFA;", 
  ANALYSIS = "estimator = mlr; ",
  VARIABLE = "weight = wt;",
  MODEL = "
    factor BY v1 v2 v3 v4;
    ",
  
  OUTPUT = "TECH1 STDYX;",
  usevariables = c("v1", "v2", "v3", "v4", "wt"))

modelResults <- lapply(1:12, function(i) {
  mplusModeler(update(modelObject, rdata = splitData),
               dataout = paste0("test", i, ".dat"),
               modelout = paste0("test", i, ".inp"),
               run = 1, hashfilename = F, writeData = "always")
})

---

prepareMplusData(splitData, filename =  ".dat",
                 writeData = "ifmissing", hashfilename=F,
                 imputed = TRUE, keepCols = c("v1", "v2", "v3", "v4", "wt"))


cheers,

Yannick

michael.hallquist

unread,
Nov 4, 2021, 4:52:20 PM11/4/21
to MplusAutomation
Hi Yannick,

Without seeing the specific problems in your case, I may be off-base. But your code looks close to me. Don't you just need rdata = splitData[[i]] ? This would then pull in the ith data frame for each iteration, while your current code sends in the whole list. If that doesn't work, feel free to send data and syntax (direct email to me and/or Josh is fine).

Best,
Michael
Reply all
Reply to author
Forward
Message has been deleted
0 new messages