How to modify a function of a library in a module

Viewed 233

I have the following problem - in a script starting like that:

modules::import("modules")
modules::import("futile.logger")
modules::import("data.table")
modules::import("REDCapR")

used as a module using modules::use in an other script, I would like to use a modified version of the function redcap_write of the package REDCapR.

I don't know how to proceed. To my point of view there are two possibilities:

  • Use a modified version of redcap_write stored locally. That would be great, because it would be an easy mofication to share. But I don't know how to force R to replace the redcap_write function of the package by my local modified version. modules::use would only import the modified function but would not replace the package version of redcap_write

  • Install a forked version of REDCapR package, that I created here https://github.com/dmongin/REDCapR/tree/overwrite. But I don't know how to do in a simple manner (uninstalling REDCapR to install my forked version would be a bit tidious: we share the code between various developper/users, each should uninstall and reinstall the package)

2 Answers

You would have to modify the things under the package Namespace. Here is one example replacing redcap_write() with the mean() function.

ns <- asNamespace("REDCapR")
fn <- "redcap_write"

unlockBinding(fn, ns)
ns[[fn]] <- mean
lockBinding(fn, ns)

Check if it worked:

library(REDCapR)

> redcap_write
function (x, ...)
UseMethod("mean")
<bytecode: 0x7f8120229100>
<environment: namespace:base>

> REDCapR::redcap_write
function (x, ...)
UseMethod("mean")
<bytecode: 0x7f8120229100>
<environment: namespace:base>

EDIT:

In order to redcap_write to call the proper functions inside its body, you have to set it in the REDCapR environment. This should work (assuming newversion is your corrected redcap_write function):

ns <- asNamespace("REDCapR")
fn <- "redcap_write"
unlockBinding(fn, ns)
environment(newversion) <- ns
ns[[fn]] <- newversion
lockBinding(fn, ns)

You can reinstall your version instead using remotes. It will replace in the package previously installed:

install.packages("remotes") # Run this line if the 'remotes' package isn't installed already.
remotes::install_github("dmongin/REDCapR",branch="overwrite")

(taken from the original RedcapR Readme, updated for your fork).

Related