Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Special assignment in R

Tags:

r

My question is just to understand how one feature of the R language works. In "the R language definition" coming with any good release of R, there is something explaining how, for example, the setting of an element of a vector works with something that looks like an assignment but is not so straightforward:

x[3:5] <- 13:15

is a shortcut for:

`*tmp*` <- x
x <- "[<-"(`*tmp*`, 3:5, value=13:15)
rm(`*tmp*`)

What I don't understand is the reason why using an intermediate symbol *tmp* and not directly do the thing with the setter function.

x <- "[<-"(x, 3:5, value=13:15)

Until now I was suspecting that it has something to do with garbage collection but as this one has significantlly changed with the v4 and as the documentation did'nt change I am now supecting that I was wrong. Can somebody explain?

Thanks

like image 977
Nicolas2 Avatar asked May 12 '21 18:05

Nicolas2


1 Answers

OK, first let's show that the description is quite literal: `*tmp*` is actually created.

`*tmp*` <- NULL
lockBinding("*tmp*", .GlobalEnv)
x[3:5] <- 13:15
#Error: cannot change value of locked binding for '*tmp*'
unlockBinding("*tmp*", .GlobalEnv)

Now, the language definition explains that the mechanism is quite general and also used for more complex assignments. Here is an example that actually creates different results if you don't use a `*tmp*` object:

x <- 1:10
local({
  x <- 11:20
  x[3:5] <<- 13:15
})
x
#[1]  1  2 13 14 15  6  7  8  9 10

x <- 1:10
local({
  x <- 11:20
  x <<- `[<-`(x, 3:5, value=13:15)
})
x
# [1] 11 12 13 14 15 16 17 18 19 20

x <- 1:10
local({
  x <- 11:20
  `*tmp*` <- get("x", envir=parent.env(environment()), inherits=TRUE)
  x <<- `[<-`(`*tmp*`, 3:5, value=13:15)
  rm(`*tmp*`)
})
x
# [1]  1  2 13 14 15  6  7  8  9 10

Other examples could probably be found.

like image 108
Roland Avatar answered Nov 20 '22 08:11

Roland