简体   繁体   中英

Using call() with namespace address (:: or :::)

I am having trouble using the call() function together with the namespace address operators :: and ::: . Simply adding it to the function name as supplied for call() produces an error when the call is evaluated, as this silly example shows:

> call("base::print", "Hi there")
`base::print`("Hi there")
> eval(call("base::print", "Hi there"))
Error in `base::print`("Hi there") : 
 could not find function "base::print"

For some reason, call() adds backticks around the function name (probably because it contains non-standard characters), which seems to mess up everything. Here is what happens when the "address" is omitted:

> call("print", "Hi there")
print("Hi there")
> eval(call("print", "Hi there"))
[1] "Hi there"

I will very much appreciate any suggestions for how to solve this issue. Note however that I need to produce the code with call() , as I am autogenerating code for rmarkdown code chunks, and I need to be able to specify the namespace, because I am using an unexported function from my package which I would really like to stay unexported.

Thanks for reading!


Update: I neglected to mention another property of the solution I am looking for (which I became aware of by reading Stéphane Laurent's otherwise great answer below): I am looking for a solution where the function definition is not copied into the call, which I believe rules out solutions using get() . As an example of what I am trying to avoid, let's say we want to call qplot() from ggplot2 . If we use eg getFromNamespace() the call will look like this (with the middle part of the output omitted for making it easier to read):

> as.call(list(getFromNamespace("qplot", "ggplot2"), 1:10))

  (function (x, y = NULL, ..., data, facets = NULL, margins = FALSE, 
  geom = "auto", xlim = c(NA, NA), ylim = c(NA, NA), log = "", 
  main = NULL, xlab = deparse(substitute(x)), ylab = deparse(substitute(y)), 
asp = NA, stat = NULL, position = NULL) 
{
  if (!missing(stat)) 
      warning("`stat` is deprecated", call. = FALSE)
  if (!missing(position)) 
      warning("`position` is deprecated", call. = FALSE)
  if (!is.character(geom)) 
      stop("`geom` must be a character vector", call. = FALSE)
  argnames <- names(as.list(match.call(expand.dots = FALSE)[-1]))
  arguments <- as.list(match.call()[-1])
  env <- parent.frame()

#### A lot more code defining the function (omitted)#####

  if (!missing(xlim)) 
      p <- p + xlim(xlim)
  if (!missing(ylim)) 
      p <- p + ylim(ylim)
  p
})(1:10)

The same thing happens if we instead use as.call(list(ggplot2::qplot, 1:10)) .

What I am looking for is something that produces the call ggplot2::qplot(1:10) .

Maybe

> eval(as.call(list(getFromNamespace("print", "base"), "Hi there")))
[1] "Hi there"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM