How to make a log-file of an R-session which combines commands, results and warnings/messages/errors from the R-console

StackOverflow https://stackoverflow.com/questions/21307328

  •  01-10-2022
  •  | 
  •  

Question

I would like to produce a log-file which keeps track of all commands (stdin), results (stdout) and errors/warnings/messages (stderr) in the R console.

I am aware that there are a lot of logging-packages and I tried several like TeachingDemos (seems to ignore stderr completely) or R2HTML (seems to ignore messages), however, none of them seems to include everything from stderr.

Only knitr and markdown seem to be able to include everything into a single file. But using this workaround, I have to write R-scripts and I cannot freely write commands in the console.
Furthermore, I cannot include the knitr or markdown command in the same R-script (which is of course a minor problem).

Here is an example:

library(TeachingDemos)
library(R2HTML)    
library(TraMineR)

logdir <- "mylog.dir"

txtStart(file=paste(logdir,"test.txt", sep=""), commands=TRUE, 
         results=TRUE, append=FALSE)
HTMLStart(outdir = logdir, file = "test", echo=TRUE, HTMLframe=FALSE)

## Messages, warnings and errors
message("Print this message.")
warning("Beware.")
"a" + 1
geterrmessage()

## Some example application with the TraMiner package 
## which uses messages frequently
data(mvad)
mvad.seq <- seqdef(mvad[, 17:86])
mvad.ham <- seqdist(mvad.seq, method="HAM")

txtStop()
HTMLStop()
Was it helpful?

Solution

If you are running R from a Unix/Linux/Mac/etc. terminal, you can do:

R | tee mydir/mylog.txt

On windows, you can run the script in

R CMD BATCH yourscript.R

and your result will appear in the same folder as yourscript.out

OTHER TIPS

On unices, I've often used the following code idiom with bash:

Some Command 2>&1 | tee NameOfOutputFile.txt

The "2>&1" says to take stderr and redirect it to stdout, which then gets piped to "tee". I will be experimenting with this and other ways of logging an R session.

Another unix trick is the "script" command, which starts a subshell whose I/O (basically everything you type and see in return) is logged to the specified file. And then exit the shell to end the script. Again, subject to experimentation. Since "sink" is native to R, I'll be trying that first.

By the way, I picked these tricks up using solaris, but they work the same running Cygwin, the unix emulator on Windows. Long time ago, I found that my Cygwin images were more up-to-date than the institutional installations of Solaris because the administrators had much more responsibility than just keeping the Solaris up-to-date. Mind you, the institutional machines were more powerful, so even though Cygwin was way more convenient, my personal machine simply didn't fill the need.

AFTERNOTE:

I took example code from page 99 of Shumway's Time Series Analysis and Its Applications With R examples. Here are the contents of a test file palette.R:

r
plot(gnp)
acf2(gnp, 50)
gnpgr = diff(log(gnp)) # growth rate
plot(gnpgr)
acf2(gnpgr, 24)
sarima(gnpgr, 1, 0, 0) # AR(1)
sarima(gnpgr, 0, 0, 2) # MA(2)
ARMAtoMA(ar=.35, ma=0, 10) # prints psi-weights
quit("no")
exit

I invoked it using:

script < palette.R

It captures the commands from palette.R and the corresponding output. So, seems usable for batch mode. For interactive mode, I'm going to go with my original plan and use sink.

I had a similar problem and in my case, I was unable to redirect truly all the output into my log file, as it was dependent on R running in interactive mode.

Specifically, in my log file, I wanted to be able to keep track of the progress bar generated by the rjags::update() function which, however, requires interactive mode:

The progress bar is suppressed if progress.bar is "none" or NULL, if the update is less than 100 iterations, or if R is not running interactively.

Therefore, I needed to trick R into thinking that it was running interactively, while it was in fact run from a bash script (interactive_R.sh, below) using here document:

interactive_R.sh

#!/bin/bash

R --interactive << EOT

# R code starts here
print(interactive())
quit("no")
# R code ends here

EOT

(Sidenote: Make sure to avoid the $ character in your R code, as this would not be processed correctly - for example, retrieve a column from a data.frame() by using df[["X1"]] instead of df$X1.)

Then you can simply run this script and send its contents into a log file using the bash command below:

$ ./interactive_R.sh > outputFile.log 2>&1

Your log file will then look as follows:

outputFile.log

R version 4.0.2 (2020-06-22) -- "Taking Off Again"
Copyright (C) 2020 The R Foundation for Statistical Computing
Platform: x86_64-conda_cos6-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

>
> # R code starts here
> print(interactive())
[1] TRUE
> quit("no")
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top