在函数内部使用setDT

Mat*_*hew 13 r data.table

我正在编写一个函数,除其他外,将输入强制转换为data.table.

library(data.table)
df <- data.frame(id = 1:10)
f <- function(df){setDT(df)}
f(df)
df[, temp := 1]
Run Code Online (Sandbox Code Playgroud)

但是,最后一个命令输出以下警告:

警告消息:在[.data.table(DF, :=(温度,1)):检测到并通过取整个表的副本固定无效.internal.selfref使得:=可以通过参考添加此新列.在较早的时候,此data.table已被R复制(或使用structure()或类似方法手动创建).避免使用键< - ,名称< - 和attr < - 当前(并且奇怪地)在R中可以复制整个data.table.使用set*语法来避免复制:?set,?setnames和?setattr.另外,在R <= v3.0.2中,列表(DT1,DT2)复制了整个DT1和DT2(用于复制命名对象的R列表()); 如果是咬人,请升级到R> v3.0.2.如果此消息没有帮助,请向datatable-help报告,以便修复根本原因.

我正在使用data.table和R 3.1.1的v1.9.3.这是否意味着df在某些时候复制?如何避免这种警告?

编辑:setDT实际使用NSE 的代码.所以这似乎有效:

df1 <- data.frame(id = 1:10)
f <- function(df){eval(substitute(setDT(df)),parent.frame())}
f(df1)
df1[, temp := 1]
Run Code Online (Sandbox Code Playgroud)

看来我可以做其他的东西在函数内DF f

df1 <- data.frame(id = 1:10)
f <- function(df){
      eval(substitute(setDT(df)),parent.frame())
      df[, temp := 1]
      }
f(df1)
Run Code Online (Sandbox Code Playgroud)

这是正确的方法吗?

Aru*_*run 17

好问题!警示说明应当说:...固定通过采取整个表格的副本....会解决这个问题.

setDT 做两件事:

  • 将类设置data.tabledata.frame/list
  • 用于alloc.col过度分配列(以便:=可以直接使用)

如果输入不是已经,则第二步需要浅拷贝data.table.这就是我们分配回其环境中的符号(setDT的父帧)的原因.但是父框架setDT是你的功能f().因此,setDT(df)你的函数内部已经顺利进行,但是df驻留在全局环境中的只会改变它的类,而不是过度分配(因为浅拷贝切断了链接).

在下一步中,:=再次检测到那些和浅拷贝以进行过度分配.

到目前为止,这个想法是在setDT将数据提供给函数之前使用转换为data.tables .但我希望这些案例得到解决(将会看一下).

谢谢你!