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

Gabor Grothendieck ggrothendieck at gmail.com
Fri Jun 24 18:12:29 CEST 2011


On Fri, Jun 24, 2011 at 11:10 AM, Ravi Varadhan <rvaradhan at jhmi.edu> wrote:
> Thank you very much, Jim.  That works!
>
> I did know that I could process the character strings using regex, but was also wondering if there was a direct way to get this.
>
> Suppose, in the current example I would like to obtain a 3-column matrix that contains the parameters and the function value:
>
> 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))
>
> Now, I need to tweak your solution to get the 3-column matrix.  It would be nice, if there was a more direct way to get the numerical output, perhaps a numeric option in capture.output().
>

This works in general assuming that we only wish to keep those output
lines having the same number of numerics as the most frequently output
length, i.e. 3 in your example above and 1 in the original example.
Also it does not require modification of the function to be optimized.

The first line extracts all numerics that have a decimal in them (so
that, for example, the 1 in [1] is not extracted).  The next two lines
count how many numbers are in each extracted line and returns the most
frequently occurring non-zero length as n so that n is 3 here.  The
final line extracts those lines and rbind's them. fvals is from your
post.

library(gsubfn)
fvals.numeric <- strapply(fvals, "[-0-9]+[.][0-9]*", as.numeric)
tab <- table(sapply(fvals.numeric, length))
n <- as.numeric(names(which.max(tab[names(tab) > 0])))
do.call(rbind, Filter(function(x) length(x) == n, fvals.numeric))

If we knew in advance that we wanted only lines with 3 numbers and
that those three numbers are each prefaced by a space (both of which
are the case in your example) then we could simplify it to just this:

library(gsubfn)
fvals.numeric <- strapply(fvals, " [-0-9.]+", as.numeric)
do.call(rbind, fn$Filter(x ~ length(x) == 3, fvals.numeric))

There is more on strapply and fn$ at http://gsubfn.googlecode.com

-- 
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