Error handling in R - Debugging with RStudio Part 2


After the first part covers the different ways to activate the debugger, the second part focuses on efficient debugging.
„Debugging is like being the detective in a crime movie where you are also the murderer.”(1)
... and sometimes you don’t even remember committing the act.
In the following, we will explore the debugging features of RStudio using a simple example. The following functions are supposed to reverse the letters of individual words but not the entire sentence.
# drehe ein Wort um
stringrev <- function(str) {
vec <- strsplit(str, "")
vec <- rev(unlist(vec))
paste(vec, collapse = "")
}
# trenne einen Satz in einzelne Woerter
crazify <- function(str) {
vec <- strsplit(str, " ")
vec <- lapply(unlist(vec), stringrev)
paste(vec, collapse = " ")
}
For single sentences, the code works without any issues. Building on that, we want to apply the function to a passage from another blog post, which is stored in a data frame.
test_it <- function() {
sentences <- data.frame(
titles = c("first", "second"),
text = c("Bokaj, der beste Ingenieur im nicht-parametrischen
Universum und glücklicherweise Leiter unseres
Maschinenraums, hat eine Idee!",
"Wir demontieren von einem der anderen Schiffe den
Antrieb und verstärken damit unseren."))
sentences$text <- vapply(sentences$text, crazify, "character")
return(sentences)
}
However, this error message appears:
Error in strsplit(str, " ") : non-character
argument
To get to the bottom of this error message, we enable the "Debugging on Error" option, as explained in the previous blog post.
The first thing you notice is that the appearance of RStudio changes as soon as you enter debugging mode.
Environment-Pane

Normally, the Environment pane displays the global objects. However, when in debugging mode, it instead shows the objects within the environment of the respective function. Above the list of objects, there is a dropdown menu that allows switching between different environments. If variables are grayed out, it means they are objects that are not yet present in the environment but will be available to the function in the future.
Traceback

The traceback contains all the functions that were called to reach the current function that caused the error. This window also allows switching between previous function calls, which in turn updates the displayed code and the objects shown in the environment. However, it is important to note that this does not change the current environment. At the bottom of the list is the first function that was called, which in our case is test_it(),
and it continues up to crazify()
, which calls the R function strsplit().
Konsole

In debugging mode, there are two prominent changes to the console. First, the input now shows
Browse[1]>
This indicates that you are in R’s environment browser. For the most part, the console behaves like the normal console in debugging mode, with a few exceptions:
- Objects are evaluated based on the current environment. For example, the text data frame is displayed when you enter
x
, and it is also possible to assign a new value tox
. - Pressing the Enter key executes the current statement and moves to the next one. This allows for conveniently stepping through the code one step at a time.
- A variety of debugging functions are available, which will be covered in more detail later.
The second major change in the console is the function bar located above it. This provides practical buttons to send specific debugging functions directly to the R console. There is no difference between entering the commands manually in the R console or using the buttons. The buttons, from left to right, correspond to the following console commands:
To switch the current environment, use the recover()
function. This lists the environments of the previously called functions. From this list, you can select the appropriate environment.
Error Detection
But where is the error in our example? In the Environment pane, we can see that x
, which is passed to the strsplit()
function, is a factor rather than a character. This is because the default setting for data.frame
is stringsAsFactors = default.stringsAsFactors()
. If we add stringsAsFactors = FALSE
to the test_it
function in our original code block, we can see that the function runs successfully and produces the desired result.

References
- https://twitter.com/fortes/status/399339918213652480
- Introduction to Debugging in R
- https://github.com/rstudio/webinars/tree/master/15-RStudio-essentials/2-Debugging