From ripley at stats.ox.ac.uk  Thu Jul 20 22:46:58 2006
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Thu, 20 Jul 2006 21:46:58 +0100 (BST)
Subject: [Rd] How do I modify an exported function in a locked
	environment?
In-Reply-To: <0BE438149FF2254DB4199E2682C8DFEB01D554A2@crcmail1.BCCRC.CA>
References: <0BE438149FF2254DB4199E2682C8DFEB01D554A2@crcmail1.BCCRC.CA>
Message-ID: <Pine.LNX.4.64.0607202134590.32650@gannet.stats.ox.ac.uk>

Please do not post to multiple lists: I have removed R-help.

On Thu, 20 Jul 2006, Steven McKinney wrote:

> Running R.app on Mac OS X 10.4
> 
> I am trying to learn how to modify functions
> in a locked environment.

This is deliberately hard.

> For an example, suppose I'm using the package "zoo".
> 
> zoo contains function "rollmean.default"
> 
> > rollmean.default
> function (x, k, na.pad = FALSE, align = c("center", "left", "right"), 
>     ...) 
> {
>     x <- unclass(x)
>     n <- length(x)
>     y <- x[k:n] - x[c(1, 1:(n - k))]
>     y[1] <- sum(x[1:k])
>     rval <- cumsum(y)/k
>     if (na.pad) {
>         rval <- switch(match.arg(align), left = {
>             c(rval, rep(NA, k - 1))
>         }, center = {
>             c(rep(NA, floor((k - 1)/2)), rval, rep(NA, ceiling((k - 
>                 1)/2)))
>         }, right = {
>             c(rep(NA, k - 1), rval)
>         })
>     }
>     return(rval)
> }
> <environment: namespace:zoo>
> 
> Suppose for whatever reason I want output to be
> in percent, so I'd like to modify the result to be
> rval <- 100 * cumsum(y)/k
> 
> I cannot just copy the function and change it, as the namespace
> mechanism ensures the rollmean.default in 'zoo' continues to be used.
> 
> If I use
> fixInNamespace("rollmean.default", ns = "zoo")
> I can edit the rval <- cumsum(y)/k line to read
> rval <- 100 * cumsum(y)/k
> save the file and exit the R.app GUI editor.
> 
> But this does not update the exported copy of the
> function (the documentation for fixInNamespace says
> this is the case) - how do I accomplish this last step?

You need to unlock the binding, then assign in package:zoo.
Something like

unlockBinding("rollmean.default", as.environment("package:zoo"))
assign("rollmean.default", zoo:::rollmean.default, pos="package:zoo")

However, it is not usual to export methods, and that is why this case is 
particularly hard.

> If I list the function after editing, I see the original
> copy.  But if I reinvoke the editor via fixInNamespace(),
> I do see my modification.
> Where is my copy residing?  How do I push it out
> to replace the exported copy?
> 
> Is this the proper way to modify a package function?

Many would say it was not proper to `modify a package function'.

> Are there other ways?  I've searched webpages, R news,
> help files and have been unable to find out how to
> get this process fully completed.

> Any guidance appreciated.

You may not like the guidance ....

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595



[Rd] How do I modify an exported function in a locked environment?
Prof Brian Ripley