Stuck with definition of S3 method for autoplot
Asked Answered
S

2

6

I'm stuck with defining S3 method for autoplot.

I have the following (full code here):

#' Autoplot for bigobenchmark object
#'
#' @importFrom ggplot2 autoplot
#'
#' @param object
#'
#' @return A ggplot2 plot
#' @export
#'
#' @examples
#' # Create plot for benchmarks
#' library(ggplot2)
#' bench <- bigobenchmark(1:n, for(i in 1:n) for(i in 1:n) 1:n, args=seq(from=1, to=100, length.out = 50))
#' autoplot(bench)
autoplot.bigobenchmark <- function(object) {
  plt <- ggplot2::ggplot(data = object$benchmarks, ggplot2::aes(x=arg, y=mean, colour=expr))
  plt <- plt + ggplot2::geom_line()
  plt <- plt + ggplot2::geom_pointrange(aes(ymin=min, ymax=max))
  plt
}

As I understand now I should be able to run, but it fails:

> autoplot(test)
Error in autoplot(test) : could not find function "autoplot"

Why it doesn't found the function? I have a proper @importFrom ggplot2 autoplot and Roxygen produces correct NAMESPACE.

There is a ggplot2 in Imports in DESCRIPTION.

I have no idea why it doesn't work and why I need to library(ggplot2) to use it.

Sissy answered 17/4, 2018 at 21:50 Comment(1)
export the autoplot function to make it available to the user.Atlante
C
6

When you import a package, it's "loaded via a namespace (and not attached)" (quoting from sessionInfo()).

When you want to use a function from an imported package you typically call it using the structure ggplot2::ggplot(), as you have done.

Therefore, to use autoplot you would still need to use ggplot2::autoplot().

If you don't, your package is not aware of the autoplot function from ggplot2.

There are a few solutions to this:

  1. use Depends: ggplot2 (see links below for a discussion on Imports vs Depends, and section 1.1.3 or writing R extensions]
  2. define a plot method which then calls the various ggplot2::ggplot() functions
  3. continue with autoplot.bigobenchmark, but require the user to load ggplot2 prior to use (an example of this in practice is in the zoo package. See also ?zoo::autoplot
  4. Export your own autoplot function, but this may cause conflict if the user then later loads ggplot2

Here's an example of solution 2

#' plot for bigobenchmark object
#'
#' @importFrom ggplot2 autoplot
#'
#' @param object
#'
#' @return A ggplot2 plot
#' @export
#'
#' @examples
#' # Create plot for benchmarks
#' library(ggplot2)
#' bench <- bigobenchmark(1:n, for(i in 1:n) for(i in 1:n) 1:n, args=seq(from=1, to=100, length.out = 50))
#' plot(bench)
#'
#' @author Andrew Prokhorenkov
plot.bigobenchmark <- function(object) {
  plt <- ggplot2::ggplot(data = object$benchmarks, ggplot2::aes(x=arg, y=mean, colour=expr))
  plt <- plt + ggplot2::geom_line()
  plt <- plt + ggplot2::geom_pointrange(ggplot2::aes(ymin=min, ymax=max))
  plt
}

And here's an example of solution 4

#' Autoplot for bigobenchmark object
#'
#' @importFrom ggplot2 autoplot
#'
#' @param object
#'
#' @return A ggplot2 plot
#' @export
#'
#' @examples
#' # Create plot for benchmarks
#' library(ggplot2)
#' bench <- bigobenchmark(1:n, for(i in 1:n) for(i in 1:n) 1:n, args=seq(from=1, to=100, length.out = 50))
#' autoplot(bench)
#'
#' @author Andrew Prokhorenkov
autoplot <- function(object) UseMethod("autoplot")

#' @export
autoplot.bigobenchmark <- function(object) {
  plt <- ggplot2::ggplot(data = object$benchmarks, ggplot2::aes(x=arg, y=mean, colour=expr))
  plt <- plt + ggplot2::geom_line()
  plt <- plt + ggplot2::geom_pointrange(ggplot2::aes(ymin=min, ymax=max))
  plt
}

A better explanation of Imports vs Depends is given by Josh O'Brian and majom (quoting Hadley) in this SO answer

Colchis answered 17/4, 2018 at 23:42 Comment(0)
S
4

In addition to @SymbolixAU's response, you can import autoplot from ggplot2 and export it like this, there will be no conflict with ggplot2:

#' bigobenchmark exported operators and S3 methods
#'
#' The following functions are imported and then re-exported
#' from the bigobenchmark  package to avoid loading them.
#'
#' @importFrom ggplot2 autoplot
#' @name autoplot
#' @export
NULL
Spall answered 18/4, 2018 at 8:23 Comment(2)
Ah yes, I forgot about this approach. I even use it to export the pipe in one of my pacakges. This is probably the best solution.Colchis
Yes! I use this for the pipe too the first timeSpall

© 2022 - 2024 — McMap. All rights reserved.