Xu Wang
Xu Wang

Reputation: 10607

find all functions in a package that use a function

I would like to find all functions in a package that use a function. By functionB "using" functionA I mean that there exists a set of parameters such that functionA is called when functionB is given those parameters.

Also, it would be nice to be able to control the level at which the results are reported. For example, if I have the following:

outer_fn <- function(a,b,c) {
    inner_fn <- function(a,b) {
        my_arg <- function(a) {
            a^2
        }
        my_arg(a)
    }
    inner_fn(a,b)
}

I might or might not care to have inner_fn reported. Probably in most cases not, but I think this might be difficult to do.

Can someone give me some direction on this?

Thanks

Upvotes: 2

Views: 412

Answers (2)

Ben Bolker
Ben Bolker

Reputation: 226871

(Upgraded from a comment.) There is a very nice foodweb function in Mark Bravington's mvbutils package with a lot of this capability, including graphical representations of the resulting call graphs. This blog post gives a brief description.

Upvotes: 3

Tommy
Tommy

Reputation: 40871

A small step to find uses of functions is to find where the function name is used. Here's a small example of how to do that:

findRefs <- function(pkg, fn) {
  ns <- getNamespace(pkg)
  found <- vapply(ls(ns, all.names=TRUE), function(n) {
     f <- get(n, ns)
     is.function(f) && fn %in% all.names(body(f))
  }, logical(1))

  names(found[found])
}

findRefs('stats', 'lm.fit')
#[1] "add1.lm"  "aov"      "drop1.lm" "lm"       "promax"

...To go further you'd need to analyze the body to ensure it is a function call or the FUN argument to an apply-like function or the f argument to Map etc... - so in the general case, it is nearly impossible to find all legal references...

Then you should really also check that getting the name from that function's environment returns the same function you are looking for (it might use a different function with the same name)... This would actually handle your "inner function" case.

Upvotes: 3

Related Questions