How do I override a non-visible function in the package namespace?
Use fixInNamespace
. :)
fixInNamespace("predict.ar", "stats")
or
fixInNamespace("predict.ar", pos="package:stats")
(Several years later...)
From Nicholas H's comment: if you want to push some code to CRAN that depends upon an internal function from another package, it will throw a build warning and be rejected by R-core. If you want that internal function, you should just take a copy of it using the :::
operator and maintain it yourself.
predict.ar <- stats:::predict.ar
R: what's the proper way to overwrite a function from a package?
There are lots of different cases here.
If it's a bug in someone else's package
Then the best practice is to contact the package maintainer and persuade them to fix it. That way everyone gets the fix, not just you.
If it's a bug while developing your own package
Then you need to find a workflow where rebuilding packages is easy. Like using the devtools
package and typing build(mypackage)
, or clicking a button ("Build & Reload" in RStudio; "R CMD build" in Architect).
If you just want different behaviour to an existing package
If it isn't a bug as such, or the package maintainer won't make the fix that you want, then you'll have to maintain you own copy of f1
. Using assignInNamespace
to override it in the existing package is OK for exploring, but it's a bit hacky so it isn't really suitable for a permanent solution.
Your best bet is to create your own package containing copies of f1
and f2
. This is less effort than it sounds, since you can just define f2 <- existingpackage::f2
.
In response to the comment:
Second and third cases makes sense if you are alone but they require to build and install the packages which is tricky in the case of my organisation as the packages are deployed on dozens of computer and I need root access to update the packages.
So take a copy of the existing package source, apply your patch, and host it on your company network or github or Bitbucket. Then the updated package can be installed programmatically via
install.packages("//some/network/path/mypackage_0.0-1.tar.gz", repos = NULL)
or
library(devtools)
install_github("mypackage", "mygithubusername")
Since the installation is just a line of code, you can easily push it to as many machines as you like. You don't need root access either - just install the package to a library folder that doesn't require root access to write to. (Read the Startup and .libPaths help pages for how to define a new library.) You'll need network access to those machines, but I can't help you with that. Speak to your network administrator or your boss or whoever can get you permission.
Change internal function of a package
Try
?assignInNamespace
to replace .HMR.fit1
in the HMR
package with your version.
Possible duplicate of :
How do I override a non-visible function in the package namespace?
Overriding a package function inherited by another package
Changing the function in the formatR namespace doesn't change what knitr uses because knitr is already loaded. So, you could unload and reload it.
assignInNamespace("tidy.source", function()print("My tidy.source"), "formatR")
detach('package:knitr', unload=TRUE)
library(knitr)
get("tidy.source", envir=asNamespace("knitr"))
#function()print("My tidy.source")
how to fix/edit an invisible function in R interaction session?
There are functions assignInNamespace
and fixInNamespace
that allow doing what you say. There is also the edit
argument to the trace
function which will let you edit a function in place. Using trace
has the advantage of making it easy to untrace
and remove the changes that you made.
Get namespace of function
You can use getAnywhere
For example, if you're looking for the namespace for the stringr
function str_locate
you can do
getAnywhere("str_locate")$where
# [1] "package:stringr" "namespace:stringr"
This will work as long as stringr
is "visible on the search path, registered as an S3 method or in a namespace but not exported."
The result is a named list, and you can see what's available from getAnywhere
with names
names(getAnywhere("str_locate"))
# [1] "name" "objs" "where" "visible" "dups"
How can a non-imported method in a not-attached package be found by calls to functions not having it in their namespace?
I'm not sure if I correctly understand your question, but the main point is that group
is character vector while data$group
is factor.
After attaching gmodels
, the call for reorder(factor)
calls gdata:::reorder.factor
.
so, reorder(factor(group))
calls it.
In transform
, the function is evaluated within the environment of the first argument, so in T2 <- transform(data, group = reorder(group,-num))
, group
is factor.
UPDATED
library
attaches the import packages into loaded namespace.
> loadedNamespaces()
[1] "RCurl" "base" "datasets" "devtools" "grDevices" "graphics" "methods"
[8] "stats" "tools" "utils"
> library(gmodels) # here, namespace:gdata is loaded
> loadedNamespaces()
[1] "MASS" "RCurl" "base" "datasets" "devtools" "gdata" "gmodels"
[8] "grDevices" "graphics" "gtools" "methods" "stats" "tools" "utils"
Just in case, the reorder
generic exists in namespace:stats
:
> r <- ls(.__S3MethodsTable__., envir = asNamespace("stats"))
> r[grep("reorder", r)]
[1] "reorder" "reorder.default" "reorder.dendrogram"
And for more details
The call of reorder
will search the S3generics in two envs:
see ?UseMethod
first in the environment in which the generic function is called, and then in the registration data base for the environment in which the generic is defined (typically a namespace).
then, loadNamespace
registers the S3 functions to the namespace.
So , in your case, library(gmodels)
-> loadNamespace(gdata)
-> registerS3Methods(gdata)
.
After this, you can find it by:
> methods(reorder)
[1] reorder.default* reorder.dendrogram* reorder.factor*
Non-visible functions are asterisked
However, as the reorder.factor
is not attached on your search path, you cannot access it directly:
> reorder.factor
Error: object 'reorder.factor' not found
Probably this is whole scenario.
Related Topics
Inst and Extdata Folders in R Packaging
Joining Aggregated Values Back to the Original Data Frame
How to Define Fixed Aspect-Ratio for (Base R) Scatter-Plot
Deleting Columns from a Data.Frame Where Na Is More Than 15% of the Column Length
Format for Ordinal Dates (Day of Month with Suffixes -St, -Nd, -Rd, -Th)
Poly() in Lm(): Difference Between Raw VS. Orthogonal
How to Add Multiple Columns to a Data.Frame in One Go
Merge Many Data Frames from CSV Files, When Id Column Is Implied
R: Assign Variable Labels of Data Frame Columns
How to Extract the Row with Min or Max Values
Print Unicode Character String in R
Forward and Backward Fill Data Frame in R
Convert All Data Frame Character Columns to Factors