[R] findGlobals on apply

Luke Tierney luke at stat.uiowa.edu
Wed Apr 9 01:08:01 CEST 2008


On Wed, 9 Apr 2008, Christophe Genolini wrote:

> Hi Luke
>
> Thanks for all these explanation, things are clearer.
>
> Let me go back on my initial problem, that was, as a programmer, I would like 
> to have a tool to detect typo by detecting globals variables:
> I get that findGlobals is not design for that.
>
> I did not realy understand the use of checkUsage (sorry for that, I am not a 
> high level programmer).
> But I find an example on which checkUsage does not detect the typo either:
>
> mObjBis <- 3
> f <- function(myOb){
> myObBis <- myOb^2
> plot(myObBis)
> return(mObjBis)
> }
> checkUsage(f,all=TRUE)

I don't see how a general tool can detect a problem here.  If you know
the only global variables you will ever use are functions then you can
write your own tool to reflect that style, but for common styles there
is no clear reason I can see to detect a problem here.  A C compiler
could not detect a problem here unless the function was declared to
have a different return type than the global variable.

> So, my question is a more general question : is there a function that can 
> detect global variable with exclusion of the function and the reserved word?
>
> For example:
> g <- function(x)return(x+pi)
> we don't want pi to be considere as a global variable since it is a 
> constant...

But in R pi is a global variable.  checkUsage doesn't warn about its
use because it has a binding.

> Is there a function that can deal with that ?

If you know what you want you can write one, something like

myGlobals <- function(f, exclude = c("pi", "T", "F")) {
     isGlobFun <- function(s)
         ! (exists(s, .GlobalEnv) && is.function(get(s,.GlobalEnv)))
     g <- findGlobals(f)
     setdiff(g[sapply(g, isGlobFun)], exclude)
}

I would suggest you use this sort of thing in conjunction with
checkUsage since that checks for other kinds of errors; for example
look at what it does with the variant

f <- function(myOb){
     myObBis <- myOb^2
     plot(mObjBis)
     return(mObjBis)
}

Best,

luke

>
> Christophe
>
>> On Tue, 8 Apr 2008, Christophe Genolini wrote:
>> 
>>> 
>>>>> f <- function(x){apply(x,2,mean)}
>>>>> findGlobals(f)
>>>> mean is a global variable, so findGlobals gets it right.
>>> That sound strange to me: a "variable" is something that vary... mean
>>> does not vary. maen will ge an argument that is a line of x and will
>>> make some calculous on it, that is the comportement of a function.
>>> Of course, mean is an argument of an other function, but I do not think
>>> this is a reason good enouth to say that mean is a variable.
>> 
>> You are missing some points about R and findGlobals.
>> 
>> In R, functions are first class values: they can be assigned to
>> variables, passed as arguments, and returned as results, just like
>> vectors. In contrast to many other languages there is not special
>> mechanism for defining functions and associating them with a name --
>> the way you define a function is
>> 
>> foo <- function(...) ...
>> 
>> which creates a function value and assigns it to a variable.
>> 
>> findGlobals just looks at the function body and arguments and
>> determines which of the variables used would have their definitions
>> looked up in the global environment if this code is run. It does not
>> try to detect which of these have values or not, never mind what the
>> types of those falues are.
>> 
>> The result returned by findGlobals with merge=FALSE separates into
>> variables that are explicitly used as funcitons, i.e foo in foo(x) and
>> ones that are not. One could argue that findGlobals should know
>> enough about apply() to realize that the FUN argument is implicitly
>> used as a function; if this change were made then
>> 
>> apply(x, 2, pi)
>> 
>> pi would be listed as a function because it is _used_ that way.
>> 
>>> Furthemore, I use findGlobals to detect some typo. In
>>> 
>>> f <- function(myObject){return(mObject^2)}
>>> 
>>> findGlobals will detect that mObject is a global so I know there is a
>>> typo somewhere.
>>> Considering mean as a globals do not let us use findGlobals this way.
>> 
>> You need to do some extra work to get this -- checking which globals
>> have values, and maybe whether those that are used as functions have
>> values that are functions. checkUsage does this, among other things.
>> For this example checkUsage produces
>> 
>> > checkUsage(f)
>> <anonymous>: no visible binding for global variable ‘mObject’
>> 
>> luke
>> 
>>> Christophe
>>> 
>>> ______________________________________________
>>> R-help at r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>> PLEASE do read the posting guide 
>>> http://www.R-project.org/posting-guide.html
>>> and provide commented, minimal, self-contained, reproducible code.
>>> 
>> 
>
>

-- 
Luke Tierney
Chair, Statistics and Actuarial Science
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:      luke at stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu


More information about the R-help mailing list