4.11 Troubleshooting and Debugging

Bugs in code are normal. You are not a bad programmer if your code has bugs (thank goodness!). However, some bugs can be very difficult to fix, and some are even difficult to find. You will spend a substantial amount of time debugging your code in R, especially as you are learning the language and its many quirks. You will encounter R error and warning messages routinely during development, and not all of them are straightforward to understand. It is important that you learn how to seek the answers to the problems R reports on your own; your colleagues (and instructors!) will thank you for it.

There is no standard approach to debugging, but here we borrow ideas from Hadley Wickam’s excellent section on debugging in his Advanced R book:

  1. Google! - copy and paste the error into google and see what comes back. Especially when starting out, the errors you receive have been encountered countless times by others before you, and solutions/explanations of them are already out there. If you aren’t already familiar with Stack Overflow, you will be very soon.
  2. Make it repeatable - When you encounter an error, don’t change anything in your code and try again to make sure you get the same error again. This may require you to isolate the code with the error in a different setting to make it more easy to run. If you do, this means the error is repeatable, or replicable, and you can now try modifying the code in question to see if and how the error changes.
  3. Find out where the bug is* - Most bugs involve multiple lines of code, only a subset of which contains the actual error. Sometimes the exact line where the error occurs is obvious, but other times the error is a consequence of a mistake assumption made earlier in the code.
  4. Fix it and test it - When you have identified the specific issue causing the bug, modify the code so it produces the correct result and then rigorously test your fix to make sure it is correct. Sometimes making one change to code causes side effects elsewhere in your code in ways that are difficult to predict. Ideally, you have already written unit tests that explicitly test parts of your code, but if not you will need to use other means of convincing yourself that your fix worked.

This debugging process will become second nature as you work more in R.

Practically speaking, the most basic debugging method is to run code that isn’t working the way it should, print out intermediate results to inspect the state of your variables, and make adjustments accordingly. In RStudio, the Environment Inspector in the top right of the interface makes inspecting the current values of your variables very easy. You can also easily execute lines of code from your script in the interpreter at the bottom right using Cntl-Enter and test out modifications there.

Sometimes you will be working with highly nested data structures like lists of lists. These objects can be difficult to inspect due to their size. The str() function, which stands for structure, will pretty print an object with its values and its structure:

nested_lists <- list(
  a=list(
      item1=c(1,2,3),
      item2=c('A','B','C')
  ),
  b=list(
      var1=1:10,
      var2=100:110,
      var3=1000:1010
  ),  
  c=c(10,9,8,7,6,5)
)
nested_lists
$a
$a$item1
[1] 1 2 3

$a$item2
[1] "A" "B" "C"


$b
$b$var1
 [1]  1  2  3  4  5  6  7  8  9 10

$b$var2
 [1] 100 101 102 103 104 105 106 107 108 109 110

$b$var3
 [1] 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
str(nested_lists)
List of 3
 $ a:List of 2
  ..$ item1: num [1:3] 1 2 3
  ..$ item2: chr [1:3] "A" "B" "C"
 $ b:List of 3
  ..$ var1: int [1:10] 1 2 3 4 5 6 7 8 9 10
  ..$ var2: int [1:11] 100 101 102 103 104 105 106 107 108 109 ...
  ..$ var3: int [1:11] 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ...
 $ c: num [1:6] 10 9 8 7 6 5

The output str is more concise and descriptive than simply printing out the object.

RStudio has many more debugging tools you can use. Check out the section on debugging in Hadley Wickam’s Advanced R book in the Read More box for description of these tools.