Load dependencies only for one function

Viewed 451

I am creating a package with a few functions. Only one auxiliary function needs plotly.

However when I install using devtools I get a note unused arguments in layout(yaxis = ay,... Then I read Hadley's article about imports vs depends. Using import doesn't remove the note, but adding plotly with depends in the NAMESPACE-file solves the issue.

Next I read the paragraph about 'Search Path'. Here Hadley states that

You should never use require() or library() in a package: instead, use the Depends or Imports fields in the DESCRIPTION

My issue now is that the function which uses plotly is more of an add-on to the package. All other (more important) functions work with base-R. Therefore I want to use plotly only for the one function which needs it.

  1. Is that possible without creating a note during install?
  2. Why are require or library so bad inside a package?
  3. Would it be okay to use requireNamespace and then require afterwards?

Here is some sample code:

#' Some plotly function
#'
#' Some very long description
#'
#' @param x_vec A numeric vector
#' @param y_vec A numeric vector
#' @keywords Some keywords
#' @return A plotly object
#' @export
#' @examples

debugMinEx<-function(x_vec,y_vec){

ay <- list(title = "",zeroline = FALSE,showline = FALSE,
           showticklabels = FALSE, showgrid = FALSE,
           scaleanchor="x",scaleratio=1) ## empty axis
ax <- list(title = "",zeroline = FALSE,showline = FALSE,
           showticklabels = FALSE, showgrid = FALSE) ## empty axis
my_legend<-list(font = list(family = "sans-serif", size = 14, color = "#000000"),
                x = 0, y = -0.05,orientation = "h")

plot_ly() %>%
  add_trace(x=x_vec,y=y_vec,
            type='scatter',mode='lines') %>%
  layout(yaxis = ay,xaxis=ax,
          legend = my_legend)
}
1 Answers

Use Suggests for this.

You can read about it in Writing R Extensions or in Hadley's Package Basics: Decription. In both cases, the recommendation is

  • The optional dependency goes in the Suggests field of your package DESCRIPTION.
  • Use if (requireNamespace) in the function to test it the package is there.

Something like this:

if (requireNamespace("plotly", quietly = TRUE)) {
      # do your plotly stuff
   } else {
      # do non-plotly stuff
      # maybe as simple as stop("Please install plotly to use this function")
   }

As for whether you can use require after requireNamespace - that seems pointless. Hadley's recommendations seem to be pretty clear to use requireNamespace("plotly") to load the package and subsequently use plotly:: to call the needed functions.

If you'd prefer to ignore this advice, then just do require the first time. Using requireNamespace followed by require is redundant. As explained in your link, requireNamespace loads a package without attaching it. require both loads and attaches.

Related