Home > R programming > Call by reference in R

Call by reference in R

Sometimes it is convenient to use “call by reference evaluation” inside an R function. For example, if you want to have multiple return value for your function, then either you return a list of return value and split them afterward or you can return the value via the argument.

For some reasons(I would like to know too), R do not support call by reference. The first reason come up in my mind is safety, if the function can do call by reference, it is more difficult to trace the code and debug(you have to find out which function change the value of your variables by examining the details of your function). In fact, R do “call by reference” when the value of the argument is not changed. They will make a copy of the argument only when the value is changed.  So we can expect there’s no efficiency gain (at least not a significant one) even we can do call by reference.

Anyway, it is always good to know how to have a “pseudo call by reference” in R (you can choose (not) to use it for whatever reason). The trick to implement call by reference is to make use of the eval.parent function in R. You can add a code to replace the argument value in the parent environment so that the function looks like implementing the call by reference evaluation strategy. Here are some examples of how to do it:

set<-function(x,value){
   eval.parent(substitute(x<-value))
}
valX <- 51
set(valX ,10)
valX
>[1] 10
addOne_1<-function(x,value){
   eval.parent(substitute(x<-x+1))
}
valX <- 51
addOne_1(valX)
valX
>[1] 52

Note that you could not change the value of x inside the function. If you change the value of x, a new object will be created. The substitute function will replace x with the new value and hence this method wont work. For example

addOne_2<-function(x,value){
   x<-x+1
   eval.parent(substitute(x<-x))
}
valX <- 51
addOne_2(valX)
>Error in 52 <- 52 : invalid (do_set) left-hand side to assignment

If you want to change the value of x inside the function, you have to copy x to a new object and use new object as x.  At the end of the function, you can replace the value of x with the new object at the parent environment.

addOne_3<-function(x,value){
   xx<-x
   xx<-xx+1
   eval.parent(substitute(x<-xx))
}
valX <- 51
addOne_3(valX)
valX
>[1] 52

Another way to do call by reference more formally is using the R.oo packages.

Another way to implement

About these ads
Categories: R programming
  1. Kenn
    September 12, 2011 at 09:40

    Using lots of eval and substitute is an easy way to mess things up. On the other hand, the idea of call by reference may sometimes be useful. Notice that the new “reference classes” are meant exactly for this purpose. For simpler uses, you can use environments which are also “refObjects” (test this using is(new.env())

    e <- new.env()
    set <- function(obj, value){
    obj $ tag <- value
    return("You don't expect a useful return value, do you?")
    }

    e $ tag
    set(e, 100)
    e$tag

    This way of (ab)using environments can sometimes be useful and is certainly safer than the eval.parent way (which may have some limited use in some contexts, too but …)

  2. anon
    September 12, 2011 at 11:15

    R is a functional language and there should not be any side effects from function calling. What you propose is the reason for a lot of trouble in C and should be avoided.

  3. September 12, 2011 at 12:24

    Thanks a lot for comments!

    Yup, I agree that it can mess things up easily and should be avoid.

    To Kenn: Is the reference classes you have mentioned inside the {methods} packages? I better to have a look on that one. It sounds very useful!

  4. Kenn
    September 13, 2011 at 04:36

    Reference classes are indeed in the methods package (but it’s about a year old and still called “preliminary” so you probably won’t find anything on it in books), see e.g. ?setRefClass

    As for OO in R, there are packages R.oo and proto; the latter is my favorite (using, behind the scenes, environments in a rather similar way as in my example).

    And yes, R is to a certain degree a functional language but side effects are common. Start by assignments (pure 100% side effect), or consider functions like fix and plot. Another side of functional style is the way arguments are treated, and also here there are numerous exceptions (e.g., functions like subset, but also when you type library(something) instead of library(“something”) you are using nonstandard evaluation).

  5. EtienneBR
    September 14, 2011 at 12:48

    “For some reasons(I would like to know too), R do not support call by reference”

    John Chamber is addressing the question throughout his book [1]. But you mainly got it right: it’s one of the aspects that makes the «Software Thrustwothy» because it is much clearer what the code is doing.

    [1] http://www.springer.com/statistics/computanional+statistics/book/978-1-4419-2612-8

  6. ibrahim
    January 22, 2013 at 06:46

    I tried your code for dendrogram but did not work! (as if it is still call by value)

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: