Застрял с определением метода S3 для автографа

Я застрял с определением метода S3 для autoplot.

У меня есть следующее (полный код здесь):

#' 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
}

Как я понимаю теперь, я должен быть в состоянии запустить, но это не удается:

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

Почему он не нашел функцию? У меня правильный @importFrom ggplot2 autoplot, а Roxygen выдает правильный NAMESPACE.

Есть ggplot2 в Imports в DESCRIPTION.

Я понятия не имею, почему он не работает и почему мне нужно library(ggplot2) его использовать.


person m0nhawk    schedule 17.04.2018    source источник
comment
export функцию autoplot, чтобы сделать ее доступной для пользователя.   -  person Roland    schedule 18.04.2018


Ответы (2)


Когда вы импортируете пакет, он «загружается через пространство имен (а не прикрепляется)» (цитата из sessionInfo()).

Когда вы хотите использовать функцию из импортированного пакета, вы обычно вызываете ее, используя структуру ggplot2::ggplot(), как вы сделали.

Следовательно, чтобы использовать autoplot, вам все равно нужно использовать ggplot2::autoplot().

Если вы этого не сделаете, ваш пакет не знает о функции autoplot из ggplot2.

Есть несколько решений для этого:

  1. используйте Depends: ggplot2 (см. ссылки ниже для обсуждения Imports и Depends и раздел 1.1.3 или написание расширений R]
  2. определить метод plot, который затем вызывает различные функции ggplot2::ggplot()
  3. продолжайте с autoplot.bigobenchmark, но потребуйте, чтобы пользователь загрузил ggplot2 перед использованием (пример этого на практике находится в пакет зоопарка. См. также ?zoo::autoplot
  4. Экспортируйте свою собственную функцию autoplot, но это может вызвать конфликт, если пользователь затем загрузит ggplot2

Вот пример решения 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
}

А вот пример решения 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
}

Лучшее объяснение Imports vs Depends дано Джошем О'Брайаном и майомом (цитируя Хэдли) в этом ответе SO

person SymbolixAU    schedule 17.04.2018

В дополнение к ответу @SymbolixAU вы можете импортировать autoplot из ggplot2 и экспортировать его вот так, не будет конфликта с 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
person Victorp    schedule 18.04.2018
comment
Ах да, я забыл об этом подходе. Я даже использую его для экспорта канала в один из моих пакеты. Это, пожалуй, лучшее решение. - person SymbolixAU; 18.04.2018
comment
Да! Я использую это для трубы тоже в первый раз - person Victorp; 18.04.2018