Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the `[<-` function work in R?

I've seen a couple of people using [<- as a function with Polish notation, for example

x <- matrix(1:4, nrow = 2)
`[<-`(x, 1, 2, 7)

which returns

     [,1] [,2]
[1,]    1    7
[2,]    2    4

I've tried playing around with [<- a little, and it looks like using it this way prints the result of something like x[1,2] <- 7 without actually performing the assignment. But I can't figure out for sure what this function actually does, because the documentation given for ?"[" only mentions it in passing, and I can't search google or SO for "[<-".

And yes, I know that actually using it is probably a horrible idea, I'm just curious for the sake of a better understanding of R.

like image 415
Empiromancer Avatar asked Feb 01 '16 20:02

Empiromancer


2 Answers

This is what you would need to do to get the assignment to stick:

 `<-`(    `[`(   x, 1, 2), 7)  # or x <- `[<-`(   x, 1, 2, 7)
 x
     [,1] [,2]
[1,]    1    7
[2,]    2    4

Essentially what is happening is that [ is creating a pointer into row-col location of x and then <- (which is really a synonym for assign that can also be used in an infix notation) is doing the actual "permanent" assignment. Do not be misled into thinking this is a call-by-reference assignment. I'm reasonably sure there will still be a temporary value of x created.

Your version did make a subassignment (as can be seen by what it returned) but that assignment was only in the local environment of the call to [<- which did not encompass the global environment.

like image 188
IRTFM Avatar answered Nov 01 '22 16:11

IRTFM


Since `[`(x, y) slices an object, and `<-`(x, z) performs assignment, it seems like `[<-`(x,y,z) would perform the assignment x[y] <- y. @42-'s answer is a great explanation of what [<- actually does, and the top answer to `levels<-`( What sorcery is this? provides some insight into why R works this way.

To see what [<- actually does under the hood, you have to go to the C source code, which for [<- can be found at http://svn.r-project.org/R/trunk/src/main/subassign.c (the relevant parts start at around line 1470). You can see that x, the object being "assigned to" is protected so that only the local version is mutated. Instead, we're using VectorAssign, MatrixAssign, ArrayAssign, etc. to perform assignment locally and then returning the result.

like image 40
Empiromancer Avatar answered Nov 01 '22 16:11

Empiromancer