【问题标题】:Wrapper functions for data.tabledata.table 的包装函数
【发布时间】:2014-10-21 01:09:38
【问题描述】:

我有一个已经使用 data.frame 上下文编写的项目。为了改善计算时间,我试图利用使用 data.table 的速度来代替。我的方法是构建读取帧的包装函数,将它们转换为表格,进行计算,然后再转换回帧。这是一个简单的例子......

FastAgg<-function(x, FUN, aggFields, byFields = NULL, ...){
  require('data.table')
  y<-setDT(x)
  y<-y[,lapply(X=.SD,FUN=FUN,...),.SDcols = aggFields,by=byFields]
  y<-data.frame(y)
  y
}

我遇到的问题是,在运行此函数后 x 已转换为表格,然后我使用 data.frame 表示法编写的代码行失败。如何确保我输入的 data.frame 没有被运行函数改变?

【问题讨论】:

  • 哇,即使这样做也会改变原来的 data.frame,这是我没想到的:dat &lt;- data.frame(a=1); dat2 &lt;- dat; setDT(dat2); is.data.table(dat); 老实说,这对我来说似乎有问题。
  • 使用as.data.table 而不是setDT
  • @AnandaMahto - 这似乎确实有效。我收集setDT 会导致问题,因为它在不复制的情况下更改对象,&lt;- 在我的示例中可能不会这样做,直到有其他东西作用于它。
  • @thelatemail,如果您查看 R 公共房间,我最近在向 Arun 询问相关的事情。建议在函数中使用as.data.table 代表data.frames 和copy 代表data.tables。

标签: r data.table


【解决方案1】:

对于您的情况,我建议(当然)使用data.table 而不仅仅是在函数中使用:-)。

但如果这不太可能发生,那么我建议使用 setDT + setDF 设置。我建议在函数外部使用setDT(并提供 data.table 作为输入) - 通过引用将 data.frame 转换为 data.table,然后在完成所需的操作后,您可以使用setDF 使用 setDF 将结果转换回 data.frame 并从函数中返回。但是,执行 setDT(x) 会将 x 更改为 data.table - 因为它通过引用进行操作。

如果这不理想,那么在你的函数中使用as.data.table(.),因为它对副本进行操作。然后,您仍然可以使用setDF() 将生成的 data.table 转换为 data.frame 并从您的函数中返回该 data.frame。

这些功能是最近引入的(主要是由于用户请求)。避免这种混淆的想法是导出shallow() 函数并跟踪需要复制列的对象,并在内部(自动)完成所有操作。现在这一切都处于非常早期的阶段。当我们成功后,我会更新这篇文章。


还可以查看?copy?setDT?setDF。这些函数帮助页面的第一段是:

data.table 的说法中,所有set* 函数都通过引用更改其输入。也就是说,除了临时工作内存(与一列一样大)之外,根本不进行任何复制。通过引用修改输入的唯一其他data.table 运算符是:=。查看下面的See Also 部分,了解set* data.table 提供的其他功能。

还有setDT的例子:

set.seed(45L)
X = data.frame(A=sample(3, 10, TRUE), 
         B=sample(letters[1:3], 10, TRUE), 
         C=sample(10), stringsAsFactors=FALSE)

# get the frequency of each "A,B" combination
setDT(X)[, .N, by="A,B"][]

没有分配(虽然我承认这里可以稍微解释一下)。

setDF:

X = data.table(x=1:5, y=6:10)
## convert 'X' to data.frame, without any copy.
setDF(X)

我认为这很清楚。但我会尽量提供更清晰的说明。此外,我还将尝试在文档中添加如何最好地使用这些功能。

【讨论】:

  • 我非常感谢您建议在整个过程中简单地使用 data.table,这既是因为学习曲线似乎更少(来自 SQL 背景),而且因为速度要好得多。当然,我确信您可以理解我不想为我的所有项目重写我的所有代码。 :-P
猜你喜欢
  • 2021-05-06
  • 1970-01-01
  • 2018-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多