1

我正在尝试对R中数据框的每一行进行计算,并将计算附加为框架中的新列。我开始使用“by”函数,但计算速度非常慢,所以我改用“apply”函数。我想象它的工作方式是使用我的函数运行 apply ,将输出保存到变量并将该数据附加到原始数据框中。

我创建了一个函数来计算保险计划的期限长度并返回该值,这在样本数据集上运行良好。当我使用较大的数据集时,出现“无法分配大小的向量 ...”的错误。我知道很多人建议使用更多的 RAM,但我已经有 16GB 的内存,并且在R中加载了整个数据集,我的计算机说它只使用了 7.7GB 的内存。该数据集有 44 列,约 1100 万条记录,所以我没有看到再添加一列数据会占用 8GB 内存?

朝着正确方向的任何一点都会很棒。


以下是我正在使用的功能:

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 )
    }

}

我一直在通过调用来运行该函数:

tmp <- apply(policy_data, 1, get_term_length)
4

3 回答 3

5

data.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)]   
于 2012-10-15T05:02:16.210 回答
4

“经验法则”是您将需要 _at_least_ 3 倍于您正在使用的最大对象的连续RAM,因此您可能需要更频繁地重新启动并限制系统上其他正在运行的应用程序的数量。我对拥有 32 GB 的硬件感到相当满意,并且正在研究基于 5-6 GB 大小的数据对象的回归模型。

(我也通常对添加一列数据所花费的时间不满意,所以我有时会创建“外部”或“平行”向量,通常使用 ave() 函数来进行表操作。或者我使用子集()-s 的数据。)R 专家正在研究这个,但尚未公布解决方案。Matthew Dowle 开发了 'data.table' 包来解决它(并且速度非常快),但代价是“[”操作需要不同的语义。

您可以在此处找到其他讨论内存要求的帖子。最常被投票的可能是: 在 R 会话中管理可用内存的技巧。我有点惊讶,那里的答案中没有提到 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)
                 ))

pmin如果您希望该ifelse功能正常工作,您不想使用“na.rm=TRUE” 。

于 2012-08-09T21:22:37.733 回答
3

看起来您不需要整个 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))
于 2012-08-09T21:31:28.110 回答