6

There seems to be little documentation about this (unless I'm looking in the wrong place!). I'm running R on the command line on Unix:

R --no-save < myfile1.r >& out1.txt

If I have several R scripts running simultaneously, do I have to put savehistory("history1.Rhistory") etc at the end of each file, or can the name of the .Rhistory file be given in the command line arguments?

I also assume that all warnings are saved in the R workspace; however, only the last 50 ever seem to be visible (There were 50 or more warnings (use warnings() to see the first 50)) - is there a way to save all warnings?

Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
ChrisW
  • 4,970
  • 7
  • 55
  • 92
  • I think you want to use Rscript instead of R for this kind of scripting – Paul Hiemstra Jan 24 '12 at 13:08
  • 2
    If you are simply running a script, surely the history will just be `source(myfile1.r)`. Why do you need to save that? – Richie Cotton Jan 24 '12 at 13:11
  • Sorry - I didn't make myself clear; I actually meant how to save the workspace, not history! That will teach me for not proofreading questions... – ChrisW Jan 24 '12 at 15:16

3 Answers3

5

I also assume that all warnings are saved in the R workspace

Nope. From ?warnings:

 It is undocumented where ‘last.warning’ is stored nor that it is
 visible, and this is subject to change.  Prior to R 2.4.0 it was
 stored in the workspace, but no longer.

Since then it has undocumentedly been stored in the variable last.warning in baseenv(), but don't rely on that to always be the case. (Also note that that variable doesn't exist if there hasn't been a warning yet.) You are supposed to access the last warnings with warnings() instead.

is there a way to save all warnings?

Not obviously. The theory is that 50 warnings is plenty to worry about at once. Read the first 50, and fix the problems or wrap the offending code in suppressWarnings if you think that the warning is erroneous, then deal with the next set.

Richie Cotton
  • 118,240
  • 47
  • 247
  • 360
3

If you do want to save all of the warnings, perhaps to an external file, you could wrap the code you are executing in a call to withCallingHandlers(). It allows you define a 'handler' for warning conditions. The handler is a function that is run each time a warning is encountered; you can use it to do pretty much anything you'd like with the warning message it is passed. (For an excellent short intro to this topic, see Martin Morgan's answer to this SO question.)

Here, I define a handler that: (a) appends the warning message to a file; and (b) uses invokeRestart() to carry on with evaluation of the function at the place where the warning was thrown. You can obviously modify this to suit your precise needs:

# DEFINE A WRAPPER FUNCTION THAT:
#    - EVALUATES A GIVEN EXPRESSION
#    - SAVES ALL WARNINGS TO A LOGFILE
saveAllWarnings <- function(expr, logFile="warning_log.R") {
    withCallingHandlers(expr, 
        warning=function(w) {
            cat(conditionMessage(w), "\n\n",  file=logFile, append=TRUE)
            invokeRestart("muffleWarning")
        })
}

# TRY IT OUT WITH A MADE UP FUNCTION THAT THROWS SEVERAL WARNINGS
messyFun <- function() {
    warning("oops")
    warning("boops")
    warning("can't I get anything right?")
    1
}

saveAllWarnings(messyFun(), logFile="messyFun warning log.R")
Community
  • 1
  • 1
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
1

This worked for me.

From rdocumentation.org:

Note that the length(last.warning) is maximally getOption("nwarnings") (at the time the warnings are generated) which is 50 by default. To increase, use something like

options(nwarnings = 10000) 

Then run your code and call the warnings function.

warnings()

It is necessary to run this line before the offending code runs. Running the original code, changing the number of warnings and calling the warnings() function will still return the default 50.

Alex W
  • 449
  • 4
  • 10