library(butcher)
If you come across any model objects that should be subject to butchering, but does not exist in our current repository as listed here, please consider becoming a contributor to this package! For any first-timers, this is great place to start as we’ve created templates that make this process as seamless as possible.
Let’s say our new model object, of class blob
, was
generated from a R
package called blobber
. If
you want to add axe methods for this class, first clone butcher onto
your local computer and open up RStudio (see
usethis::create_from_github("tidymodels/butcher")
for an
automated way to do this). After you have opened RStudio and are in the
butcher
RStudio Project, run:
> new_model_butcher(model_class = "blob", package_name = "blobber")
You’ll get the following console messages:
'path_to_butcher_package'
✔ Setting active project to 'blobber' to Suggests field in DESCRIPTION
✔ Adding `requireNamespace("blobber", quietly = TRUE)` to test if package is installed
● Use `blobber::fun()` (replacing `fun()`).
● Then directly refer to functons like
ℹ Writing skeleton files'R/blob.R'
✔ Writing 'tests/testthat/test-blob.R'
✔ Writing 'R/blob.R'
● Modify 'tests/testthat/test-blob.R' ● Modify
new_model_butcher()
leverages usethis
to:
blobber
modeling package under
Suggests
in the butcher
package description
file.R
directory with all
possible axe methods for blob
.tests/testthat
to test new blob
axe methods.As shown by the R
scripts attached to other model
objects that exist in this package, not all axe generics are
used. In fact, if you take a look at the elnet.R
script,
the only component of the model object fit from the package
glmnet
that might be worth axing is the call
.
To help target what is worth removing from blob
, we
recommend first beginning with butcher::weigh()
to identify
which parts of the model object take up the most memory.
> weigh(fitted_blob_object)
# A tibble: 25 x 2
object size<chr> <dbl>
1 terms 4.01
2 qr.qr 0.00666
3 residuals 0.00286
4 fitted.values 0.00286
5 effects 0.0014
6 coefficients 0.00109
7 call 0.000728
8 model.mpg 0.000304
9 model.cyl 0.000304
10 model.disp 0.000304
# … with 15 more rows
In this example, the fitted model objected generated from
blobber
has a terms
component that is taking
4.01 Mb. From here, you can examine the structure of this terms
component by leveraging
lobstr::sxp(fitted_blob_object$terms)
or simply running
utils::str(fitted_blob_object$terms)
. If you are looking to
hunt for a specific component like the environment, fitted values,
training data, controls or the call object, take a look at
butcher::locate()
.
Perhaps from our model object, blob
, we find that the
call
is the only piece worth axing (or replacing). The
R/blob.R
skeleton would be completed by putting a
placeholder for the original call.
#' Axing a blob.
#'
#' blob model objects are created from the blobber package. They are
#' generally leveraged for classification ... insert anything relevant
#' ... This is where all the blob specific documentation lies.
#'
#' @param x Model object.
#' @param verbose Print information each time an axe method is executed
#' that notes how much memory is released and what functions are
#' disabled. Default is \code{TRUE}.
#' @param ... Any additional arguments related to axing.
#'
#' @return Axed model object.
#'
#' @name axe-blob
NULL
#' Remove the call.
#'
#' @rdname axe-blob
#' @export
<- function(x, verbose = TRUE, ...) {
axe_call.blob <- x
old <- exchange(x, "call", call("dummy_call"))
x if (verbose) {
assess_object(
old,
x,disabled = c("print", "summary")
)
}add_butcher_class(x)
}
Here we assign the current blob object x
to the variable
old
as a means to evaluate the memory released once
axe_call()
is executed on the original model object. Next,
we actually exchange()
the current call with a dummy call
of a (hopefully) smaller size. We also include
assess_object()
with the additional string parameter of
disabled
so console messages will be printed out, alerting
users of any downstream functions would be affected by axing the call.
Since the original model object is fundamentally different, we attach an
additional butcher_blob
class by calling
add_butcher_class()
at the end of each axe method. Once the
axe methods are set, we then have a skeleton file
tests/testthat/test-blob.R
to aid in any unit testing.
Adding a new model object to butcher:
new_model_butcher(model_class = "blob", package_name = "blobber")
butcher::weigh()
and
butcher::locate()
to decide what to axeR/blob.R
and
tests/testthat/test-blob.R