[英]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.