x = c(1, 39, 2982, '5', 22)
sqrt(x)Error in sqrt(x): non-numeric argument to mathematical function
Knowing you have a bug is the first step.
If you have an error message, this step is taken care of for you:
x = c(1, 39, 2982, '5', 22)
sqrt(x)Error in sqrt(x): non-numeric argument to mathematical function
However, many times there will be no error messages, you just have to figure out that something isn’t right.
range(x)[1] "1" "5"
Develop expectations about what your data should look like and check them frequently, not just at the end of your process. Use investigative functions to check your expectations.
print()head()str()View()dim()range()table()class()is.na()Unit tests are outside the scope of this workshop but you can find more information via the testthat package.
Start debugging with an empty environment. This means you have restarted R, and haven’t automatically loaded any data or restored your workspace using an .RData file. You may need to uncheck an option in your global options menu.
Run your script interactively in the console. This will help identify the line of code where any errors occur. If your bug is not accompanied by an error message, use investigative functions at each step in your script to figure at what step the problem originates.
range(x)[1] "1" "5"
str(x) chr [1:5] "1" "39" "2982" "5" "22"
In this case all of our values are strings, so R is sorting them as if they were words, not numbers.
If the bug is happening inside of a function, you have several options to troubleshoot. If you wrote the function, you can add the function call browser() inside your function. browser() opens an interactive debugging environment when called, allowing you to investigate what objects exist in the local environment of your function. It also means you can run the lines of the code inside your function interactively. If you did not write the offending function, you can use debug() to insert browser() as the first line of code of the function in question. Use undebug() to remove the
browser() function call when you are done.
For bugs where the problem is nested somewhere deep in a function that you may or may not have access to, you can use the function recover() to enter a debugging session deep in the function call rabbit hole. By setting
options(error=recover)you will trigger recover() to run any time you hit an error. This will then allow you to select the evaluation environment level at which to run a debugging session (see below).
When running knitting/rendering notebooks, Rmarkdown and quarto notebooks provide the line numbers of the entire code chunk where the error occurred instead of the exact line number of the error. If you are struggling to identify where in a notebook an error occurs and running code in the console does not trigger the error, break your longer code chunks up into shorter ones. This will narrow down the number of lines of code you need to investigate.
If you don’t have any ability work with R interactively, like in the case of a remote computing cluster, you can use the function dump.frames() to create an R object called last.dump that contains information about the evaluation environment in question. In lieu of creating an R object, you can write that information to a file as well. You can even set options=dump.frames if you want environment information every time you hit an error.
Sometimes simply locating the bug is enough to figure out how to solve it, like in the case of syntax errors. However, many times locating the bug is just the beginning…
When identifying the location of the bug is not enough to figure out how to fix it, it’s time to go looking for help.
? or help()Tips for googling:
Sometimes though, Google doesn’t doesn’t even know what you are talking about. In this case, your best option is to get proactive and ask for help. You can do this through any number of forums, including but not limited to:
Whenever you ask for help, important that you provide people all the information they need to understand the problem, but not so much information that that determining the problem becomes a slog. Enter the Reprex.
When asking your question make sure you:
sessionInfo() into your postRepr(oducible) ex(amples), are minimal of code that trigger your bug and can be run by anyone, without any specialized data or software. Many times, the act of creating a reprex will help you debug your code.
Remember to:
For more detailed guidance on asking good questions see the R Posting Guide. For tools to craft your reprex, there is a tidyverse package with the same name: reprex
Sometimes fixing the bug is trivial once you have determined the cause. Other times, there is more work to do.
try() and tryCatch()packageDescription() to find bug report locationFor more information on reporting bugs in R see the Reporting Bugs in R page on CRAN.
try() and tryCatch()stop() or warnings using warning()