Operator “[<-” in RStudio and R
up vote
40
down vote
favorite
By accident i've encountered strange behaviour of "[<-"
operator. It behaves differently depending on order of calls and whether i'm using RStudio or just ordinary RGui. I will make myself clear with an example.
x <- 1:10
"[<-"(x, 1, 111)
x[5] <- 123
As far as i know, first assigment shouldn't change x
(or maybe i'm wrong?), while the second should do. And in fact the result of above operations is
x
[1] 1 2 3 4 123 6 7 8 9 10
However, when we perform these operations in different order, results are different and x
has changed! Meaningly:
x <- 1:10
x[5] <- 123
"[<-"(x, 1, 111)
x
[1] 111 2 3 4 123 6 7 8 9 10
But it only happens when i'm using plain R! In RStudio the behaviour is the same in both options. I've checked it on two machines (one with Fedora one with Win7) and the situation looks exactly the same.
I know the 'functional' version ("[<-"(x..)
) is probably never used but i'm very curious why it is happening. Could anyone explain that?
==========================
EDIT:
Ok, so from comments i get that the reason was that x <- 1:10
has type 'integer' and after replacing x[5] <- 123
it's 'double'.
But still remains question why behaviour is different in RStudio? I restart R session and it doesn't change anything.
r rstudio
|
show 15 more comments
up vote
40
down vote
favorite
By accident i've encountered strange behaviour of "[<-"
operator. It behaves differently depending on order of calls and whether i'm using RStudio or just ordinary RGui. I will make myself clear with an example.
x <- 1:10
"[<-"(x, 1, 111)
x[5] <- 123
As far as i know, first assigment shouldn't change x
(or maybe i'm wrong?), while the second should do. And in fact the result of above operations is
x
[1] 1 2 3 4 123 6 7 8 9 10
However, when we perform these operations in different order, results are different and x
has changed! Meaningly:
x <- 1:10
x[5] <- 123
"[<-"(x, 1, 111)
x
[1] 111 2 3 4 123 6 7 8 9 10
But it only happens when i'm using plain R! In RStudio the behaviour is the same in both options. I've checked it on two machines (one with Fedora one with Win7) and the situation looks exactly the same.
I know the 'functional' version ("[<-"(x..)
) is probably never used but i'm very curious why it is happening. Could anyone explain that?
==========================
EDIT:
Ok, so from comments i get that the reason was that x <- 1:10
has type 'integer' and after replacing x[5] <- 123
it's 'double'.
But still remains question why behaviour is different in RStudio? I restart R session and it doesn't change anything.
r rstudio
3
It might be worth reading stackoverflow.com/questions/15178507/… -- this is not the same issue however
– mnel
Mar 21 '13 at 22:30
1
WHat do you mean byplain old R
?
– mnel
Mar 21 '13 at 22:53
2
This is a wild guess, and I'm not sure how to test it, but in the question mnel linked to, the point was made that if there is a second reference to the object that the replacement will not be done in place but will result in a copy (and thus not modify the original variable). Perhaps RStudio, as part of its GUI, has references to the object. That is possible since it has an object browser. Or some other aspect which is triggering the copying mechanism rather than the replace-in-place behavior.
– Brian Diggs
Mar 21 '13 at 23:12
1
I can't reproduce this, same behavior (order matters) in both, RStudio and RGUI (and Eclipse, which uses Rterm).
– Roman Luštrik
Mar 21 '13 at 23:12
1
@Arun -- I think that initial comment was a red herring. This isn't a problem with R, so I would be shocked (and not in a good way) if it has changed since the Feb 20th version of R-devel that I'm running...
– Josh O'Brien
Mar 21 '13 at 23:25
|
show 15 more comments
up vote
40
down vote
favorite
up vote
40
down vote
favorite
By accident i've encountered strange behaviour of "[<-"
operator. It behaves differently depending on order of calls and whether i'm using RStudio or just ordinary RGui. I will make myself clear with an example.
x <- 1:10
"[<-"(x, 1, 111)
x[5] <- 123
As far as i know, first assigment shouldn't change x
(or maybe i'm wrong?), while the second should do. And in fact the result of above operations is
x
[1] 1 2 3 4 123 6 7 8 9 10
However, when we perform these operations in different order, results are different and x
has changed! Meaningly:
x <- 1:10
x[5] <- 123
"[<-"(x, 1, 111)
x
[1] 111 2 3 4 123 6 7 8 9 10
But it only happens when i'm using plain R! In RStudio the behaviour is the same in both options. I've checked it on two machines (one with Fedora one with Win7) and the situation looks exactly the same.
I know the 'functional' version ("[<-"(x..)
) is probably never used but i'm very curious why it is happening. Could anyone explain that?
==========================
EDIT:
Ok, so from comments i get that the reason was that x <- 1:10
has type 'integer' and after replacing x[5] <- 123
it's 'double'.
But still remains question why behaviour is different in RStudio? I restart R session and it doesn't change anything.
r rstudio
By accident i've encountered strange behaviour of "[<-"
operator. It behaves differently depending on order of calls and whether i'm using RStudio or just ordinary RGui. I will make myself clear with an example.
x <- 1:10
"[<-"(x, 1, 111)
x[5] <- 123
As far as i know, first assigment shouldn't change x
(or maybe i'm wrong?), while the second should do. And in fact the result of above operations is
x
[1] 1 2 3 4 123 6 7 8 9 10
However, when we perform these operations in different order, results are different and x
has changed! Meaningly:
x <- 1:10
x[5] <- 123
"[<-"(x, 1, 111)
x
[1] 111 2 3 4 123 6 7 8 9 10
But it only happens when i'm using plain R! In RStudio the behaviour is the same in both options. I've checked it on two machines (one with Fedora one with Win7) and the situation looks exactly the same.
I know the 'functional' version ("[<-"(x..)
) is probably never used but i'm very curious why it is happening. Could anyone explain that?
==========================
EDIT:
Ok, so from comments i get that the reason was that x <- 1:10
has type 'integer' and after replacing x[5] <- 123
it's 'double'.
But still remains question why behaviour is different in RStudio? I restart R session and it doesn't change anything.
r rstudio
r rstudio
edited Mar 21 '13 at 23:06
asked Mar 21 '13 at 22:26
BartekCh
590413
590413
3
It might be worth reading stackoverflow.com/questions/15178507/… -- this is not the same issue however
– mnel
Mar 21 '13 at 22:30
1
WHat do you mean byplain old R
?
– mnel
Mar 21 '13 at 22:53
2
This is a wild guess, and I'm not sure how to test it, but in the question mnel linked to, the point was made that if there is a second reference to the object that the replacement will not be done in place but will result in a copy (and thus not modify the original variable). Perhaps RStudio, as part of its GUI, has references to the object. That is possible since it has an object browser. Or some other aspect which is triggering the copying mechanism rather than the replace-in-place behavior.
– Brian Diggs
Mar 21 '13 at 23:12
1
I can't reproduce this, same behavior (order matters) in both, RStudio and RGUI (and Eclipse, which uses Rterm).
– Roman Luštrik
Mar 21 '13 at 23:12
1
@Arun -- I think that initial comment was a red herring. This isn't a problem with R, so I would be shocked (and not in a good way) if it has changed since the Feb 20th version of R-devel that I'm running...
– Josh O'Brien
Mar 21 '13 at 23:25
|
show 15 more comments
3
It might be worth reading stackoverflow.com/questions/15178507/… -- this is not the same issue however
– mnel
Mar 21 '13 at 22:30
1
WHat do you mean byplain old R
?
– mnel
Mar 21 '13 at 22:53
2
This is a wild guess, and I'm not sure how to test it, but in the question mnel linked to, the point was made that if there is a second reference to the object that the replacement will not be done in place but will result in a copy (and thus not modify the original variable). Perhaps RStudio, as part of its GUI, has references to the object. That is possible since it has an object browser. Or some other aspect which is triggering the copying mechanism rather than the replace-in-place behavior.
– Brian Diggs
Mar 21 '13 at 23:12
1
I can't reproduce this, same behavior (order matters) in both, RStudio and RGUI (and Eclipse, which uses Rterm).
– Roman Luštrik
Mar 21 '13 at 23:12
1
@Arun -- I think that initial comment was a red herring. This isn't a problem with R, so I would be shocked (and not in a good way) if it has changed since the Feb 20th version of R-devel that I'm running...
– Josh O'Brien
Mar 21 '13 at 23:25
3
3
It might be worth reading stackoverflow.com/questions/15178507/… -- this is not the same issue however
– mnel
Mar 21 '13 at 22:30
It might be worth reading stackoverflow.com/questions/15178507/… -- this is not the same issue however
– mnel
Mar 21 '13 at 22:30
1
1
WHat do you mean by
plain old R
?– mnel
Mar 21 '13 at 22:53
WHat do you mean by
plain old R
?– mnel
Mar 21 '13 at 22:53
2
2
This is a wild guess, and I'm not sure how to test it, but in the question mnel linked to, the point was made that if there is a second reference to the object that the replacement will not be done in place but will result in a copy (and thus not modify the original variable). Perhaps RStudio, as part of its GUI, has references to the object. That is possible since it has an object browser. Or some other aspect which is triggering the copying mechanism rather than the replace-in-place behavior.
– Brian Diggs
Mar 21 '13 at 23:12
This is a wild guess, and I'm not sure how to test it, but in the question mnel linked to, the point was made that if there is a second reference to the object that the replacement will not be done in place but will result in a copy (and thus not modify the original variable). Perhaps RStudio, as part of its GUI, has references to the object. That is possible since it has an object browser. Or some other aspect which is triggering the copying mechanism rather than the replace-in-place behavior.
– Brian Diggs
Mar 21 '13 at 23:12
1
1
I can't reproduce this, same behavior (order matters) in both, RStudio and RGUI (and Eclipse, which uses Rterm).
– Roman Luštrik
Mar 21 '13 at 23:12
I can't reproduce this, same behavior (order matters) in both, RStudio and RGUI (and Eclipse, which uses Rterm).
– Roman Luštrik
Mar 21 '13 at 23:12
1
1
@Arun -- I think that initial comment was a red herring. This isn't a problem with R, so I would be shocked (and not in a good way) if it has changed since the Feb 20th version of R-devel that I'm running...
– Josh O'Brien
Mar 21 '13 at 23:25
@Arun -- I think that initial comment was a red herring. This isn't a problem with R, so I would be shocked (and not in a good way) if it has changed since the Feb 20th version of R-devel that I'm running...
– Josh O'Brien
Mar 21 '13 at 23:25
|
show 15 more comments
1 Answer
1
active
oldest
votes
up vote
36
down vote
accepted
Rstudio's behavior
Rstudio's object browser modifies objects it examines in a way that forces copying upon modification. Specifically, the object browser employs at least one R function whose call internally forces evaluation of the object, in the process resetting the value of the object's named field from 1 to 2. From the R-Internals manual:
When an object is about to be altered, the named field is consulted. A value of 2 means that the object must be duplicated before being changed. [...] A value of 1 is used for situations [...] where in principle two copies of a exist for the duration of the computation [...] but for no longer, and so some primitive functions can be optimized to avoid a copy in this case.
To see that the object browser modifies the named field ([NAM()]
in the next code block), compare the results of running the following lines. In the first, both 'lines' are run together, so that Rstudio has no time to 'touch' X
before its structure is queried. In the second, each line is pasted in separately, so X
is modified before it is examined.
## Pasted in together
x <- 1:10; .Internal(inspect(x))
# @46b47b8 13 INTSXP g0c4 [NAM(1)] (len=10, tl=0) 1,2,3,4,5,...
## Pasted in with some delay between lines
x <- 1:10
.Internal(inspect(x))
# @42111b8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...
Once the named field is set to 2, [<-(X, ...)
will not modify the original object. Pasting the following into Rstudio all at once modifies X
, while pasting it in line-by-line does not:
x <- 1:10
"[<-"(x, 1, 111)
One more consequence of all this is that Rstudio's object browser actually makes some operations slower than they would otherwise be. Again, compare the same two commands first pasted in together, and then one at a time:
## Pasted in together
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0 0 0
## Pasted in one at a time
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0.11 0.04 0.16
Variable behavior of [<- in R
The behavior of [<-
w.r.t. modifying a vector X
depends on the storage types of X
and of the element being assigned into it. This explains R
's behavior but not Rstudio's.
In R, when [<-
either appends to a vector X
, or performs a subassignment that requires that X
's type be modified, X
is copied and the value that is returned does not overwrite the pre-existing variable X
. (To do that you need to do something like X <- "[<-(X, 2, 100)
.
So, neither of the following modify X
X <- 1:2 ## Note: typeof(X) --> "integer"
## Subassignment that requires that X be coerced to "numeric" type
"[<-"(X, 2, 100) ## Note: typeof(100) --> "numeric"
X
# [1] 1 2
## Appending to X
"[<-"(X, 3, 100L)
X
# [1] 1 2
Whenever possible, though, R does allow the [<-
function to modify X
directly by reference (i.e. without making a copy). "Possible" here includes cases in which a sub-assignment doesn't require that X
's type be modified.
So all of the following modify X
X <- c(0i, 0i, 0i, 0i)
"[<-"(X, 1, TRUE)
"[<-"(X, 2, 20L)
"[<-"(X, 3, 3.14)
"[<-"(X, 4, 5+5i)
X
# [1] 1.00+0i 20.00+0i 3.14+0i 5.00+5i
Anybody have a nice reference to R's hierarchy of types, in whichlogical < integer < numeric < complex < character
, and types to the left are automatically converted to types to the right?
– Josh O'Brien
Mar 21 '13 at 23:20
2
I've reproduced your last example and the result was the same, but when before replacing"[<-"(X, 2, 20L)
i run commandtypeof(X)
, then replacing doesn't work (in RGui). Strange.
– BartekCh
Mar 21 '13 at 23:30
Only cran.r-project.org/doc/manuals/r-release/…, which lists them in that order (without specifically mentioning a hierarchy)
– mnel
Mar 21 '13 at 23:35
1
@JoshO'Brien: for reference to the hierarchy use:?Comparison
– 42-
Mar 22 '13 at 0:28
2
I gave a slightly fuller answer on R-Devel, but you don't need to know C to get the gist of the difference betweenclass()
andtypeof()
-- just type them both at the R prompt and note the difference in what's printed.
– mweylandt
Mar 23 '13 at 9:51
|
show 22 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
36
down vote
accepted
Rstudio's behavior
Rstudio's object browser modifies objects it examines in a way that forces copying upon modification. Specifically, the object browser employs at least one R function whose call internally forces evaluation of the object, in the process resetting the value of the object's named field from 1 to 2. From the R-Internals manual:
When an object is about to be altered, the named field is consulted. A value of 2 means that the object must be duplicated before being changed. [...] A value of 1 is used for situations [...] where in principle two copies of a exist for the duration of the computation [...] but for no longer, and so some primitive functions can be optimized to avoid a copy in this case.
To see that the object browser modifies the named field ([NAM()]
in the next code block), compare the results of running the following lines. In the first, both 'lines' are run together, so that Rstudio has no time to 'touch' X
before its structure is queried. In the second, each line is pasted in separately, so X
is modified before it is examined.
## Pasted in together
x <- 1:10; .Internal(inspect(x))
# @46b47b8 13 INTSXP g0c4 [NAM(1)] (len=10, tl=0) 1,2,3,4,5,...
## Pasted in with some delay between lines
x <- 1:10
.Internal(inspect(x))
# @42111b8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...
Once the named field is set to 2, [<-(X, ...)
will not modify the original object. Pasting the following into Rstudio all at once modifies X
, while pasting it in line-by-line does not:
x <- 1:10
"[<-"(x, 1, 111)
One more consequence of all this is that Rstudio's object browser actually makes some operations slower than they would otherwise be. Again, compare the same two commands first pasted in together, and then one at a time:
## Pasted in together
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0 0 0
## Pasted in one at a time
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0.11 0.04 0.16
Variable behavior of [<- in R
The behavior of [<-
w.r.t. modifying a vector X
depends on the storage types of X
and of the element being assigned into it. This explains R
's behavior but not Rstudio's.
In R, when [<-
either appends to a vector X
, or performs a subassignment that requires that X
's type be modified, X
is copied and the value that is returned does not overwrite the pre-existing variable X
. (To do that you need to do something like X <- "[<-(X, 2, 100)
.
So, neither of the following modify X
X <- 1:2 ## Note: typeof(X) --> "integer"
## Subassignment that requires that X be coerced to "numeric" type
"[<-"(X, 2, 100) ## Note: typeof(100) --> "numeric"
X
# [1] 1 2
## Appending to X
"[<-"(X, 3, 100L)
X
# [1] 1 2
Whenever possible, though, R does allow the [<-
function to modify X
directly by reference (i.e. without making a copy). "Possible" here includes cases in which a sub-assignment doesn't require that X
's type be modified.
So all of the following modify X
X <- c(0i, 0i, 0i, 0i)
"[<-"(X, 1, TRUE)
"[<-"(X, 2, 20L)
"[<-"(X, 3, 3.14)
"[<-"(X, 4, 5+5i)
X
# [1] 1.00+0i 20.00+0i 3.14+0i 5.00+5i
Anybody have a nice reference to R's hierarchy of types, in whichlogical < integer < numeric < complex < character
, and types to the left are automatically converted to types to the right?
– Josh O'Brien
Mar 21 '13 at 23:20
2
I've reproduced your last example and the result was the same, but when before replacing"[<-"(X, 2, 20L)
i run commandtypeof(X)
, then replacing doesn't work (in RGui). Strange.
– BartekCh
Mar 21 '13 at 23:30
Only cran.r-project.org/doc/manuals/r-release/…, which lists them in that order (without specifically mentioning a hierarchy)
– mnel
Mar 21 '13 at 23:35
1
@JoshO'Brien: for reference to the hierarchy use:?Comparison
– 42-
Mar 22 '13 at 0:28
2
I gave a slightly fuller answer on R-Devel, but you don't need to know C to get the gist of the difference betweenclass()
andtypeof()
-- just type them both at the R prompt and note the difference in what's printed.
– mweylandt
Mar 23 '13 at 9:51
|
show 22 more comments
up vote
36
down vote
accepted
Rstudio's behavior
Rstudio's object browser modifies objects it examines in a way that forces copying upon modification. Specifically, the object browser employs at least one R function whose call internally forces evaluation of the object, in the process resetting the value of the object's named field from 1 to 2. From the R-Internals manual:
When an object is about to be altered, the named field is consulted. A value of 2 means that the object must be duplicated before being changed. [...] A value of 1 is used for situations [...] where in principle two copies of a exist for the duration of the computation [...] but for no longer, and so some primitive functions can be optimized to avoid a copy in this case.
To see that the object browser modifies the named field ([NAM()]
in the next code block), compare the results of running the following lines. In the first, both 'lines' are run together, so that Rstudio has no time to 'touch' X
before its structure is queried. In the second, each line is pasted in separately, so X
is modified before it is examined.
## Pasted in together
x <- 1:10; .Internal(inspect(x))
# @46b47b8 13 INTSXP g0c4 [NAM(1)] (len=10, tl=0) 1,2,3,4,5,...
## Pasted in with some delay between lines
x <- 1:10
.Internal(inspect(x))
# @42111b8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...
Once the named field is set to 2, [<-(X, ...)
will not modify the original object. Pasting the following into Rstudio all at once modifies X
, while pasting it in line-by-line does not:
x <- 1:10
"[<-"(x, 1, 111)
One more consequence of all this is that Rstudio's object browser actually makes some operations slower than they would otherwise be. Again, compare the same two commands first pasted in together, and then one at a time:
## Pasted in together
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0 0 0
## Pasted in one at a time
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0.11 0.04 0.16
Variable behavior of [<- in R
The behavior of [<-
w.r.t. modifying a vector X
depends on the storage types of X
and of the element being assigned into it. This explains R
's behavior but not Rstudio's.
In R, when [<-
either appends to a vector X
, or performs a subassignment that requires that X
's type be modified, X
is copied and the value that is returned does not overwrite the pre-existing variable X
. (To do that you need to do something like X <- "[<-(X, 2, 100)
.
So, neither of the following modify X
X <- 1:2 ## Note: typeof(X) --> "integer"
## Subassignment that requires that X be coerced to "numeric" type
"[<-"(X, 2, 100) ## Note: typeof(100) --> "numeric"
X
# [1] 1 2
## Appending to X
"[<-"(X, 3, 100L)
X
# [1] 1 2
Whenever possible, though, R does allow the [<-
function to modify X
directly by reference (i.e. without making a copy). "Possible" here includes cases in which a sub-assignment doesn't require that X
's type be modified.
So all of the following modify X
X <- c(0i, 0i, 0i, 0i)
"[<-"(X, 1, TRUE)
"[<-"(X, 2, 20L)
"[<-"(X, 3, 3.14)
"[<-"(X, 4, 5+5i)
X
# [1] 1.00+0i 20.00+0i 3.14+0i 5.00+5i
Anybody have a nice reference to R's hierarchy of types, in whichlogical < integer < numeric < complex < character
, and types to the left are automatically converted to types to the right?
– Josh O'Brien
Mar 21 '13 at 23:20
2
I've reproduced your last example and the result was the same, but when before replacing"[<-"(X, 2, 20L)
i run commandtypeof(X)
, then replacing doesn't work (in RGui). Strange.
– BartekCh
Mar 21 '13 at 23:30
Only cran.r-project.org/doc/manuals/r-release/…, which lists them in that order (without specifically mentioning a hierarchy)
– mnel
Mar 21 '13 at 23:35
1
@JoshO'Brien: for reference to the hierarchy use:?Comparison
– 42-
Mar 22 '13 at 0:28
2
I gave a slightly fuller answer on R-Devel, but you don't need to know C to get the gist of the difference betweenclass()
andtypeof()
-- just type them both at the R prompt and note the difference in what's printed.
– mweylandt
Mar 23 '13 at 9:51
|
show 22 more comments
up vote
36
down vote
accepted
up vote
36
down vote
accepted
Rstudio's behavior
Rstudio's object browser modifies objects it examines in a way that forces copying upon modification. Specifically, the object browser employs at least one R function whose call internally forces evaluation of the object, in the process resetting the value of the object's named field from 1 to 2. From the R-Internals manual:
When an object is about to be altered, the named field is consulted. A value of 2 means that the object must be duplicated before being changed. [...] A value of 1 is used for situations [...] where in principle two copies of a exist for the duration of the computation [...] but for no longer, and so some primitive functions can be optimized to avoid a copy in this case.
To see that the object browser modifies the named field ([NAM()]
in the next code block), compare the results of running the following lines. In the first, both 'lines' are run together, so that Rstudio has no time to 'touch' X
before its structure is queried. In the second, each line is pasted in separately, so X
is modified before it is examined.
## Pasted in together
x <- 1:10; .Internal(inspect(x))
# @46b47b8 13 INTSXP g0c4 [NAM(1)] (len=10, tl=0) 1,2,3,4,5,...
## Pasted in with some delay between lines
x <- 1:10
.Internal(inspect(x))
# @42111b8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...
Once the named field is set to 2, [<-(X, ...)
will not modify the original object. Pasting the following into Rstudio all at once modifies X
, while pasting it in line-by-line does not:
x <- 1:10
"[<-"(x, 1, 111)
One more consequence of all this is that Rstudio's object browser actually makes some operations slower than they would otherwise be. Again, compare the same two commands first pasted in together, and then one at a time:
## Pasted in together
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0 0 0
## Pasted in one at a time
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0.11 0.04 0.16
Variable behavior of [<- in R
The behavior of [<-
w.r.t. modifying a vector X
depends on the storage types of X
and of the element being assigned into it. This explains R
's behavior but not Rstudio's.
In R, when [<-
either appends to a vector X
, or performs a subassignment that requires that X
's type be modified, X
is copied and the value that is returned does not overwrite the pre-existing variable X
. (To do that you need to do something like X <- "[<-(X, 2, 100)
.
So, neither of the following modify X
X <- 1:2 ## Note: typeof(X) --> "integer"
## Subassignment that requires that X be coerced to "numeric" type
"[<-"(X, 2, 100) ## Note: typeof(100) --> "numeric"
X
# [1] 1 2
## Appending to X
"[<-"(X, 3, 100L)
X
# [1] 1 2
Whenever possible, though, R does allow the [<-
function to modify X
directly by reference (i.e. without making a copy). "Possible" here includes cases in which a sub-assignment doesn't require that X
's type be modified.
So all of the following modify X
X <- c(0i, 0i, 0i, 0i)
"[<-"(X, 1, TRUE)
"[<-"(X, 2, 20L)
"[<-"(X, 3, 3.14)
"[<-"(X, 4, 5+5i)
X
# [1] 1.00+0i 20.00+0i 3.14+0i 5.00+5i
Rstudio's behavior
Rstudio's object browser modifies objects it examines in a way that forces copying upon modification. Specifically, the object browser employs at least one R function whose call internally forces evaluation of the object, in the process resetting the value of the object's named field from 1 to 2. From the R-Internals manual:
When an object is about to be altered, the named field is consulted. A value of 2 means that the object must be duplicated before being changed. [...] A value of 1 is used for situations [...] where in principle two copies of a exist for the duration of the computation [...] but for no longer, and so some primitive functions can be optimized to avoid a copy in this case.
To see that the object browser modifies the named field ([NAM()]
in the next code block), compare the results of running the following lines. In the first, both 'lines' are run together, so that Rstudio has no time to 'touch' X
before its structure is queried. In the second, each line is pasted in separately, so X
is modified before it is examined.
## Pasted in together
x <- 1:10; .Internal(inspect(x))
# @46b47b8 13 INTSXP g0c4 [NAM(1)] (len=10, tl=0) 1,2,3,4,5,...
## Pasted in with some delay between lines
x <- 1:10
.Internal(inspect(x))
# @42111b8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...
Once the named field is set to 2, [<-(X, ...)
will not modify the original object. Pasting the following into Rstudio all at once modifies X
, while pasting it in line-by-line does not:
x <- 1:10
"[<-"(x, 1, 111)
One more consequence of all this is that Rstudio's object browser actually makes some operations slower than they would otherwise be. Again, compare the same two commands first pasted in together, and then one at a time:
## Pasted in together
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0 0 0
## Pasted in one at a time
x <- 1:5e7
system.time(x[1] <- 9L)
# user system elapsed
# 0.11 0.04 0.16
Variable behavior of [<- in R
The behavior of [<-
w.r.t. modifying a vector X
depends on the storage types of X
and of the element being assigned into it. This explains R
's behavior but not Rstudio's.
In R, when [<-
either appends to a vector X
, or performs a subassignment that requires that X
's type be modified, X
is copied and the value that is returned does not overwrite the pre-existing variable X
. (To do that you need to do something like X <- "[<-(X, 2, 100)
.
So, neither of the following modify X
X <- 1:2 ## Note: typeof(X) --> "integer"
## Subassignment that requires that X be coerced to "numeric" type
"[<-"(X, 2, 100) ## Note: typeof(100) --> "numeric"
X
# [1] 1 2
## Appending to X
"[<-"(X, 3, 100L)
X
# [1] 1 2
Whenever possible, though, R does allow the [<-
function to modify X
directly by reference (i.e. without making a copy). "Possible" here includes cases in which a sub-assignment doesn't require that X
's type be modified.
So all of the following modify X
X <- c(0i, 0i, 0i, 0i)
"[<-"(X, 1, TRUE)
"[<-"(X, 2, 20L)
"[<-"(X, 3, 3.14)
"[<-"(X, 4, 5+5i)
X
# [1] 1.00+0i 20.00+0i 3.14+0i 5.00+5i
edited Apr 3 '13 at 15:40
answered Mar 21 '13 at 23:17
Josh O'Brien
126k14270380
126k14270380
Anybody have a nice reference to R's hierarchy of types, in whichlogical < integer < numeric < complex < character
, and types to the left are automatically converted to types to the right?
– Josh O'Brien
Mar 21 '13 at 23:20
2
I've reproduced your last example and the result was the same, but when before replacing"[<-"(X, 2, 20L)
i run commandtypeof(X)
, then replacing doesn't work (in RGui). Strange.
– BartekCh
Mar 21 '13 at 23:30
Only cran.r-project.org/doc/manuals/r-release/…, which lists them in that order (without specifically mentioning a hierarchy)
– mnel
Mar 21 '13 at 23:35
1
@JoshO'Brien: for reference to the hierarchy use:?Comparison
– 42-
Mar 22 '13 at 0:28
2
I gave a slightly fuller answer on R-Devel, but you don't need to know C to get the gist of the difference betweenclass()
andtypeof()
-- just type them both at the R prompt and note the difference in what's printed.
– mweylandt
Mar 23 '13 at 9:51
|
show 22 more comments
Anybody have a nice reference to R's hierarchy of types, in whichlogical < integer < numeric < complex < character
, and types to the left are automatically converted to types to the right?
– Josh O'Brien
Mar 21 '13 at 23:20
2
I've reproduced your last example and the result was the same, but when before replacing"[<-"(X, 2, 20L)
i run commandtypeof(X)
, then replacing doesn't work (in RGui). Strange.
– BartekCh
Mar 21 '13 at 23:30
Only cran.r-project.org/doc/manuals/r-release/…, which lists them in that order (without specifically mentioning a hierarchy)
– mnel
Mar 21 '13 at 23:35
1
@JoshO'Brien: for reference to the hierarchy use:?Comparison
– 42-
Mar 22 '13 at 0:28
2
I gave a slightly fuller answer on R-Devel, but you don't need to know C to get the gist of the difference betweenclass()
andtypeof()
-- just type them both at the R prompt and note the difference in what's printed.
– mweylandt
Mar 23 '13 at 9:51
Anybody have a nice reference to R's hierarchy of types, in which
logical < integer < numeric < complex < character
, and types to the left are automatically converted to types to the right?– Josh O'Brien
Mar 21 '13 at 23:20
Anybody have a nice reference to R's hierarchy of types, in which
logical < integer < numeric < complex < character
, and types to the left are automatically converted to types to the right?– Josh O'Brien
Mar 21 '13 at 23:20
2
2
I've reproduced your last example and the result was the same, but when before replacing
"[<-"(X, 2, 20L)
i run command typeof(X)
, then replacing doesn't work (in RGui). Strange.– BartekCh
Mar 21 '13 at 23:30
I've reproduced your last example and the result was the same, but when before replacing
"[<-"(X, 2, 20L)
i run command typeof(X)
, then replacing doesn't work (in RGui). Strange.– BartekCh
Mar 21 '13 at 23:30
Only cran.r-project.org/doc/manuals/r-release/…, which lists them in that order (without specifically mentioning a hierarchy)
– mnel
Mar 21 '13 at 23:35
Only cran.r-project.org/doc/manuals/r-release/…, which lists them in that order (without specifically mentioning a hierarchy)
– mnel
Mar 21 '13 at 23:35
1
1
@JoshO'Brien: for reference to the hierarchy use:
?Comparison
– 42-
Mar 22 '13 at 0:28
@JoshO'Brien: for reference to the hierarchy use:
?Comparison
– 42-
Mar 22 '13 at 0:28
2
2
I gave a slightly fuller answer on R-Devel, but you don't need to know C to get the gist of the difference between
class()
and typeof()
-- just type them both at the R prompt and note the difference in what's printed.– mweylandt
Mar 23 '13 at 9:51
I gave a slightly fuller answer on R-Devel, but you don't need to know C to get the gist of the difference between
class()
and typeof()
-- just type them both at the R prompt and note the difference in what's printed.– mweylandt
Mar 23 '13 at 9:51
|
show 22 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f15559387%2foperator-in-rstudio-and-r%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
It might be worth reading stackoverflow.com/questions/15178507/… -- this is not the same issue however
– mnel
Mar 21 '13 at 22:30
1
WHat do you mean by
plain old R
?– mnel
Mar 21 '13 at 22:53
2
This is a wild guess, and I'm not sure how to test it, but in the question mnel linked to, the point was made that if there is a second reference to the object that the replacement will not be done in place but will result in a copy (and thus not modify the original variable). Perhaps RStudio, as part of its GUI, has references to the object. That is possible since it has an object browser. Or some other aspect which is triggering the copying mechanism rather than the replace-in-place behavior.
– Brian Diggs
Mar 21 '13 at 23:12
1
I can't reproduce this, same behavior (order matters) in both, RStudio and RGUI (and Eclipse, which uses Rterm).
– Roman Luštrik
Mar 21 '13 at 23:12
1
@Arun -- I think that initial comment was a red herring. This isn't a problem with R, so I would be shocked (and not in a good way) if it has changed since the Feb 20th version of R-devel that I'm running...
– Josh O'Brien
Mar 21 '13 at 23:25