Dear Jeff, Many thanks for the suggestion, but I don't think tryCatch() is the answer, mainly because it causes code to stop executing when a warning is signalled:
> f <- function(w) print(w$message) > tryCatch({warning("Test"); print(3)},warning=f) [1] "Test" (The "print(3)" call is not run.) In this regard, withCallingHandlers() is preferable. But either way it is untidy, at best, to routinely put code inside one of these functions when I know I always want to handle warnings my way. If I could set an appropriate option when a package is loaded, or in an .Rprofile, then I should never need to worry about whether a bit of code might generate warnings and so should be wrapped. Regards, Jon 2009/2/4 Jeffrey Horner <jeff.hor...@vanderbilt.edu>: > Jon Clayden wrote on 02/04/2009 06:59 AM: >> >> Dear all, >> >> For an open-source project that I'm working on (1), which uses R for all >> its heavy lifting but includes a wrapper shell script, I was hoping to find >> a way to capture all warnings (and, in fact, errors too), and handle them in >> my own way. I realise I can do this for a single expression using something >> like: >> >> > f <- function(w) print(w$message) >> > withCallingHandlers(warning("Test"),warning=f) >> [1] "Test" >> Warning message: >> In withCallingHandlers(warning("Test"), warning = f) : Test >> >> But I would like to capture all warnings, globally. The >> "warning.expression" option doesn't seem to allow an argument, and I can't >> seem to use "last.warning" to get at the message either: >> >> > g <- function() print(last.warning$message) >> > options(warning.expression=quote(g())) >> > warning("Test2") >> NULL >> >> Could anyone tell me whether there's a way to do this, please? An old >> thread on this topic seemed to go unresolved (2), and I've skimmed RNEWS and >> I don't see anything about this since then. > > In fact, the thread did have the answer: tryCatch(). The help page is a bear > to read and comprehend, but if you do invest the time it should convince you > that you will want to use it. I find that I have to read and reread many > sections of R documentation before I can reconcile what I want to know with > what the authors are trying to tell me. > > I don't comprehend everything about R's condition system, but let me see if > I can convince you that you need tryCatch() to do what you want. > > Consider: > > x <- function() warning("warning message") > y <- function() call_unknown_fun() > z <- function() message('message message') > > Each of these functions signal conditions of a particular condition class: > simpleWarning, simpleError, and simpleMessage, respectively. > > w <- function(e) str(e) > > I'm going to use w to trap the simpleWarning condition: > >> tryCatch(x(),simpleWarning=w) > List of 2 > $ message: chr "warning message" > $ call : language x() > - attr(*, "class")= chr [1:3] "simpleWarning" "warning" "condition" > > So tryCatch returned a list with two elements, the message and the call that > signaled the condition. In fact the list is actually an S3 object of class > simpleWarning, which inherits from warning and condition. Reading the help > page for tryCatch(), I can actually do this: > >> tryCatch(x(),condition=w) > List of 2 > $ message: chr "warning message" > $ call : language x() > - attr(*, "class")= chr [1:3] "simpleWarning" "warning" "condition" > > since simpleWarning inherits from condition. And in fact I can use the > condition class to trap everything I want. > >> tryCatch(y(),condition=w) > List of 2 > $ message: chr "could not find function \"call_unknown_fun\"" > $ call : language y() > - attr(*, "class")= chr [1:3] "simpleError" "error" "condition" > >> tryCatch(z(),condition=w) > List of 2 > $ message: chr "message message\n" > $ call : language message("message message") > - attr(*, "class")= chr [1:3] "condition" "message" "simpleMessage" > > (Side note: is the class hierarchy actually correct for this simpleMessage > object?) > > So in summary, wrap every R expression you want to run within a single > tryCatch() call and trap all conditions with one handler for the abstract > class named 'condition'. I think that's what you want... > > Jeff > > >> >> > sessionInfo() >> R version 2.8.1 (2008-12-22) >> i386-apple-darwin8.11.1 >> >> locale: >> en_GB.UTF-8/en_US.UTF-8/C/C/en_GB.UTF-8/en_GB.UTF-8 >> >> attached base packages: >> [1] stats graphics grDevices utils datasets splines methods >> [8] base >> >> other attached packages: >> [1] tractor.session_1.0.0 tractor.base_1.0.3 tractor.nt_1.0.2 >> >> loaded via a namespace (and not attached): >> [1] tools_2.8.1 >> >> Regards, >> Jon >> >> >> (1) http://code.google.com/p/tractor/ >> (2) http://finzi.psych.upenn.edu/R/Rhelp02/archive/61872.html >> >> >> -- >> Jonathan D. Clayden, Ph.D. >> Research Fellow >> Radiology and Physics Unit >> UCL Institute of Child Health >> 30 Guilford Street >> LONDON WC1N 1EH >> United Kingdom >> >> t | +44 (0)20 7905 2708 >> f | +44 (0)20 7905 2358 >> w | www.homepages.ucl.ac.uk/~sejjjd2/ >> >> ______________________________________________ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel > > > -- > http://biostat.mc.vanderbilt.edu/JeffreyHorner > > ______________________________________________ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel