Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R force local scope

Tags:

r

This is probably not correct terminology, but hopefully I can get my point across.

I frequently end up doing something like:

myVar = 1 f <- function(myvar) { return(myVar); } # f(2) = 1 now 

R happily uses the variable outside of the function's scope, which leaves me scratching my head, wondering how I could possibly be getting the results I am.

Is there any option which says "force me to only use variables which have previously been assigned values in this function's scope"? Perl's use strict does something like this, for example. But I don't know that R has an equivalent of my.


EDIT: Thank you, I am aware of that I capitalized them differently. Indeed, the example was created specifically to illustrate this problem!

I want to know if there is a way that R can automatically warn me when I do this.

EDIT 2: Also, if Rkward or another IDE offers this functionality I'd like to know that too.

like image 442
Xodarap Avatar asked Jun 02 '11 15:06

Xodarap


1 Answers

As far as I know, R does not provide a "use strict" mode. So you are left with two options:

1 - Ensure all your "strict" functions don't have globalenv as environment. You could define a nice wrapper function for this, but the simplest is to call local:

# Use "local" directly to control the function environment f <- local( function(myvar) { return(myVar); }, as.environment(2)) f(3) # Error in f(3) : object 'myVar' not found  # Create a wrapper function "strict" to do it for you... strict <- function(f, pos=2) eval(substitute(f), as.environment(pos)) f <- strict( function(myvar) { return(myVar); } ) f(3) # Error in f(3) : object 'myVar' not found 

2 - Do a code analysis that warns you of "bad" usage.

Here's a function checkStrict that hopefully does what you want. It uses the excellent codetools package.

# Checks a function for use of global variables # Returns TRUE if ok, FALSE if globals were found. checkStrict <- function(f, silent=FALSE) {     vars <- codetools::findGlobals(f)     found <- !vapply(vars, exists, logical(1), envir=as.environment(2))     if (!silent && any(found)) {         warning("global variables used: ", paste(names(found)[found], collapse=', '))         return(invisible(FALSE))     }      !any(found) } 

And trying it out:

> myVar = 1 > f <- function(myvar) { return(myVar); } > checkStrict(f) Warning message: In checkStrict(f) : global variables used: myVar 
like image 110
Tommy Avatar answered Sep 19 '22 13:09

Tommy