1

I made some ad hoc modifications to a function in the package metafor by copying the function code from Github and replacing the function in my environment as described here:

my.rma.uni = function(...) {
# here I simply copied the existing code with no modifications as a test
}

unlockBinding("rma.uni", as.environment("package:metafor"))
assign("rma.uni", rma.uni_mm, as.environment("package:metafor"))
lockBinding("rma.uni", as.environment("package:metafor"))

But when I try to now to run rma.uni, my modified version appears unable to find metafor's other internal functions:

Error in .chkdots(ddd, c("knha", "scale", "link", "outlist")) : 
  could not find function ".chkdots"

I also tried simply calling my.rma.uni directly (which would actually be my preference so that I can have both the standard rma.uni and my version available at the same time), but this yields the same error.

How can I ensure that my modified function can access all the internal functions?

half-pass
  • 1,851
  • 4
  • 22
  • 33

2 Answers2

2

For a short-term hack, I usually just access any necessary hidden functions via triple-colon, e.g. metafor:::.chkdots. This is unwieldy (I usually go through and fix them one by one as they fail) and unsuitable for submitting to CRAN etc., but it works for me.

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
1

If you need your function to access "private" functions from a namespace, you can set the environment of your function. Normally functions automatically take the environment of where they are defined. But you can programatically change that.

If you just do

environment(my.rma.uni) <- as.environment("package:metafor")

Then the my.rma.uni function will look up any free symbols in the metafor namespace rather than the global namespace. You can do this without messing with locking/unlocking the binding and assigning in the namespace. You only need to do what if you want to completely replace the function in the package. Most times it's better just to create your own copy in the global namespace.

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
MrFlick
  • 195,160
  • 17
  • 277
  • 295