Nicolas2
Nicolas2

Reputation: 2210

Special assignment in 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

Upvotes: 7

Views: 128

Answers (1)

Roland
Roland

Reputation: 132969

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.

Upvotes: 4

Related Questions