2

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)

denis
  • 5,580
  • 1
  • 13
  • 40

2 Answers2

5

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)
nicola
  • 24,005
  • 3
  • 35
  • 56
Karolis Koncevičius
  • 9,417
  • 9
  • 56
  • 89
  • I will check that as soon as I can. It looks promising, I just want to verify how it is handled with the `modules` structure – denis Nov 09 '20 at 09:28
  • It is not working as I expect it. All the non exported functions called inside my modified `redcap_write()` do not work, so the call to to the modified function gives an error. I tried to include them as a module, but I still get errors – denis Nov 09 '20 at 21:44
  • Maybe try adding those non-exported functions under the same namespace: `ns[["fun1"]] <- function1; ns[["fun2"]] <- function2;`. – Karolis Koncevičius Nov 09 '20 at 21:51
  • @denis Made an edit on the answer which hopefully addresses your last issue. Didn't post a new answer, since Karolis here was very close. – nicola Nov 11 '20 at 08:24
  • It does not work, because of the `modules` structure I guess. My function `redcap_write` is indicated in `{modules:REDCapR}`, but I cannot do `asNamespace("modules:REDCapR")`. If I do what you propose in the edit, it does not modify the function loaded with `modules::import("REDCapR")` – denis Nov 13 '20 at 10:23
  • But you don't need to do `asNamespace(modules:REDCapR)`. Just `asNamespace("REDCapR")`. Simply execute the code in the answer and then call `modules:import("REDCapR")`. – Karolis Koncevičius Nov 14 '20 at 10:00
  • @denis Tested with `modules` today, and it seemed to be working fine for me. – Karolis Koncevičius Nov 16 '20 at 14:55
1

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).

paradigmatic
  • 40,153
  • 18
  • 88
  • 147
  • doing `remotes::install_github(repo="dmongin/REDCapR/tree/overwrite")` (the branch with my modifs) I have `Downloading GitHub repo dmongin/REDCapR@HEAD Error: Failed to install 'REDCapR' from GitHub:` – denis Nov 09 '20 at 21:50
  • from [here](https://github.com/r-lib/devtools/issues/1939) I tried `Sys.setenv("TAR" = "internal")` but still the same error – denis Nov 09 '20 at 21:52
  • @denis I edited the answer to select the `overwrite` branch. – paradigmatic Nov 10 '20 at 06:41
  • Thanks! It does not install the modified version, I do not know why. It starts with ` remotes::install_github("dmongin/REDCapR",branch = "overwrite") Downloading GitHub repo dmongin/REDCapR@HEAD`, install the package, but then the `redcap_write` function is the one from master. I manage to have the modified version by downloading my `overwrite` branch and building it locally. – denis Nov 10 '20 at 09:24