[R] How to capture console output in a numeric format

Gabor Grothendieck ggrothendieck at gmail.com
Fri Jun 24 19:23:38 CEST 2011


On Fri, Jun 24, 2011 at 11:16 AM, William Dunlap <wdunlap at tibco.com> wrote:
> Try using dput(f) instead of print(f) and
> use eval(parse(text=capture.output(...))).
>
> I would tend to use something like
>   OUTPUTS <- list()
>   fr <- function(x) {
>       on.exit(OUTPUTS[[length(OUTPUTS)+1]] <<- list(x=x,f=f))
>       ... compute and return f
>   }
> so you don't have to use capture.output.
> (You can use trace() to automate this sort
> of thing.)
>

A variation of this is to  use a proto object (or to use environments
directly at the expense of slightly more code). Below we keep all the
loose ends (i.e. aMatrix and fr) in p.  Note that p$fr automatically
fills in the first argument of fr so that the version that ultimately
gets passed to optim only has one argument, x.

fr <- function(p, x) {   ## Rosenbrock Banana function
   on.exit(p$aMatrix <- rbind(p$aMatrix,cbind(x1, x2, f)))
   x1 <- x[1]
   x2 <- x[2]
   f <- 100 * (x2 - x1 * x1)^2 + (1 - x1)^2
   f
}

library(proto)
p <- proto(fr = fr, aMatrix = NULL)
fvals <- capture.output(ans <- optim(c(-1.2,1), p$fr))
p$aMatrix

By the way, in my example using gsubfn another possibility might be to
assume that the last line of output defines the number of fields that
are to be used. That gives this which is intermediate in length
between the other two gsubfn solutions:

fr <- function(x) {   ## Rosenbrock Banana function
   on.exit(print(cbind(x1, x2, f)))
   x1 <- x[1]
   x2 <- x[2]
   f <- 100 * (x2 - x1 * x1)^2 + (1 - x1)^2
   f
}

fvals <- capture.output(ans <- optim(c(-1.2,1), fr))

library(gsubfn)
fvals.numeric <- strapply(fvals, "[-0-9]+[.][0-9]*", as.numeric)
n <- length(tail(fvals.numeric, 1)[[1]])
do.call(rbind, Filter(function(x) length(x) == n, fvals.numeric))

-- 
Statistics & Software Consulting
GKX Group, GKX Associates Inc.
tel: 1-877-GKX-GROUP
email: ggrothendieck at gmail.com



More information about the R-help mailing list