Trying to get rid of this error : cannot allocate vector of size 500 mb

Trying to get rid of this error : cannot allocate vector of size 500 mb

已尝试 gc(),增加 memory.limit(),似乎没有任何效果。使用 64 位 R。 data.frame df 有 3200 万行,大小约为 4 GB; df2 比较小。除了 df 和 df2 之外,我已经从全局环境中删除了所有变量。错误出现在下面 sqldf 代码行之后。

谁能帮我解决 data.table 包中这段代码的等效问题,看看使用它是否能解决堆栈溢出问题:

df <- sqldf(
  'select A.*, 
  case when A.cost is null then B.meancost else A.cost end imputedcost 
  from df A 
  left join df2 B on A.ID = B.ID'
)

我假设您在这里尝试使用 sqldf 进行操作,因为 df 和 df2 非常大,因为 500 mb 本身不足以导致堆栈溢出。跳出两种可能:

  • 您当前在内存中有很多其他数据(df 和 df2 可能非常大)
  • df 和 df2 的左连接占用的内存比错误指示的多

可能的解决方案:

  • 用对内存更友好的东西替换左连接。 table B 内的 meancost 变量是可变的还是静态的?即,这可能只是一个数字吗?
  • 尝试使用 data.table 而不是 sqldf 进行此转换。 sqldf 在这种工作中的计算速度不是很快,这表明它在内存方面的效率可能较低。
  • 将数据集分解成更小的部分,以便 R 可以将其全部放入内存
  • 在旨在处理大型数据转换的实际 SQL 环境中进行这些转换,而不是在所有内容都存储在内存中的 R 中进行。如果愿意,您可以使用 PostgreSQL 通过 R 与 SQL 环境交互。

下面是我可能会用 data.table 来解决这个问题:

# Set up data.tables
library(data.table)
df <- as.data.table(df)
df2 <- as.data.table(df2)

# Combine, just selecting the necessary columns from df2
df <- data.table::merge.data.table(df, df2[, .(ID, meancost)], by = "ID", all.x = T)

# Set imputed cost conditional on cost existing
df[, imputedcost := cost]
df[is.na(cost) | is.null(cost), imputedcost := meancost]

# Remove the meancost column
df[, meancost := NULL]

sqldf 默认使用内存数据库,但您可以通过以下命令让它使用外部数据库。

您无需设置任何内容。它做到了这一切。只需将 dbname = tempfile() 添加到您的 sqldf 语句中。

sqldf(...whatever..., dbname = tempfile())

以下内容不会对内存使用产生任何影响,但请注意,您可以将此查询编写为:

sqldf('select A.*, coalesce(A.cost, B.meancost) as newcost
  from df A
  left join df2 B using(ID)`)