Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stuck with definition of S3 method for autoplot

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.

like image 516
m0nhawk Avatar asked Apr 17 '18 21:04

m0nhawk


2 Answers

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

like image 146
SymbolixAU Avatar answered Sep 24 '22 06:09

SymbolixAU


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
like image 24
Victorp Avatar answered Sep 26 '22 06:09

Victorp