R中的应用函数导致内存分配错误
我试图对R中数据帧的每一行进行计算,并将计算作为新列附加到帧中。我开始使用“by”函数,但计算速度非常慢,所以我改为使用“apply”函数。我想象它的工作方式是使用我的函数运行apply,将输出保存到变量,并将该数据附加到原始数据帧 我创建了一个函数来计算保险计划的期限长度并返回该值,该函数在样本数据集上运行良好。当我使用较大的数据集时,我得到一个错误“无法分配大小的向量…”。我知道很多人建议增加RAM,但我已经有16GB的内存,而且整个数据集都加载在R中,我的电脑说它只使用了7.7GB的内存。数据集有44列,记录约1100万条,所以我不知道再添加一列数据会占用8GB的内存 在正确的方向上的任何一点都是很好的R中的应用函数导致内存分配错误,r,data.table,R,Data.table,我试图对R中数据帧的每一行进行计算,并将计算作为新列附加到帧中。我开始使用“by”函数,但计算速度非常慢,所以我改为使用“apply”函数。我想象它的工作方式是使用我的函数运行apply,将输出保存到变量,并将该数据附加到原始数据帧 我创建了一个函数来计算保险计划的期限长度并返回该值,该函数在样本数据集上运行良好。当我使用较大的数据集时,我得到一个错误“无法分配大小的向量…”。我知道很多人建议增加RAM,但我已经有16GB的内存,而且整个数据集都加载在R中,我的电脑说它只使用了7.7GB的内存。
以下是我正在使用的函数:
get_term_length <- function(row_data){
# convert values to dates
expiration_date <- as.Date( row_data[42] )
start_date <- as.Date( row_data[43] )
cancellation_date <- as.Date( row_data[44] )
# check to see if the cancellation date is NA - just use entire policy length
if( is.na(cancellation_date) ){
return( expiration_date - start_date) )
}
# check to see if policy was cancelled early
if(cancellation_date < expiration_date){
return( cancellation_date - start_date )
}
# the policy was for the entire term
else{
return( expiration_date - start_date )
}
}
get_term_length经验法则是,您需要的连续RAM至少是您正在使用的最大对象的3倍,因此您可能需要更频繁地重新启动,并限制系统上其他正在运行的应用程序的数量。我对我的32 GB硬件相当满意,并且正在基于5-6 GB大小的数据对象建立回归模型
(我通常也对添加一列数据所需的时间感到不满,因此我有时会创建“外部”或“并行”向量,通常使用ave()函数进行表操作。或者我使用数据的子集()-s。)R专家们目前正在处理这一问题,但还没有公布解决方案。Matthew Dowle开发了“data.table”包来解决它(而且速度非常快),代价是“[”操作需要不同的语义
您可以在此处找到其他讨论内存需求的帖子。最常被投票的帖子可能是:
.我有点惊讶,答案中没有提到data.table包
编辑:我看到了您接受的答案(这实际上是处理数据子集的一个实例),但我认为这与您之前得到的结果不同。要获得该结果,您需要以下内容:
tmp <- with(policy_data,
ifelse( is.na(cancellation_date), expiration_date - start_date , # else
pmin(as.Date(cancellation_date)-as.Date(start_date),
as.Date(expiration_date)-as.Date(start_date)
))
tmp经验法则您需要的连续RAM至少是您正在使用的最大对象的3倍,因此您可能需要更频繁地重新启动,并限制系统上其他正在运行的应用程序的数量。我对我的32 GB硬件相当满意,并且正在基于5-6 GB的数据对象建立回归模型n码
(我通常也不满意添加一列数据所需的时间,因此我有时会创建“外部”或“并行”向量,通常使用ave()函数进行表操作。或者我使用数据的子集()R大师正在研究这个问题,但目前还没有公布解决方案。Matthew Dowle开发了“data.table”包来解决这个问题(而且速度非常快),代价是“[”操作需要不同的语义
您可以在此处找到其他讨论内存需求的帖子。最常被投票的帖子可能是:
.我有点惊讶,答案中没有提到data.table包
编辑:我看到了您接受的答案(这实际上是处理数据子集的一个实例),但我认为这与您之前得到的结果不同。要获得该结果,您需要以下内容:
tmp <- with(policy_data,
ifelse( is.na(cancellation_date), expiration_date - start_date , # else
pmin(as.Date(cancellation_date)-as.Date(start_date),
as.Date(expiration_date)-as.Date(start_date)
))
tmp看起来不需要整个data.frame。只需提取所需的3列,就可以恢复大部分内存
tmp <- with(policy_data,
pmin(as.Date(cancellation_date)-as.Date(start_date),
as.Date(expiration_date)-as.Date(start_date),
na.rm=TRUE))
tmp看起来不需要整个data.frame。只需提取所需的3列,就可以恢复大部分内存
tmp <- with(policy_data,
pmin(as.Date(cancellation_date)-as.Date(start_date),
as.Date(expiration_date)-as.Date(start_date),
na.rm=TRUE))
tmpAdata.table
如@Dwin所暗示的解决方案
library(data.table)
policy_data <- as.data.table(policy_data)
# set the date columns to be IDate (the exact form of this will depend
# on the format they are currently in
policy_data[, cancellation_date := as.IDate(cancellation_date)]
policy_data[, start_date := as.IDate(start_date)]
policy_data[, end_date := as.IDate(end_date)]
# create a column which is an indicator for NA
policy_data[, isna := is.na(cancellation_date)]
setkey(policy_data, isna)
policy_data[J(TRUE), tmp := expiration_date - start_date]
policy_data[J(FALSE), tmp := pmin(cancellation_date - start_date, expiration_date-start_date)]
库(data.table)
政策数据Adata.table
如@Dwin所暗示的解决方案
library(data.table)
policy_data <- as.data.table(policy_data)
# set the date columns to be IDate (the exact form of this will depend
# on the format they are currently in
policy_data[, cancellation_date := as.IDate(cancellation_date)]
policy_data[, start_date := as.IDate(start_date)]
policy_data[, end_date := as.IDate(end_date)]
# create a column which is an indicator for NA
policy_data[, isna := is.na(cancellation_date)]
setkey(policy_data, isna)
policy_data[J(TRUE), tmp := expiration_date - start_date]
policy_data[J(FALSE), tmp := pmin(cancellation_date - start_date, expiration_date-start_date)]
库(data.table)
策略数据查看data.table
和操作符:=
(例如,使用标记[r]
和[data.table]
搜索SO)它的要点是:R本质上是一种函数式语言->一般来说,函数不会就地修改对象->修改你说的7.7Gb数据帧?当然!我会准备一份副本来处理!->你现在已经填充了超过15Gb的空间。砰!(专家们,请不要吹毛求疵!我保持基本。)感谢joran的解释;这很有意义。我假设apply只会将row对象的副本传递给函数,但我猜不会。根本问题可能是您熟悉SAS或SPSS的IF函数的隐式循环。R IF()函数不执行循环操作,因此您需要使用ifelse()。查看数据.表格
和运算符:=
(例如,使用标记[r]
和[data.table]
搜索SO)它的要点是:R本质上是一种函数式语言->一般来说,函数不会就地修改对象->修改你说的7.7Gb数据帧?当然!我会准备一份副本来处理!->你现在已经填充了超过15Gb的空间。砰!(专家们,请不要吹毛求疵!我保持基本。)感谢joran的解释;这很有意义。我假设apply只会将row对象的副本传递给函数,但我猜不会。根本问题可能是您熟悉SAS或SPSS的IF函数的隐式循环。R IF()函数不执行循环操作,因此您需要使用ifelse()。这也将加快数百倍。这非常有效!它运行速度超快,处理整个数据集的速度比使用函数的示例集快