Debugging With the Superassignment Operator

I show here how the <<- assignment operator may be used to debug R functions by writing local variables into the global environment.

Consider the following code:

PlotExponentialSmoother <- function(x){
   exp.smoother  <- HoltWinters(x, beta=FALSE, gamma=FALSE)
   plot.subtitle <- paste("Sum of Squared Errors:", exp.smoother$sse)
   plot(exp.smoother, sub=plot.subtitle)
}

PlotExponentialSmoother(window(sunspots, 1950))

Running that code produces a graph of sunspot activity since 1950 and an exponential smoother of those data. But there's a problem: The graph subtitle doesn't come out properly.

My guess is that this is because exp.smoother$sse is a non-existent variable. In order to verify that, I want to have a look at exp.smoother. Trouble is, that variable is local to PlotExponentialSmoother().

So I use the <<- operator to write to the global environment from within the PlotExponentialSmoother() function:

PlotExponentialSmoother <- function(x){
   exp.smoother  <- HoltWinters(x, beta=FALSE, gamma=FALSE)
es <<- exp.smoother
   plot.subtitle <- paste("Sum of Squared Errors:", exp.smoother$sse)
   plot(exp.smoother, sub=plot.subtitle)
}

PlotExponentialSmoother(window(sunspots, 1950))

Having run that code, I can access that variable from my workspace:

> str(es)
List of 9
$ fitted      : mts [1:407, 1:2] 101.6 97.7 104.6 109.7 107.7 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr [1:2] "xhat" "level"
  ..- attr(*, "tsp")= num [1:3] 1950 1984 12
  ..- attr(*, "class")= chr [1:3] "mts" "ts" "matrix"
$ x           : Time-Series [1:408] from 1950 to 1984: 101.6 94.8 109.7 113.4 106.2 ...
$ alpha       : num 0.58
$ beta        : logi FALSE
$ gamma       : logi FALSE
$ coefficients: Named num 37.8
  ..- attr(*, "names")= chr "a"
$ seasonal    : chr "additive"
$ SSE         : num 134447
$ call        : language HoltWinters(x = x, beta = FALSE, gamma = FALSE)
- attr(*, "class")= chr "HoltWinters"

Ah! So I should have been using exp.smoother$SSE rather than exp.smoother$sse. Problem solved.

Yes, this is a tiny hack. Hardly worth a blog post except that it's very useful—and not widely known.