Hello!
Minimal reproducible example:
library(data.table)
f = function(flag = FALSE) {
dt1 = data.table(a = 1)
dt2 = data.table(a = 1)
dt3 = dt1[, .(a, b = 0)]
print(body(f))
if (flag) dt3[dt2, b := 999, on = "a"]
print(body(f))
return(invisible(dt3))
}
f(flag = FALSE)
f(flag = TRUE)
> f(flag = FALSE)
{
dt1 = data.table(a = 1)
dt2 = data.table(a = 1)
dt3 = dt1[, .(a, b = 0)]
print(body(f))
if (flag)
dt3[dt2, `:=`(b, 999), on = "a"]
print(body(f))
return(invisible(dt3))
}
{
dt1 = data.table(a = 1)
dt2 = data.table(a = 1)
dt3 = dt1[, .(a, b = 0)]
print(body(f))
if (flag)
dt3[dt2, `:=`(b, 999), on = "a"]
print(body(f))
return(invisible(dt3))
}
> f(flag = TRUE)
{
dt1 = data.table(a = 1)
dt2 = data.table(a = 1)
dt3 = dt1[, .(a, b = 0)]
print(body(f))
if (flag)
dt3[dt2, `:=`(b, 999), on = "a"]
print(body(f))
return(invisible(dt3))
}
{
dt1 = data.table(a = 1)
dt2 = data.table(a = 1)
dt3 = dt1[, .(a, b = 999)]
print(body(f))
if (flag)
dt3[dt2, `:=`(b, 999), on = "a"]
print(body(f))
return(invisible(dt3))
}
As you can see, after assigning (:=) a new value to column "b" (when flag is TRUE), the body of "f" function is changed on the line "dt3 = ..." ("b = 0" is replaced by "b = 999"). The result of function run will then be different when executing it with FALSE flag value.
Output of sessionInfo():
R version 3.5.1 (2018-07-02)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7600)
Matrix products: default
locale:
[1] LC_COLLATE=Russian_Russia.1251 LC_CTYPE=Russian_Russia.1251 LC_MONETARY=Russian_Russia.1251
[4] LC_NUMERIC=C LC_TIME=Russian_Russia.1251
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] data.table_1.12.3
loaded via a namespace (and not attached):
[1] compiler_3.5.1 tools_3.5.1 yaml_2.2.0
Thanks for the great report! I can also reproduce in v1.12.2 too.
@mattdowle , Thanks!
After further investigations it comes out that there is no need for a wrapper-function.
Here is a concise example for this issue:
library(data.table)
value = 0
dt1 = data.table(a = 1)
dt2 = dt1[, .(a, b = ..value)]
dt2[1, b := 999]
print(value)
Thanks. I found the line at fault yesterday and did wonder that it might not be wrapper only. So it's really good to have an example already. WIP ...
Related #3766. Thanks @kirillmayantsev for not giving up on us!
Most helpful comment
@mattdowle , Thanks!
After further investigations it comes out that there is no need for a wrapper-function.
Here is a concise example for this issue: