0

I'm trying to write functions that use data.table methods to add and edit columns by reference. However, the same code that work in the console does not work when called from within a function. Here is a simple examples:

> dt <- data.table(alpha = c("a","b","c"), numeric = 1:3)
> foo <- function(x) {
    print(is.data.table(x))
    x[,"uppercase":=toupper(alpha)]
}

When I call this function, I get the following error.

> test = foo(dt)
[1] TRUE
 Error in `:=`("uppercase", toupper(alpha)) : 
 Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are
 defined for use in j, once only and in particular ways. See help(":="). 

Yet if I type the same code directly into the console, it works perfectly fine.

> dt[,"uppercase":=toupper(alpha)]
> dt
   alpha numeric uppercase
1:     a       1         A
2:     b       2         B
3:     c       3         C

I've scoured stackoverflow and the only clues I could find suggest that the function might be looking for alpha in a different environment or parent frame.

EDIT: More information to reproduce the error. The function is not within a package, but declared directly in the global environment. I didn't realize this before, but in order to reproduce the error I need to dump the function to a file, then load it. I've saved all of my personal functions via dput and load them into R with dget, so that's why I get this error often.

> dput(foo, "foo.R")
> foo <- dget("foo.R")
> foo(dt)
 Error in `:=` etc...
3
  • 1
    I don't see that error. Perhaps you need to upgrade to version 1.9.6 of the package, currently on CRAN. By the way, because foo modifies dt, you don't need to assign the result like test = foo(dt); just do foo(dt) and you'll see that dt itself is changed. Commented Oct 20, 2015 at 16:25
  • 1
    is your function inside a package? if so be sure you have data.table imported in NAMESPACE Commented Oct 20, 2015 at 16:36
  • not inside a package, but loaded manually with dget() or with source(). Perhaps that has something to do with why my functions can't access data.table methods? @Frank you're right, I tend to forget that := changes the data.table without need for assigning a new object. Commented Oct 23, 2015 at 13:32

1 Answer 1

1

This problem is a different flavor of the one described in the post Function on data.table environment errors. It's not exactly a problem, just how dget is designed. But for those curious, this happens because dget assigns the object to parent environment base, and the namespace base isn't data.table aware.

If x is a function the associated environment is stripped. Hence scoping information can be lost.

One workaround is to assign the function to the global enviornment:

> environment(foo) <- .GlobalEnv

But I think the best solution here is to use saveRDS to transfer R objects, which is what ?dget recommends.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.