R 正在尝试消除此错误:无法分配大小为500 mb的向量

R 正在尝试消除此错误:无法分配大小为500 mb的向量,r,memory-management,garbage-collection,data.table,sqldf,R,Memory Management,Garbage Collection,Data.table,Sqldf,尝试了gc(),增加了memory.limit(),但似乎没有任何效果。使用64位R。data.framedf有3200万行,大小约为4GB;df2相对较小。除了df和df2之外,我已经从全局环境中删除了所有变量。错误出现在下面的sqldf代码行之后 是否有人可以帮助我在data.table包中使用与此代码等效的代码,以查看使用此代码是否可以解决堆栈溢出问题: df <- sqldf( 'select A.*, case when A.cost is null then B.me

尝试了
gc()
,增加了
memory.limit()
,但似乎没有任何效果。使用64位R。data.frame
df
有3200万行,大小约为4GB;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'
)

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

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

  • 将左连接替换为内存更友好的连接。平均成本在表B中是可变的还是静态的?i、 这可能只是一个数字吗
  • 尝试使用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]
#设置数据表
库(数据表)

默认情况下,df
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)`)

谢谢。除了df和df2之外,我已经从全局env中删除了所有其他变量,但是我仍然得到了这个错误。您可以使用
object.size()
查看df和df2的大小。我怀疑它们正在消耗R的大部分可用内存,您需要将它们加载到PostgreSQL或类似程序中,以使用可用内存对它们进行整体操作。另一种选择是将它们分成更小的部分(例如,一次只能读取一半的行)。当我试图运行代码时,它会说:“merge”不是从“namespace:data.table”导出的对象df:4020986780的大小,df2:8964578的大小您可能需要
data.table::merge.data.table()
;更新答案。如果我读对了,你有一个4GB的df对象,当连接到df2时,它会变得更大。这可能是罪魁祸首;将数据集分解为更小的组件或使用外部数据库。