[R-pkg-devel] Trying to work around missing functionality

Duncan Murdoch murdoch@dunc@n @ending from gm@il@com
Tue Aug 28 18:40:28 CEST 2018


On 28/08/2018 9:17 AM, J C Nash wrote:
> Indeed, it appears that globalVariables must be outside the function. However, I had quite a bit of
> fiddle to get things to work without errors or warnings or notes. While I now have a package that
> does not complain with R CMD check, I am far from satisfied that I can give a prescription. I had
> to remove lines in the rootfinder like
>     envroot$fn <- fn
> that were used to set the function to be used inside my instrumented function, and instead
> call TraceSetup(fn=fn, ...) where a similar statement was given. Why that worked while the direct
> assignment (note, not a <<- one) did not, I do not understand. However, I will work with this for
> a while and try to get a better handle on it.
> 
> Thanks for the pointer. As an old-time programmer from days when you even set the add table, I'm
> still uncomfortable just putting code in a directory and assuming it will be executed, i.e., the
> globals.R file. However, I now have this set to establish the global structure as follows

The code in the R directory in a package is all executed once when the 
package is installed, to produce the functions and other objects in the 
package.  But that execution can do other things too, and that's what 
the call to globalVariables() does.

(The order of execution of the files in the R directory usually doesn't 
matter, but it is well defined:  alphabetical order by filename in the C 
locale unless overridden by the Collate field in DESCRIPTION.)

Duncan Murdoch

