将字符串列表分解为分区

RJ-*_*RJ- 5 r subset plyr data.table

这是我的问题.我有一个200k行的数据集.

  • 每行对应于对受试者进行的测试.
  • 受试者的测试数量不等.
  • 每个测试都是过时的.

我想为每个测试分配一个索引.例如,对象1的第一次测试将是1,对象1的第二次测试将是2.对象2的第一次测试将是1等.

我的策略是获取唯一主题ID的列表,使用lapply将数据集子集化为使用唯一主题ID的数据帧列表,每个主题具有他/她自己的数据帧并进行测试.理想情况下,我可以对每个主题的每个数据帧进行排序,并为每个测试分配一个索引.

但是,在200k x 32的数据帧上进行此操作使我的笔记本电脑(i5,Sandy Bridge,4GB内存)很快耗尽内存.

我有两个问题:

  1. 有一个更好的方法吗?
  2. 如果没有,我唯一的选择是克服内存限制是将我的唯一SubjectID列表分解为更小的集合,例如每个列表1000个SubjectID,通过数据集提供它,并在所有内容的末尾将列表连接在一起.然后,如何创建一个函数来打破我的SubjectID列表,方法是提供一个表示分区数的整数.例如,BreakPartition(数据集,5)将数据集分成5个分区.

这是生成一些虚拟数据的代码:

UniqueSubjectID <- sapply(1:500, function(i) paste(letters[sample(1:26, 5, replace = TRUE)], collapse =""))
UniqueSubjectID <- subset(UniqueSubjectID, !duplicated(UniqueSubjectID))
Dataset <- data.frame(SubID = sample(sapply(1:500, function(i) paste(letters[sample(1:26, 5, replace = TRUE)], collapse ="")),5000, replace = TRUE))
Dates <- sample(c(dates = format(seq(ISOdate(2010,1,1), by='day', length=365), format='%d.%m.%Y')), 5000, replace = TRUE)
Dataset <- cbind(Dataset, Dates)
Run Code Online (Sandbox Code Playgroud)

lei*_*eif 5

我猜测分裂/ lapply是用尽内存的东西.您应该考虑采用更加矢量化的方法.从稍微修改的示例代码版本开始:

n <- 200000
UniqueSubjectID <- replicate(500, paste(letters[sample(26, 5, replace=TRUE)], collapse =""))
UniqueSubjectID <- unique(UniqueSubjectID)
Dataset <- data.frame(SubID = sample(UniqueSubjectID , n, replace = TRUE))
Dataset$Dates <- sample(c(dates = format(seq(ISOdate(2010,1,1), by='day', length=365), format='%d.%m.%Y')), n, replace = TRUE)
Run Code Online (Sandbox Code Playgroud)

假设您想要的是按主题按日期顺序计算测试的索引,您可以执行以下操作.

Dataset <- Dataset[order(Dataset$SubID, Dataset$Dates), ]
ids.rle <- rle(as.character(Dataset$SubID))
Dataset$SubIndex <- unlist(sapply(ids.rle$lengths, function(n) 1:n))
Run Code Online (Sandbox Code Playgroud)

现在,'数据集'中的'SubIndex'列包含测试的副主题编号索引.这需要非常少的内存,并在我的4GB Core 2 duo笔记本电脑上运行几秒钟.