ckluss
ckluss

Reputation: 1281

How to copy a foreign package and overwrite a function?

I like to build a CRAN conform package, but have to overwrite a function from a foreign package. Probably I have to copy the entire package functions under a different namespace? Is there a way to do it in a CRAN way?

Local the following works, but of course not for valid CRAN packages

library(xyz)

f1 <- xyz:::f    
body(f1) <- parse(text = gsub("df < 0", "any(df < 0)", deparse(body(f1))))

assignInNamespace("f", f1, ns="xyz")

I am very grateful for an example. (There is no way that the maintainer of xyz will change it because my concern is a very special case.)

thx Christof

Upvotes: 1

Views: 586

Answers (1)

Technophobe01
Technophobe01

Reputation: 8676

My sense is you have at least two potential options here. This first is what I think you need but I include both for completeness.

  1. Create your own package and extend the base package
  2. Create your own function that extends the base package function

nb: If you could provide the package and function you wish to extend that would be super helpful as I had to make this slightly generic. I have referenced the original StackOverflow posts that helped me in this situation. In terms of further/deeper reading my recommendation would be to read:

  • R Inferno By: Patrick Burns
    • Covers the nuances of R
    • Read Section 7 - Circle 7 Tripping on Object Orientation
  • R Packages By: Hadley Wickham
    • Chapter 8. Namespaces
    • Hadley does a great job of explaining R namespaces.

Solution Options:

Create Your own Package and extend base package

In this context, my sense is to direct you to take a look at section 1.5.6 of the Writing R Extensions manual.

Why? Well, based on your description my sense would be to import the functions from the package, and then write your extension function.

You can do this by importing the classes and methods explicitly, with directives

importClassesFrom(package, ...)
importMethodsFrom(package, ...)

listing the classes and functions with methods respectively. Suppose we had two small packages A and B with B using A. Then they could have NAMESPACE files

export(f1, ng1)
exportMethods("[")
exportClasses(c1)

and

importFrom(A, ng1)
importClassesFrom(A, c1)
importMethodsFrom(A, f1)
export(f4, f5)
exportMethods(f6, "[")
exportClasses(c1, c2)

respectively.

Note that importMethodsFrom will also import any generics defined in the namespace on those methods. It is important if you export S4 methods that the corresponding generics are available. You may, for example, need to import plot from graphics to make visible a function to be converted into its implicit generic. But it is better practice to make use of the generics exported by stats4 as this enables multiple packages to unambiguously set methods on those generics.

Here is the StackOverflow question and answer that helped me previously:

Create your own function that extends the base package function

See: Overwrite method to extend it, using the original implementation

I hope the above helps.

Upvotes: 1

Related Questions