Extending base::trace()
with
ggtrace()
The low-level function ggtrace()
is designed for
interacting with functions and ggproto methods in the
ggplot2 ecosystem, from the “outside”.
Formally put, ggtrace()
allows the user to inject
arbitrary expressions (called traces) to functions and
methods that are evaluated over the execution of a ggplot. When
“triggered” by the evaluation of the ggplot, these traces may modify the
resulting graphical output, or they may simply log their values to the
“tracedump” for further inspection by the user. Check out the FAQ
vignette for more details.
Briefly, there are three key arguments to ggtrace()
:
-
method
: what function/method to trace -
trace_steps
: where in the body to inject expressions -
trace_exprs
what expressions to inject
A simple example:
dummy_fn <- function(x = 1, y = 2) {
z <- x + y
return(z)
}
dummy_fn()
#> [1] 3
The following code injects the code z <- z * 10
right
as dummy_fn
enters the third “step” in the body, right
before the line return(z)
is ran.
body(dummy_fn)[[3]]
#> return(z)
ggtrace(
method = dummy_fn,
trace_steps = 3L, # Before `return(z)` is ran
trace_exprs = quote(z <- z * 10)
)
#> `dummy_fn` now being traced.
Note that the value of trace_exprs
must be of type
“language” (a quoted expression), the idea being that we are
injecting code to be evaluate inside the function when it is
called. Often, providing the code wrapped in quote()
suffices. For more complex injections see the Expressions chapter of
Advanced R
After this ggtrace()
call, the next time
dummy_fn
is called it is run with this injected code.
# Returns 30 instead of 3
dummy_fn()
#> Triggering trace on `dummy_fn`
#> Untracing `dummy_fn` on exit.
#> [1] 30
Essentially, dummy_fn
ran with this following modified
code just now:
dummy_fn_traced <- function(x = 1, y = 2) {
z <- x + y
z <- z * 10 #< injected code!
return(z)
}
dummy_fn_traced()
#> [1] 30
By default, traces created by ggtrace functions delete
themselves after being triggered. You can also check whether a function
is currently being traced with is_traced()
.
is_traced(dummy_fn)
#> [1] FALSE
ggtrace automatically logs the output of triggered
trace to what we call tracedumps. For example,
last_ggtrace()
stores the output of the last trace
created by ggtrace()
:
# The value of `(z <- z * 10)` when it was ran
last_ggtrace() # Note that this is a list of length `trace_steps`
#> [[1]]
#> [1] 30
See the references section Extending
base::trace() for more functionalities offered by
ggtrace()
.