r - Function on data.table environment errors -
can explain me why bar
doesn't work? bug in data.table
?
circles<-data.table(radius=1:10) foo<-function(circ){ circ[,diameter:=2*radius] } dput(x = foo,file = 'func.r') bar<-dget(file = 'func.r') foo(circles) bar(circles)
it has fact dget function sets environment of object returns other .globalenv
. there's easy enough work around, it'll drive rookie me nuts trying figure out why broke in first place.
mydget<-function(file){ temp<-dget(file=file) environment(temp)<-.globalenv return(temp) } bar<-mydget(file = 'func.r')
from dput
:
if x function associated environment stripped. hence scoping information can lost.
parent.env(environment(bar)) # <environment: namespace:base>
both foo(circles)
, bar(circles)
result in [.data.table
getting dispatched, in case bar()
, looking @ traceback()
:
traceback() # 6: stop("check is.data.table(dt) == true. otherwise, := , `:=`(...) defined use in j, once , in particular ways. see help(\":=\").") # 5: `:=`(diameter, 2 * radius) # 4: `[.data.frame`(x, i, j) # 3: `[.data.table`(circ, , `:=`(diameter, 2 * radius)) @ func.r#3 # 2: circ[, `:=`(diameter, 2 * radius)] @ func.r#3 # 1: bar(circles)
as can see [.data.table
dispatches [.data.frame
. happens because of part within [.data.table
:
if (!cedta()) { # fix #5070 (to do) nargs = nargs() - (!missing(drop)) ans = if (nargs<3l) `[.data.frame`(x,i) # drop ignored anyway df[i] else if (missing(drop)) `[.data.frame`(x,i,j) else `[.data.frame`(x,i,j,drop) # added is.data.table(ans) check fix bug #5069 if (!missing(i) & is.data.table(ans)) setkey(ans,null) # see test 304 return(ans) }
here !cedta()
true
in case of bar()
. can confirm cedta
issue setting options(datatable.verbose=true)
, rerunning. get:
# cedta decided 'base' wasn't data.table aware
so cedta()
do?
suppose you're using data.table
objects, , using package that's not aware of data.table
data structure. , let's package has function called funa
. , you're calling function follows:
funa(dt)
now since package isn't data.table aware, using code follows:
funa <- function(...) { .... tmp <- dt[, cols] .... }
here dt[, cols]
not work on data.table due minor differences in data.table's defaults (by default with = true
). , data.table, we'd need dt[, cols, with=false]
.
for code work well, we've identify you're using data.table object on function package doesn't know how subset columns data.table (or in other words, not data.table aware).
and looking @ parent environment of function , gives namespace of package you're using (if you're using package), , check if package imports, or depends on data.table, or if it's 1 of packages we've whitelisted.
this case special (or strange) because function you defined has parent environment base
, , namespace base
isn't data.table aware.
therefore not bug.
?dget
describes not way transfer objects between r sessions (under note
section). saverds
works fine , can use alternative (better) workaround:
saverds(foo, "func.rds") bar <-readrds("func.rds") bar(circles) # works