R - 以数据帧列表为条件的快速子集化大数据表

时间:2015-08-15 04:32:36

标签: r data.table subset large-data

我有一个数据表和一个格式如下的数据框列表:

require(data.table)
members = c('a','b','c')
DT = do.call('rbind',
         lapply(members, function(x){
             date = seq(as.Date("2015/1/1"), as.Date("2015/12/31"), 'days')
             dummy = sample(length(date))
             dt = data.table(member=sample(x, length(dummy), replace=TRUE), date=date, dummy=dummy)} 
         )
     )

date = seq(as.Date("2015/1/1"), as.Date("2015/12/31"), 'days')
l.members = lapply(members, function(x){
                n.period = sample(10,1)
                do.call('rbind',
                    lapply(1:n.period, function(y){
                        period = sample(date, 2)
                        if (period[1]>period[2]){
                            start=period[2]
                            due=period[1]
                        }else{
                            start=period[1]
                            due=period[2]
                        }
                        return(data.frame(start.date=start, due.date=due))}
                    )
                )
            })
names(l.members) = members

DT是一个较大的(大约4G为csv文件)数据表,我希望根据l.members对其进行子集化。 l.members中的每个条目 x 都是unique(DT$member)中的成员之一。在每个条目中都有一个数据框,每行代表一个句点[ p1 p2 ],我希望根据这个句子对DT中的行进行子集化。 DT$member x DT$date => p1 DT$date< = p2 。目前的解决方法如下:

l.member.periods = lapply(members,
                       function(x){
                           DT.member = DT[member==x]
                           apply(l.members[[x]], 1,
                               function(y){
                                   start = y[1]
                                   due = y[2]
                                   return(DT.member[date>=start&date<=due])
                               }
                           )
                        }
                   )

l.members中有大约5000个条目需要几十年,每个条目大多有10行(句点)。我尝试用lapply替换mclapply,但似乎无法正常工作,最终会干掉内存并挂起。我怎样才能加快这个过程?

1 个答案:

答案 0 :(得分:3)

您可以使用l.members。 首先,您需要将data.table存储为lmembers <- rbindlist(lapply(1:length(l.members), function(i)data.table(member=names(l.members)[i], l.members[[i]], keep.rownames = TRUE))) > head(lmembers) member rn start.date due.date 1: a 1 2015-03-30 2015-04-29 2: a 2 2015-03-25 2015-12-07 3: a 3 2015-02-06 2015-03-01 4: a 4 2015-09-19 2015-11-08 5: a 5 2015-06-23 2015-08-27 6: a 6 2015-04-22 2015-10-08

foverlaps

下一步是明显使用setkey(lmembers, "member", "start.date", "due.date") DT[, date1:=date,] setkey(DT, "member","date", "date1") lmemberperiods <- foverlaps(lmembers, DT)[, .(member, rn, date, dummy)]

lmemberperiods[member=="a" & rn==1]
l.member.periods[[1]][[1]]

检查这是否会产生预期结果。

Yii::$app->request->queryParams['DataSearch']["TANGGAL_SELESAI"]
Yii::$app->request->queryParams['DataSearch']["TANGGAL"]