Debugging With the Superassignment Operator
Written by Peter Rosenmai on 31 Dec 2013.
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.