require(data.table)
dt = data.table(x=c(1,1,2,2,2), y=1, z=2)
vv = 6
dt[, get("vv")] # works fine
# ?!?!?
dt[, mget("vv")]
# Error: value for ‘vv’ not found
Is this a bug? Haven't had time to look into it yet.
Yea something's pretty messed up...
I get SDenv$.SDall to be:
# x y z x.x x.y x.z
# 1: 1 1 2 1 1 2
# 2: 1 1 2 1 1 2
# 3: 2 1 2 2 1 2
# 4: 2 1 2 2 1 2
# 5: 2 1 2 2 1 2
No way it should be calculating all that!
That said, here is a much simplified version of the error:
f <- function(...){
fenv <- new.env()
eval(substitute(get("vv")), fenv, parent.frame())}
f()
# [1] 6
g <- function(...){
fenv <- new.env()
eval(substitute(mget("vv")), fenv, parent.frame())}
g()
Error: value for ‘vv’ not found
This is simply because get has inherits = TRUE as default while mget has inherits = FALSE as default. Hence both dt[, mget("vv", inherits = TRUE)] and dt[, mget("vv", envir = as.environment(1))] work.
That handles that... curious that they have different defaults, any guesses why? Nothing in the dox.
Also, explains why dt[,{vv = 6; mget("vv")}] works (and hence this problem took so long to surface)
@DavidArenburg great! Thanks.
NP, @arunsrinivasan. But why do you think it's a bug? It has nothing to do with data.table and this is a documented/intended behavior in base R...
The idea is that mget() for data.table could be consistent with what one expects within the frame of a data.table, however inconsistent base R is between get() and mget().
So you plan to overload mget within data.table? Or silently add inherits = TRUE when detecting mget in jsub?
Neither seem ideal to me...
inherits=TRUE.
I think it'd be pretty complicated in general to handle this. Tried a simple approach of treating mget like strptime and defining SDenv$mget:
SDenv$mget = function(...) {
if ('inherits' %chin% names(list(...))) mget(...) else mget(..., inherits = TRUE)
}
But this doesn't work as hoped. Unless there's something simple I'm missing I'd say we abandon this
I agree with Michael that it does seems to complicated to handle that. We already know that inherits was responsible for a difference in question. I would advise to use a more general substitution #4304 rather than lookup up symbols in frames via get/mget. Please re-open if you do not agree.
Most helpful comment
This is simply because
gethasinherits = TRUEas default whilemgethasinherits = FALSEas default. Hence bothdt[, mget("vv", inherits = TRUE)]anddt[, mget("vv", envir = as.environment(1))]work.