Search code examples
pythonrpackagereticulate

Including a Python function in an R package without importing the entire package each time the function is used


If I'm calling a function within an R package that I created, I prefix it with the package name in which it resides. For example, if I wish to use gam from the mgcv package in the myfunc function of my package, I could write something like,

myfunc <- function(y, x, df){
    mgcv::gam(y ~ s(x), data = df)
}

Now, say I want to use the Python function indexes from the package peakutils. I could write,

myfunc <- function(y){
    pu <- reticulate::import("peakutils")
    pu$indexes(y)
}

but this would import the entire package each time myfunc was called, which is not ideal. What is the correct way of doing this? Presumably, Imports: in the DESCRIPTION file is just for R packages. Or is there a way to include it there somehow?


Solution

  • The solution is to import the Python library in the .onLoad function of the package being sure to specify delay_load = TRUE.

    For example,

    # Global reference to peakutils package - initialized in .onLoad
    peakutils <- NULL
    
    # Called upon loading the package
    .onLoad <- function(libname, pkgname) {
      # Use superassignment to update global reference to peakutils
      peakutils <<- reticulate::import("peakutils", delay_load = TRUE)
    }
    

    While this loads the entire package, it does so only once rather than each time a function from the Python library is needed. A thorough explanation is given here.