[R] What purpose is served by reflexive function assignments?

David Winsemius dwinsemius at comcast.net
Sun Dec 29 07:09:33 CET 2013


On Dec 28, 2013, at 7:27 PM, Andrew Hoerner wrote:

> Let us suppose that we have a function foo(X) which is called inside
> another function, bar(). Suppose, moreover, that the name "X" has been
> assigned a value when foo is called:
> 
> X <- 2
> bar(X=X){
> foo(X)
> }
> 
> I have noticed that many functions contain arguments with defaults of the
> form X=X. Call this reflexive assignment of arguments. How is foo(X=X)
> different from foo(X)?

The LHS X becomes a name, the RHS X will be looked up in the calling environment and fails if no value is positionally matched and then no X is found (at the time of the function definition.

> Isn't the environment from which X is located the
> parent environment of foo() in either case?

Not really. The X in foo(X) will be whatever value is given as the argument when foo is called and it will be assigned to X inside the function body.

> Or if it looks first in the
> environment inside of foo, will it not immediately pop up to the parent
> environment if it is not found in foo?

With foo(X=X) the interpreter will first determine if an argument was offered:

rm(X)
foo <- function(Z=X) print(Z^3)
foo(5)    # No error.
#[1] 125   

> Are reflexive assignments just to
> keep X from being positionally assigned accidentally, or are they doing
> something deeper? Moreover, this is the only place I have seen people
> consistently using an equals sign in place of the usual "<-", and I am
> confident that there is some subtle difference in how the two assignment
> operators work, perhaps beyond the ken of lesser mortals like myself, that
> explains why the "=" is preferred in this particular application.

If you use`X <- value` in the argument list, then what is returned is only the value and the name `X` may be lost. Or in the case of data.frame morphed inot a strange name:

d <- data.frame(X <- letters[1:3])
d
  X....letters.1.3.
1                 a
2                 b
3                 c

Since it does a deparse(substitute(.)) on the nameless expressions in the argument list.

> 
> Actually, although I would like to hear the deep answer, which I am sure
> has something to do with scoping, as everything really confusing in R does,
> my real question is, is there some rule of thumb by which one could decide
> whether or not to do a reflexive assignment in a function definition and be
> right most of the time?
> 
> Lately I have gotten several "Error: Promise is already under evaluation"
> messages, and my current rule of thumb for dealing with this is to add
> reflexive assignment to the variable if it is missing and take it out if it
> is present. This seems to work, but it makes me feel unintelligent. Is
> there a better rule? I would be most grateful for anyone who could shed
> light on the subject.
> 
> Sincerely, andrewH
> 
> -- 
> J. Andrew Hoerner
> Director, Sustainable Economics Program
> Redefining Progress
> (510) 507-4820
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> 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.

David Winsemius
Alameda, CA, USA



More information about the R-help mailing list