pyfns::hello_world()[1] "Helloooo world"
I was asked a really interesting question by @benyamindsmith yesterday. The question was essentially:
How can one export a python 🐍 function in an R package 📦?
I proposed my solution as a very minimal R package called {pyfns}.
It is an R package with one function: hello_world().
The process is fairly simple.
reticulate::source_python() into the new environmentExample usage:
pyfns::hello_world()[1] "Helloooo world"
Store python scripts inside of inst/. These files can be read using system.file(). In this example inst/helloworld.py contains
def hello_world():
return "Helloooo world"Before we can source python scripts, we must create an environment to soure them into. This is done in R/env.R like so
pyfn_env <- rlang::env()Scripts are sourced in R/zzz.R in which there is an .onLoad() function call. This gets called only once when the package is loaded.
.onLoad <- function(libname, pkgname){
reticulate::source_python(
system.file("helloworld.py", package = "pyfns"),
envir = pyfn_env
)
}In this chunk we use reticulate::source_python() to bring the python function into scope. The function needs a path to the python script that we want to source. This is where system.file() comes into play. It can access files stored in inst. Note that it does not include inst. And most importantly we set envir = pyfn_env which is the environment we created in R/env.R
Since the functions are being sourced into pyfn_env they can be called from the environment directly. In R/env.R, the R function hello_world() is just calling the hello_world() python function from the pyfn_env. If there were arguments we can pass them in using ... in the outer function or recreating the same function arguments.
#'@export
hello_world <- function() {
pyfn_env$hello_world()
}