简体   繁体   English

在用户定义的函数中操作data.table对象

[英]Manipulate data.table objects within user defined function

I'm trying to write functions that use data.table methods to add and edit columns by reference. 我正在尝试编写使用data.table方法来按引用添加和编辑列的函数。 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. 我已经检查了stackoverflow,发现的唯一线索表明该函数可能正在其他环境或父框架中寻找alpha

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并将它们加载到有R dget ,所以这就是为什么我经常会收到这样的错误。

> dput(foo, "foo.R")
> foo <- dget("foo.R")
> foo(dt)
 Error in `:=` etc...

This problem is a different flavor of the one described in the post Function on data.table environment errors . 这个问题与data.table环境错误一文中的功能有所不同。 It's not exactly a problem, just how dget is designed. 这并不是一个问题,只是dget的设计方式。 But for those curious, this happens because dget assigns the object to parent environment base , and the namespace base isn't data.table aware. 但是对于那些好奇的人来说,发生这种情况是因为dget将对象分配给父环境base ,而命名空间base却不支持data.table

If x is a function the associated environment is stripped. 如果x是一个函数,则剥离关联的环境。 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. 但我认为这里最好的解决方案是使用saveRDS转移[R对象,这是什么?dget建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM