如何使这个 R data.table 代码更节省内存?

Posted

技术标签:

【中文标题】如何使这个 R data.table 代码更节省内存?【英文标题】:How to make this R data.table code more memory-efficient? 【发布时间】:2015-03-12 23:21:37 【问题描述】:

我有两个真实的data.table 代码示例,它们可以正常工作,但似乎消耗的内存比我预期的要多,我非常感谢有关如何使这段代码更节省内存的想法。

A = data.table(a=c(rep(1,5),rep(2,5)), b1=2:11, b2=22:31, c=c(1,2,1,2,1,2,1,2,1,2))

# Example 1:
# Pick the column name (b1 or b2) based on the value in column a 
# and assign the value from <b1 or b2> by reference to column res
setkey(A, a, c)
A[, res:=get(paste0("b", a)), by=c("a", "c")] 

# Example 2:
# Group the values of A by key, saving the following: 
# 1) number of values in column res that meet some condition
# 2) the minimum value of column a
setkey(A, c)
z = A[, list(length(.I[res>5]), min(res)), by=c]

我使用lineprof 使用更大的真实数据对它们进行了测试,在整个使用data.tables 的代码中它们是异常值。

# This is more like the real size of the data I'm dealing with
A = data.table(a=c(rep(1,5e6),rep(2,5e6)), 
               b1=1:5e6, b2=(5e6+1):10e6, 
               c=round(runif(1e7, min=1, max=2)))

任何建议将不胜感激!

【问题讨论】:

感谢@David 的编辑 - 很好发现! 我认为第二个问题你可以做A[, .(sum(res&gt;5), min(res)), by=c] 您也不应该在每次迭代中调用 paste,您可以使用 do.call 调用一次,然后仅在 get 上迭代,例如 A[, temp := do.call(paste0, list("b", a))][, res := get(temp), .(a, c)] 虽然 mnel 二进制搜索会更多高效。 @mnels 二进制连接不是更有效吗?我不明白。 您的data.table 版本是什么?当前开发1.9.5 中修复了一些不需要的泄漏(来自 1.9.2/1.9.4)。 【参考方案1】:

如果示例 1 只是使用 by = list(a,c) 逐行处理,那么 get 可以工作,那么

setkey(A,a)
A[.(1), res := b1]
A[.(2), res:= b2]

应该更有效率

例如 2,通过 res 排序/键控也可以提高性能

setkey(A, c,res)
z = A[, list(length(.I[res>5]),(res[1])), by=c]

【讨论】:

谢谢!实际上,我尝试按照您在第一个示例中的建议进行操作,并且花费了绝对的时间(我在现实生活中获得了 75 个级别)。现在将尝试第二个示例! 你有 75 b cols 吗?如果是,需要多长时间:A[.(a=1:75), res := get(paste0("b", i.a)), by=.EACHI] 新闻中记录了 i.a 语法。 i.a 组件表示您想从 i 参数而不是 j 的范围中获取“a”。 (@arun 的建议很棒) 我写了一个愉快的回复,但后来注意到在我的例子中,由于某种原因,这个示例未能遍历a 的级别......

以上是关于如何使这个 R data.table 代码更节省内存?的主要内容,如果未能解决你的问题,请参考以下文章

R data.table:如何使用包含列名的 R 变量?

通过R中的列的cumsum拆分data.table

R data.table 从剪贴板读取

R语言data.table导入数据实战:data.table进行多表数据连接(mergejoin)内连接左连接外连接

使用 data.table 包滚动平均值到 R 中的多个变量

data.table中的R rowsum崩溃R.