Since R3.0, a for
loop returns NULL
(as documented):
x <- for(i in 1:3) {i+1}
x
# NULL
However, using the right-arrow assignment, it seems to returns the last value:
for(i in 1:3) {i+1} -> x
x
# [1] 4
The documentation doesn't comment on ->
, and as pointed by Ben Bolker, the ->
seems to be converted to <-
anyway:
expression(1 -> x)
# expression(x <- 1)
So my questions are:
->
behave differently from <-
in that case, if they're supposed to be identical?Really this is more of an issue of parsing I think. The command
for(i in 1:3) {i+1} -> x
actually is parsed to something like
for(i in 1:3) {
x <- {i+1}
}
You can kind of see that in the AST with the help of the lobstr
package
lobstr::ast(for(i in 1:3) {i+1} -> x)
o-`for`
+-i
+-o-`:`
| +-1
| \-3
\-o-`<-`
+-x
\-o-`{`
\-o-`+`
+-i
\-1
So the assignment is part of the loop body. For example you can also run this without error
for(i in 1:3) {i+1} ^2
or see what you get from this expression
for(i in 1:3) {i+1} + {print(i)}
# [1] 1
# [1] 2
# [1] 3
The loop body expression doesn't terminate at the end of the first brace. It ends at the end of the line (or you could make it end with a ;
or by nesting it in a code block). This isn't unique to the assignment operators in any way.
So this isn't a bug, it's just a bit of confusing syntax. What you were expecting would look more like
{for(i in 1:3) {i+1}} -> x
which still returns NULL.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With