Programmatically switch package in `::` call in R
Since ::
can be seen as a function, it looks like
`::`(dummy_pkg_name, foo)()
is what you want. Alternatively,
getFromNamespace("foo", ns = dummy_pkg_name)()
For instance,
`::`(stats, t.test)
# function (x, ...)
# UseMethod("t.test")
# <bytecode: 0x102fd4b00>
# <environment: namespace:stats>
getFromNamespace("t.test", ns = "stats")
# function (x, ...)
# UseMethod("t.test")
# <bytecode: 0x102fd4b00>
# <environment: namespace:stats>
You could also create a call()
that could then be evaluated.
call("::", quote(bar), quote(foo()))
# bar::foo()
Put into use:
c <- call("::", quote(stats), quote(t.test))
eval(c)
# function (x, ...)
# UseMethod("t.test")
# <bytecode: 0x4340988>
# <environment: namespace:stats>
Wrapped up in a function using setdiff
as our default function:
f <- function(pkg, fn = setdiff) {
pkg <- substitute(pkg)
fn <- substitute(fn)
eval(call("::", pkg, fn))
}
f(base)
# function (x, y)
# {
# x <- as.vector(x)
# y <- as.vector(y)
# unique(if (length(x) || length(y))
# x[match(x, y, 0L) == 0L]
# else x)
# }
# <bytecode: 0x30f1ea8>
# <environment: namespace:base>
f(dplyr)
# function (x, y, ...)
# UseMethod("setdiff")
# <environment: namespace:dplyr>
To adhere to KISS, simply re-assign to new named functions in global environment. Be sure to leave out ()
since you are not requesting to run the function.
parent_foo <- parentPkg::foo
child1_foo <- childPkg1::foo
child2_foo <- childPkg2::foo
child3_foo <- childPkg3::foo
Then, conditionally apply them as needed:
if (scenario=="child1") {
obj <- child1_foo(...)
}
else if (scenario=="child2") {
obj <- child2_foo(...)
}
...