Adrian
Adrian

Reputation: 9803

R: how to store message from verbose = TRUE

library(nlme)
fm1 <- nlme(height ~ SSasymp(age, Asym, R0, lrc),
              data = Loblolly,
              fixed = Asym + R0 + lrc ~ 1,
              random = Asym ~ 1,
              start = c(Asym = 103, R0 = -8.5, lrc = -3.3), verbose = TRUE)

# **Iteration 1
# LME step: Loglik: -114.787, nlminb iterations: 1
# reStruct  parameters:
#      Seed 
# -1.669062 
# PNLS step: RSS =  43.40812 
#  fixed effects: 101.4496  -8.627331  -3.233751  
#  iterations: 4 
# Convergence crit. (must all become <= tolerance = 1e-05):
#      fixed   reStruct 
# 0.02048682 0.02712258 
# 
# **Iteration 2
# LME step: Loglik: -114.7428, nlminb iterations: 1
# reStruct  parameters:
#      Seed 
# -1.624988 
# PNLS step: RSS =  43.40812 
#  fixed effects: 101.4496  -8.627331  -3.233751  
#  iterations: 1 
# Convergence crit. (must all become <= tolerance = 1e-05):
#    fixed reStruct 
#        0        0 

In particular, I am referring to the nlme function call, but I think the solution will be generalizable to other verbose = TRUE generated outputs. Essentially, I would like to store the verbose text (starting from **Iteration 1). Is there any way to do this in R?

Edit: Gregor de Cilla's answer works great for the above example (where algorithm converged). What if the algorithm didn't converge?

u2 = evaluate({
fm2 <- nlme(height ~ SSasymp(age, Asym, R0, lrc),
            data = Loblolly,
            fixed = Asym + R0 + lrc ~ 1,
            random = Asym ~ 1,
            start = c(Asym = 103, R0 = -10, lrc = -8), verbose = TRUE)
})
> cat(u2[[2]])
# Error in cat(u2[[2]]) : object 'u2' not found

Upvotes: 1

Views: 1300

Answers (2)

Gregor de Cillia
Gregor de Cillia

Reputation: 7685

The evaluate package is handy for such tasks. Here is an Example

library(evaluate)
library(nlme)

u = evaluate({
  fm1 <- nlme(height ~ SSasymp(age, Asym, R0, lrc),
              data = Loblolly,
              fixed = Asym + R0 + lrc ~ 1,
              random = Asym ~ 1,
              start = c(Asym = 103, R0 = -8.5, lrc = -3.3), verbose = TRUE)
})

# get the output in character form
output_str = u[[2]]

# check if everything worked
cat(output_str)

If you want better control over which kind of outputs are saved, take a look at the evaluate::new_output_handler documentation.

In case of errors, wrapping your expression inside a function is advisable

u2 = evaluate({
  function(){
    fm2 <- nlme(height ~ SSasymp(age, Asym, R0, lrc), data = Loblolly, 
                fixed = Asym + R0 + lrc ~ 1, 
                random = Asym ~ 1, 
                start = c(Asym = 103, R0 = -10, lrc = -8), 
                verbose = TRUE)
  }
})

The error messages can then be captured from u2[[3]].

EDIT: Since you asked, running this will show how the new_output_handler function works

my_output_handler = new_output_handler(
  error = function(x) {
    cat("source_prefix:", as.character(x))
  }
)

u2 = evaluate({
  function(){
    fm2 <- nlme(height ~ SSasymp(age, Asym, R0, lrc), data = Loblolly, 
                fixed = Asym + R0 + lrc ~ 1, 
                random = Asym ~ 1, 
                start = c(Asym = 103, R0 = -10, lrc = -8), 
                verbose = TRUE)
  }
}, output_handler = my_output_handler)

replay(u2)

Upvotes: 1

Ajay Ohri
Ajay Ohri

Reputation: 3492

To send output back to the console: sink() for output and sink(type = "message") for stderr. See examples in ? sink.

see How to capture RCurl verbose output

Upvotes: 0

Related Questions