Search code examples
rr-packageroxygen2

Use function from R package in other package: When and how to use importFrom, :: and imports


I have read the section in R packages book and I'm still a little confused. I want to use e.g. the fromJSON-function from the jsonlite-package in my own little package.

I am kind of unsure what to do and these are the questions/options I am considering:

  1. Each time I am using the fromJSON-function I could preprend it with the ::-operator like jsonlite::fromJSON. I guess in order for that to work I would need to put it into the DESCRIPTION-file under imports. Such that the jsonlite-package would always be installed if my pacakge is installed. Is that good practice?

  2. If I do that, why would I put the @importFrom jsonlite fromJSON in my roxygen-comments. I know that it adds the line importFrom(jsonlite, fromJSON) to the NAMESPACE-file. But what is the advantage or idea of that line?

  3. In the past I experieced that functions from other packages also appear under my own package like <my_package>::fromJSON. Does this has to with the importFrom(jsonlite, fromJSON)-line?

I would appreciate any tip!:)


Solution

  • My two pennyworth (five cents worth):

    I prefer your first option, to refer to external functions with (eg) jsonlite::fromJSON - because this is (to me) the only immediately unambiguous way of referencing the source of the function. This is what I have done in the packages I have written or contributed to.

    If you plan only to use your package locally, this is - I believe - all you need to do. However, if you plan to publish your package, either informally or on CRAN, you should (or will need to) do more.

    The simplest option is to use usethis::use_package() to add the package to your DESCRIPTION file. if you don't do this, any informally distributed package will (I think) install, but users will get errors when they run the code that references the external functions unless they have independently installed the required package(s). A CRAN submission will fail. (As will devtools::check().)

    You can use @importFrom in front of every function in which you use the external function. This will also add the necessary references to the NAMESPACE file and allow you to refer to the unscoped function within the body of your function. This is a shorthand that some find convenient, but personally, I don't like it. Why? because your function may use a function like filter. Just looking at the function code, the reader doesn't know if this refers to (say) dplyr::filter or stats::filter. The reader can find out by looking at the comments at the top of the function, or they may make an assumption. At best, you force them to make a little extra effort. At worst, you allow them to make an assumption that may lead to error. It also allows you to specify @importFrom stats for some functions and @importFrom dplyr for others. This is ambiguous and potentially error prone.

    I can't comment on your third point other than to ask if you are exporting these third party functions from your own package.