在函数中使用data.table

时间:2014-08-14 12:38:22

标签: r data.table

我有list data.table个,我想在应用list之前修改rbindlist元素。特别是,我想删除不相同的列,添加一个包含特定list元素名称的列,并设置列的固定顺序,以便右列被绑定(一种模仿ldply包中plyr的行为。我将所有这些步骤包装到mapply中,以便它在这个示例中看起来像:

library(data.table)
file_list <- list(cars1 = as.data.table(cars),
                  cars2 = as.data.table(cars),
                  cars3 = as.data.table(cars))
 # creating a column that is not contained in the other list elements
file_list$cars1[,speed2 := speed*100]

common_cols <- c("dist", "speed")

list_to_bind <- mapply(function(DT, DTname){
  cols_to_delete <- setdiff(colnames(DT), common_cols)
  if (length(cols_to_delete) > 0)
    DT[, cols_to_delete := NULL, with = FALSE]
  DT[, elemname := DTname]
  setcolorder(DT, c("elemname", common_cols))
  return(DT)
}, file_list, names(file_list), SIMPLIFY = FALSE)

运行此代码会产生以下警告:

  

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

以下修改后的mapply命令不会导致出现此警告:

list_to_bind <- mapply(function(DT, DTname){
  DT2 <- copy(DT)
  cols_to_delete <- setdiff(colnames(DT2), common_cols)
  if (length(cols_to_delete) > 0)
    DT2[, cols_to_delete := NULL, with = FALSE]
  DT2[, elemname := DTname]
  setcolorder(DT2, c("elemname", common_cols))
  return(DT2)
}, file_list, names(file_list), SIMPLIFY = FALSE)

我假设,警告是由于R在没有显式copy命令的情况下将实际参数的副本传递给函数的事实。但是,为什么此警告仅发生在DT[, elemname := DTname]而不是更早? R是否还要使用list元素的副本来执行DT2 <- copy(DT)命令(即,获取DT)?或者,如果它仅在更改元素时复制元素,为什么不在DT[, cols_to_delete := NULL, with = FALSE]处抛出警告?

0 个答案:

没有答案