Rmarkdown chunk code resulting in too many errors in console (I want to see them, just not all of them printed to the console) - console

I am running a piece of a chunk of code (i.e., I'm not just clicking "Run" for the entire chunk) in an RMarkdown document. Normally, when I run this code in a normal script (which reads in a large dataset), the console indicates there are warnings, and gives me the option to see the first 50 by running the command
warnings()
However, when running this same code in RMarkdown, the console prints every single one of the warnings in the console. I want to know there are warnings and be able to quickly review the first 50 of them, but I don't want the console to print all of them.
Please note, I am aware of the
warning = FALSE
argument in knitr::opts_chunk$set() command. This is not helpful in my situation because I want to see that there are warnings and quickly preview them; I just don't want the console to print *all *of them.
I double checked my warning settings using
getOption("nwarnings")
and the result was 50. However, the console is printing way more than 50 warnings when I run this piece of the code chunk.

Related

How to increase amount of output retained by R console

I'm struggling with how much output is retained in RStudio's console. An MWE would be:
for(i in 1:2000){print(i)}
Of the 2,000 printed iterations, only 1,000 lines are retained in the RStudio console. In other words, scrolling up all the way to the top of the RStudio console, the output is truncated at a printed i of 1001.
To emphasize: these are separate instances of printing to the console, so this has nothing to do with the "max.print" option (which we set to options(max.print=100000) anyway). This is solely about the number of lines retained by RStudio's console, or put differently, the absolute "height" of the console.
This is not an issue when running R through a terminal.
Is someone aware of an RStudio option to increase the amount of lines retained in its console? The RStudio options "Limit output line length" and "Limit visible console output" in Tools > Global Options > Console do not influence this behavior.
Thanks and best,
Chris
you can use rstudioapi::writeRStudioPreference("console_max_lines", <<Number of Lines>>).
<<Number of Lines>> needs to be and Integer so 2000L not 2000.
Then restart RStudio and it will be updated. Be cautious though, this can slow down RStudio a lot for large values.

How to make RStudio stop when meeting error or warning

When I select several lines of codes in a R script, and run it, RStudio will "smoothly" run all of the codes, even though there are some warnings and errors in the middle part. As a result, I have to carefully check the "Console" window, and to see whether there is any red lines. This is really time consuming and I may miss the errors. Are there some ways to make the running stop, when error or warning occurs?
RStudio currently works by pasting the selected text into the console. It doesn't care if there are errors in it. A better approach would be to get the text and source it.
You can get the selected text using
selected <- rstudioapi::getSourceEditorContext()$selection[[1]]$text
If you source this text instead of pasting it, it will stop at the first error. Do that using
source(exprs = parse(text = selected), echo = TRUE)
Another way to go would be to copy the text into the clipboard, then sourcing it from there. I don't think RStudio currently has a way to do that, but you can add one.
This function reads from the clipboard on Windows and MacOS; I'm not sure if pbpaste is generally available on Linux, but there should be some equivalent there:
readClipboard <- function() {
if (.Platform$OS.type == "windows")
lines <- readLines("clipboard")
else
lines <- system("pbpaste", intern=TRUE)
lines
}
This code sources the text from the clipboard:
source(exprs = parse(text = readClipboard()), echo = TRUE)
You could put either of these actions on a hot key in RStudio as an add-in. Instructions are here: https://rstudio.github.io/rstudioaddins/.
The advice above only stops on errors. If you want to also stop on warnings, use options(warn = 2) as #FransRodenburg said.
There are many ways you can force your script to stop when you encounter an error:
Save your script and run it using source(yourscript.R);
Wrap your script in a function and try and use the function;
Work in an Rmarkdown file and try and execute a chunk containing all the code you want to run (or try knitting for that matter);
If you really want to stop your script when a warning occurs, you could force warnings to be errors by using options(warn = 2) at the beginning of your script. If you just want to get rid of the red (lol), you can also suppress harmless warnings you have already checked using suppressWarnings(), or suppress all warnings for your script with options(warn = -1).
Be careful using options() outside a saved script though, lest you forget you have globally disabled warnings, or turned them into errors.
Depending on how large your script is, you may also just want to run it bit by bit using CTRL+Enter, rather than selecting lines.

I have suppressed warnings in knitr output but the warnings do not show up in the Rmarkdown console as expected. How do I view these?

I am using Knitr and rmarkdown. I have suppressed warnings in the .pdf output and then typically the warnings are listed in the rmarkdown console. However, in the case of one specific report, instead of getting the warnings listed in the rmarkdown console, I get this message: There were 15 warnings (use warnings() to see them). Where do I write this warnings() code to see the list of warnings?
I have tried adding warnings() at the bottom of my rmarkdown document but the output is: NULL.
If you are using an .rmd file, you will need to knit that file through an r script to produce the errors in the console, becuase .rmd files use unique consoles for each R call. Try this:
setwd("C:/blah/blah")
knitr::knit("blah.Rmd")
warnings()
If you type warnings() in the console it will show you that last 15. The console in this environment works predominately the same way that it does in a script. Anything you type is run line, by line, but you are working in the same global environment.

How to request an early exit when knitting an Rmd document?

Let's say you have an R markdown document that will not render cleanly.
I know you can set the knitr chunk option error to TRUE to request that evaluation continue, even in the presence of errors. You can do this for an individual chunk via error = TRUE or in a more global way via knitr::opts_chunk$set(error = TRUE).
But sometimes there are errors that are still fatal to the knitting process. Two examples I've recently encountered: trying to unlink() the current working directory (oops!) and calling rstudioapi::getVersion() from inline R code when RStudio is not available. Is there a general description of these sorts of errors, i.e. the ones beyond the reach of error = TRUE? Is there a way to tolerate errors in inline R code vs in chunks?
Also, are there more official ways to halt knitting early or to automate debugging in this situation?
To exit early from the knitting process, you may use the function knitr::knit_exit() anywhere in the source document (in a code chunk or inline expression). Once knit_exit() is called, knitr will ignore all the rest of the document and write out the results it has collected so far.
There is no way to tolerate errors in inline R code at the moment. You need to make sure inline R code always runs without errors1. If errors do occur, you should see the range of lines that produced the error from the knitr log in the console, of the form Quitting from lines x1-x2 (filename.Rmd). Then you can go to the file filename.Rmd and see what is wrong with the lines from x1 to x2. Same thing applies to code chunks with the chunk option error = FALSE.
Beyond the types of errors mentioned above, it may be tricky to find the source of the problem. For example, when you unintentionally unlink() the current directory, it should not stop the knitting process, because unlink() succeeded anyway. You may run into problems after the knitting process, e.g., LaTeX/HTML cannot find the output figure files. In this case, you can try to apply knit_exit() to all code chunks in the document one by one. One way to achieve this is to set up a chunk hook to run knit_exit() after a certain chunk. Below is an example of using linear search (you can improve it by using bisection instead):
#' Render an input document chunk by chunk until an error occurs
#'
#' #param input the input filename (an Rmd file in this example)
#' #param compile a function to compile the input file, e.g. knitr::knit, or
#' rmarkdown::render
knit_debug = function(input, compile = knitr::knit) {
library(knitr)
lines = readLines(input)
chunk = grep(all_patterns$md$chunk.begin, lines) # line number of chunk headers
knit_hooks$set(debug = function(before) {
if (!before) {
chunk_current <<- chunk_current + 1
if (chunk_current >= chunk_num) knit_exit()
}
})
opts_chunk$set(debug = TRUE)
# try to exit after the i-th chunk and see which chunk introduced the error
for (chunk_num in seq_along(chunk)) {
chunk_current = 0 # a chunk counter, incremented after each chunk
res = try(compile(input))
if (inherits(res, 'try-error')) {
message('The first error came from line ', chunk[chunk_num])
break
}
}
}
This is by design. I think it is a good idea to have error = TRUE for code chunks, since sometimes we want to show errors, for example, for teaching purposes. However, if I allow errors for inline code as well, authors may fail to recognize fatal errors in the inline code. Inline code is normally used to embed values inline, and I don't think it makes much sense if an inline value is an error. Imagine a sentence in a report like The P-value of my test is ERROR, and if knitr didn't signal the error, it will require the authors to read the report output very carefully to spot this issue. I think it is a bad idea to have to rely on human eyes to find such mistakes.
IMHO, difficulty debugging an Rmd document is a warning that something is wrong. I have a rule of thumb: Do the heavy lifting outside the Rmd. Do rendering inside the Rmd, and only rendering. That keeps the Rmd code simple.
My large R programs look like this.
data <- loadData()
analytics <- doAnalytics(data)
rmarkdown::render("theDoc.Rmd", envir=analytics)
(Here, doAnalytics returns a list or environment. That list or environment gets passed to the Rmd document via the envir parameter, making the results of the analytics computations available inside the document.)
The doAnalytics function does the complicated calculations. I can debug it using the regular tools, and I can easily check its output. By the time I call rmarkdown::render, I know the hard stuff is working correctly. The Rmd code is just "print this" and "format that", easy to debug.
This division of responsibility has served me well, and I can recommend it. Especially compared to the mind-bending task of debugging complicated calculations buried inside a dynamically rendered document.

Extract what was printed deep in the R console

When I execute commands in R, the output is printed in the console. After some threshold (I guess, some maximum number of lines), the R console no longer shows the first commands and their output. I cannot scroll up that far because it is simply no longer there.
How can I access this "early" output if it has disappeared from the console?
I care mostly about error messages and messages generated by my own script. I do use a script file and save my results to a file, if anyone wonders, but this still does not help solve my problem.
(I have tried saving the R workspace and R history and then loading it again, but did not know what to do next and was not able to find what I needed...)

Resources