wooden05
wooden05

Reputation: 195

Creating an if statement/loop that re-runs multiple lines of codes based on whether a line generates a warning message

I have the following chunk of code that generates, edits, and runs several Mplus input files. Here's what I want to do: if runModels(filenames) at line 13 returns an error, I would like to re-run lines 1-11 (as many time as it takes) until runModels(filenames) does not return a warning message (I stated error originally, I meant warning message). Would appreciate any help.

1 aMNLFA.sample(ob)
2 aMNLFA.initial(ob) 
3 line <- "[IBR14$1-IBR14$8];
4 [IBR21$1-IBR21$8];
5 [IBR25$1-IBR25$4];"
6 filenames = list("meanimpactscript.inp", "varimpactscript.inp", "measinvarscript_IBR14.inp", "measinvarscript_IBR21.inp", "measinvarscript_IBR25.inp")
7 for (i in filenames) {
8          txt <- readLines(i)
9          ix <- grep("ETA BY IBR25", txt) 
10         p <- paste(append(txt, line, ix), collapse = "\n")
11         writeLines(p, con=i)}
12
13 #run models in directory
13 runModels(filenames)

Upvotes: 1

Views: 35

Answers (1)

one
one

Reputation: 3902

Use tryCatch to capture error

go <- T

while(go){
  test <- tryCatch({aMNLFA.sample(ob)
    aMNLFA.initial(ob) 
    line <- "[IBR14$1-IBR14$8];
[IBR21$1-IBR21$8];
[IBR25$1-IBR25$4];"
    filenames = list("meanimpactscript.inp", "varimpactscript.inp", "measinvarscript_IBR14.inp", "measinvarscript_IBR21.inp", "measinvarscript_IBR25.inp")
    for (i in filenames) {
      txt <- readLines(i)
      ix <- grep("ETA BY IBR25", txt) 
      p <- paste(append(txt, line, ix), collapse = "\n")
      writeLines(p, con=i)}
    
    runModels(filenames)
    }, warning= function(w) return("repeat"))
  
  if(typeof(test)!="character"){
    go <- F
  }else{
    if(test!="repeat"){
      go <- F
    }
  }
}

runModels(filenames)

Reproducible example:

testfunc <- function(x){
  if(x!=10){
    warning("not 10")
  }
  return(x)
}

go <- T
count=0

while(go){
  test <- tryCatch({
  count=count+1
  testfunc(count)
  }, warning= function(w) return("repeat"))
  
  if(typeof(test)!="character"){
    go <- F
  }else{
    if(test!="repeat"){
      go <- F
    }
  }
}

> count
[1] 10
> test
[1] 10

Upvotes: 1

Related Questions