2

I want to call a function (hamming) where its name is stored as a string. To do this, I used get.

# Assign function name to variable
w <- "hamming"

# Load library for 'hamming' function
library(signal)
#> 
#> Attaching package: 'signal'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, poly

# Call function using 'get'
get(w)(10)
#>  [1] 0.0800000 0.1876196 0.4601218 0.7700000 0.9722586 0.9722586 0.7700000
#>  [8] 0.4601218 0.1876196 0.0800000

Created on 2019-11-19 by the reprex package (v0.3.0)

That works great.

Now, say I want to do exactly the same thing – and achieve the same result – but without calling library(). To do this, I included the package name along with the function name in the string, as follows:

# Assign function name to variable
w <- "signal::hamming"

# Call function using 'get'
get(w)(10)
#> Error in get(w): object 'signal::hamming' not found

Created on 2019-11-19 by the reprex package (v0.3.0)

This, however, doesn't work. Why? And how should I achieve this result without loading the entire package?

zx8754
  • 52,746
  • 12
  • 114
  • 209
Dan
  • 11,370
  • 4
  • 43
  • 68
  • 1
    Since the package isn't loaded `'signal::hamming'` doesn't exist in the environment, so there is nothing to "get". Why not just call `signal::hamming(10))` directly? No need to load the package provided it exists. Or is there perhaps a particular reason why it needs to be stored as a string in another variable? – edsandorf Nov 19 '19 at 13:06
  • Maybe via **evil** parse: `n = 10; eval(parse(text = paste0("signal::hamming(", n, ")")))` Note: `"106. If the answer is parse() you should usually rethink the question. - Thomas Lumley"` – zx8754 Nov 19 '19 at 13:11
  • @edsandorf I'm not sure I follow your logic. I understand that the package isn't loaded – that's why I use a package preface (i.e., `signal::`) to access the function. It works when I use `signal::hamming(10)` directly *without* the package loaded, so why not when I use `get`? What's the fundamental difference? The function name will be provided as a string, which is why I can't simply use `signal::hamming(10)`. – Dan Nov 19 '19 at 13:16
  • 2
    `get` only searches in the defined environment, if package is not loaded, it is not in any environment. What is the real use case for this, why are we doing this? – zx8754 Nov 19 '19 at 13:24
  • @zx8754 I think your solution can be condensed to `eval(parse(text = w))(10)`. The user is providing the function name as a string to a function that lives in a package. Since that function lives in a package, it's using `::` to access functions from other packages. – Dan Nov 19 '19 at 13:33
  • 2
    The answer in https://stackoverflow.com/questions/45302215/with-get-call-a-function-from-an-unloaded-package-without-using-library uses a function marked as being for internal use. The proper way to do this is `get("hamming", envir = loadNamespace("signal"))(10)`. – user2554330 Nov 19 '19 at 14:53
  • @user2554330 That's the solution. Can we reopen and post this as an answer? – Dan Nov 19 '19 at 15:11
  • Sure. I've voted to re-open. Not sure how many other re-open votes it will need... – user2554330 Nov 19 '19 at 16:21
  • Since this question hasn't been re-opened, I've now added a new answer to https://stackoverflow.com/questions/45302215/with-get-call-a-function-from-an-unloaded-package-without-using-library. Hopefully it answers your question as well. – user2554330 Nov 19 '19 at 17:58

0 Answers0