rdevtoolstibble

Custom formatting of tibble subclass in a package


I am trying to implement a subclass of tbl to tweak the way how my data is printed. The code is part of a package.

I have read the documentation and used these lines:

as_data_test <- function(...) {
  tibble::new_tibble(..., class = "data_test")
}

tbl_format_header.data_test <- function(x, setup, ...) {
  cli::style_italic("A Data Test = ", setup$tbl_sum)
}

Then I use devtools::load_all(".") to load the package. But when I try to print my data_test object, it does not use the custom tbl_format_header function:

devtools::load_all(".")
# i Loading datatesteR
as_data_test(mtcars)
# # A tibble: 32 x 11
#      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
#    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
#  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
#  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
#  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
#  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
#  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
#  7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
#  8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2
#  9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
# 10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
# # i 22 more rows
# # i Use `print(n = ...)` to see more rows

As you can see only the default header is printed. Placing a browser call in tbl_format_header.data_test confirms that my method is never dispatched. If I put the same code directly into an R console, everything works like a charm.

How would I get the custom printing in my devtools workflow?


Solution

  • First, more generally, if you want to implement a method for an S3 generic, you need to export it. If you are using roxygen2, you can add #' @export above your method for class tbl_sum. When you run devtools::document(), this will add the following to your NAMESPACE file:

    S3method(tbl_format_header,data_test)
    

    Second (to the contrary of the aforementioned), this will not work for tbl_sum as it does not exist in the namespace of your package. In this case, you can use roxygen2's @exportS3Method:

    #' @exportS3Method pillar::tbl_format_header
    tbl_format_header.data_test <- function(x, setup, ...) {
      cli::style_italic("A Data Test = ", setup$tbl_sum)
    }
    

    This will modify your NAMESPACE to:

    S3method(pillar::tbl_format_header,data_test)
    

    Source: R packages, chapter 11.9