简体   繁体   中英

R: How do I add an extra function to a package?

I would like to add an idiosyncratically modified function to package written by someone else, with an R Script, ie just for the session, not permanently. The specific example is, let's say, bls_map_county2() added to the blscrapeR package. bls_map_county2 is just a copy of the bls_map_county() function with an added ... argument, for purposes of changing a few of the map drawing parameters. I have not yet inserted the additional parameters. Running the function as-is, I get the error:

Error in BLS_map_county(map_data = df, fill_rate = "unemployed_rate", : could not find function "geom_map"

I assume this is because my function does not point to the blscrapeR namespace. How do I assign my function to the (installed, loaded) blscrapeR namespace, and is there anything else I need to do to let it access whatever machinery from the package it requires?

When I am hacking on a function in a particular package that in turn calls other functions I often use this form after the definition:

mof_func <- function( args) {body hacked}
environment(mod_func) <- environment(old_func)

But I think the function you might really want is assignInNamespace . These methods will allow the access to non-exported functions in loaded packages. They will not however succeed if the package is not loaded. So you may want to have a stopifnot() check surrounding require(pkgname) .

There are two parts to this answer - first a generic answer to your question, and 2nd a specific answer for the particular function that you reference, in which the problem is something slightly different.

1) generic solution to accessing internal functions when you edit a package function

You should already have access to the package namespace, since you loaded it, so it is only the unexported functions that will give you issues.

I usually just prepend the package name with the ::: operator to the non exported functions. Ie, find every instance of a call to some_internal_function() , and replace it with PackageName:::some_internal_function() . If there are several different internal functions called within the function you are editing, you may need to do this a few times for each of the offending function calls.

The help page for ::: does contain these warnings

Beware -- use ':::' at your own risk!

and

It is typically a design mistake to use ::: in your code since the corresponding object has probably been kept internal for a good reason. Consider contacting the package maintainer if you feel the need to access the object for anything but mere inspection.

But for what you are doing, in terms of temporarily hacking another function from the same package for your own use, these warnings should be safe to ignore (at you own risk, of course - as it says in the manual)

2) In the case of blscrapeR ::bls_map_county()

The offending line in this case is

ggplot2::ggplot() + geom_map(...

in which the package writers have specified the ggplot2 namespace for ggplot() , but forgotten to do so for geom_map() which is also part of ggplot2 (and not an internal function in blscrapeR ).

In this case, just load ggplot2, and you should be good to go.

You may also consider contacting the package maintainer to inform them of this error.

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