> 
>> ## Put in R directory.
>> if(getRversion() >= "2.15.1") { utils::globalVariables(c('envroot')) } # Try declaring here
>> groot<-list(ifn=0, igr=0, ftrace=FALSE, fn=NA, gr=NA, label="none")
>> envroot <- list2env(groot) # Note globals in FnTrace
> 
> Then TraceSetup() is
> 
>> TraceSetup <- function(ifn=0, igr=0, ftrace=FALSE, fn=NA, gr=NA){
>>     envroot$ifn <- ifn
>>     envroot$igr <- igr
>>     envroot$ftrace <- ftrace
>>     envroot$fn <- fn
>>     envroot$gr <- gr
>>     return()
>> }
> 
> and it is called at the start of the rootfinder routine.
> 
> Thus I am establishing a global, then (re-)setting values in TraceSetup(), then
> incrementing counters etc. in the instrumented FnTrace() that is the function for which I find
> the root, which calls fn() given by the "user". Messy, but I can now track progress and measure
> effort.
> 
> I'm sure there are cleaner solutions. I suggest offline discussion would be better until such
> options are clearer.
> 
> Thanks again.
> 
> JN
> 
> 
> 
> On 2018-08-28 12:01 AM, Fox, John wrote:
>> Hi John,
>>
>> It's possible that I didn’t follow what you did, but it appears as if you call globalVariables() *inside* the function. Instead try to do as Richard Heiberger suggested and place the call outside of the function, e.g., in a source file in the package R directory named globals.R. (Of course, the name of the source file containing the command isn’t important.)
>>
>> I hope this helps,
>>   John
>>
>> -----------------------------------------------------------------
>> John Fox
>> Professor Emeritus
>> McMaster University
>> Hamilton, Ontario, Canada
>> Web: https://socialsciences.mcmaster.ca/jfox/
>>
>>
>>
>>> -----Original Message-----
>>> From: R-package-devel [mailto:r-package-devel-bounces using r-project.org] On
>>> Behalf Of J C Nash
>>> Sent: Monday, August 27, 2018 8:44 PM
>>> To: Richard M. Heiberger <rmh using temple.edu>
>>> Cc: List r-package-devel <r-package-devel using r-project.org>
>>> Subject: Re: [R-pkg-devel] Trying to work around missing functionality
>>>
>>> Unfortunately, makes things much worse. I'd tried something like this already.
>>>
>>>> * checking examples ... ERROR
>>>> Running examples in ‘rootoned-Ex.R’ failed The error most likely
>>>> occurred in:
>>>>
>>>>> ### Name: rootwrap
>>>>> ### Title: zeroin: Find a single root of a function of one variable within
>>>>> ###   a specified interval.
>>>>> ### Aliases: rootwrap
>>>>> ### Keywords: root-finding
>>>>>
>>>>> ### ** Examples
>>>>>
>>>>> # Dekker example
>>>>> # require(rootoned)
>>>>> dek <- function(x){ 1/(x-3) - 6 }
>>>>> r1 <- rootwrap(dek, ri=c(3.0000001, 6), ftrace=TRUE,
>>>>> method="uniroot")
>>>> Error in registerNames(names, package, ".__global__", add) :
>>>>    The namespace for package "rootoned" is locked; no changes in the global
>>> variables list may be made.
>>>> Calls: rootwrap -> TraceSetup -> <Anonymous> -> registerNames
>>>> Execution halted
>>>
>>> Also had to use utils::globalVariables( ...
>>>
>>> JN
>>>
>>>
>>> On 2018-08-27 08:40 PM, Richard M. Heiberger wrote:
>>>> Does this solve the problem?
>>>>
>>>> if (getRversion() >= '2.15.1')
>>>>    globalVariables(c('envroot'))
>>>>
>>>> I keep this in file R/globals.R
>>>>
>>>> I learned of this from John Fox's use in Rcmdr.
>>>>
>>>> On Mon, Aug 27, 2018 at 8:28 PM, J C Nash <profjcnash using gmail.com>
>>> wrote:
>>>>> In order to track progress of a variety of rootfinding or
>>>>> optimization routines that don't report some information I want, I'm
>>>>> using the following setup (this one for rootfinding).
>>>>>
>>>>> TraceSetup <- function(ifn=0, igr=0, ftrace=FALSE, fn=NA, gr=NA){ #
>>>>> JN: Define globals here
>>>>>     groot<-list(ifn=ifn, igr=igr, ftrace=ftrace, fn=fn, gr=gr, label="none")
>>>>>     envroot <<- list2env(groot) # Note globals in FnTrace
>>>>>     ## This generates a NOTE that
>>>>>     ## TraceSetup: no visible binding for '<<-' assignment to ‘envroot’
>>>>> ##   envroot<-list2env(groot, parent=.GlobalEnv) # Note globals in FnTrace -
>>> - this does NOT work
>>>>>     ## utils::globalVariables("envroot") # Try declaring here --
>>>>> causes errors # end globals
>>>>>     envroot
>>>>> }
>>>>>
>>>>> FnTrace <- function(x,...) {
>>>>>    # Substitute function to call when rootfinding
>>>>>    # Evaluate fn(x, ...)
>>>>>      val <- envroot$fn(x, ...)
>>>>>      envroot$ifn <- envroot$ifn + 1 # probably more efficient ways
>>>>>      if (envroot$ftrace) {
>>>>>         cat("f(",x,")=",val," after ",envroot$ifn," ",envroot$label,"\n")
>>>>>      }
>>>>>      val
>>>>> }
>>>>>
>>>>>
>>>>> Perhaps there are better ways to do this, but this does seem to work quite
>>> well.
>>>>> It lets me call a rootfinder with FnTrace and get information on evaluations
>>> of fn().
>>>>> (There's another gr() routine, suppressed here.)
>>>>>
>>>>> However, R CMD check gives a NOTE for
>>>>>
>>>>>    TraceSetup: no visible binding for global variable ‘envroot’
>>>>>    Undefined global functions or variables:
>>>>>      envroot
>>>>>
>>>>> The commented lines in TraceSetup suggest some of the things I've
>>>>> tried. Clearly I don't fully comprehend how R is grinding up the
>>>>> code, but searches on the net seem to indicate I am far from alone. Does
>>> anyone have any suggestion of a clean way to avoid the NOTE?
>>>>>
>>>>> JN
>>>>>
>>>>> ______________________________________________
>>>>> R-package-devel using r-project.org mailing list
>>>>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>>
>>> ______________________________________________
>>> R-package-devel using r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
> 
> ______________________________________________
> R-package-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>



More information about the R-package-devel mailing list