在R中组合和过滤每日数据集

时间:2017-08-03 18:56:23

标签: r

我目前正在尝试找到使用大量日常交易数据集的最有效方法。以下是一天数据集的示例:

Date                Time        Name          Price        Quantity 
2005/01/03          012200      Dave          1.40         1  
2005/01/03          012300      Anne          1.35         2  
2005/01/03          015500      Steve         1.54         1  
2005/01/03          021500      Dave          1.44         15  
2005/01/03          022100      James         1.70         7  

在实际数据中,每天有大约40,000行,每天都是一个单独的逗号分隔的.txt文件。数据从2005年一直持续到今天。我只对" Dave"感兴趣和#34;安妮," (以及其他98个名字)但该组中还有成千上万的其他人。有些日子可能有一个给定人的多个条目,有些日子可能没有给定的人。由于存在大量数据,因此提取和组合所有数据的最有效方法是安妮," "戴夫"和其他98个人(理想情况下分为100个单独的数据集)?

我想到的两种方式是:

1)每天过滤到#34; Dave"或者"安妮"然后附加到一个大数据集。

2)将所有日期附加到一个大数据集并过滤到" Dave"或者"安妮。"

哪种方法能给我最有效的结果?还有一种我无法想到的更好的方法吗?

感谢您的帮助!

安迪

2 个答案:

答案 0 :(得分:1)

IMO,如果存储空间不是问题,您应该使用选项2.从长远来看,这为您提供了更大的灵活性(假设您希望将来添加/删除名称)。

总是更容易修剪数据,而不是后悔没有收集它。我选择1的唯一原因是存储或速度是您工作流程的瓶颈。

答案 1 :(得分:1)

我相信这个问题可以通过分析回答。

工作流

正如@Frank指出的那样,该方法可能取决于处理要求:

  • 这是一次性练习吗? 然后可以进一步研究这两种方法的可行性。
  • 这是一项重复的任务,应该添加实际的每日交易数据吗? 然后,如果方法2在每次重复时重新处理整组数据,则效率可能会降低。

内存要求

R将所有数据保存在内存中(除非使用了一个特殊的“大内存”包)。因此,其中一个限制是用于此任务的计算机系统的可用内存。

正如在brittenb's comment中已经指出的那样,有12年的每日数据文件总计为12 * 365 = 4380个文件。每个文件包含大约40 k行。

问题中提供的5行样本数据集可用于通过复制创建40 k行的虚拟文件:

library(data.table)
DT <- fread(
  "Date                Time        Name          Price        Quantity 
  2005/01/03          012200      Dave          1.40         1  
  2005/01/03          012300      Anne          1.35         2  
  2005/01/03          015500      Steve         1.54         1  
  2005/01/03          021500      Dave          1.44         15  
  2005/01/03          022100      James         1.70         7  ",
  colClasses = c(Time = "character")
)
DT40k <- rbindlist(replicate(8000L, DT, simplify = FALSE))

str(DT40k)
Classes ‘data.table’ and 'data.frame':    40000 obs. of  5 variables:
 $ Date    : chr  "2005/01/03" "2005/01/03" "2005/01/03" "2005/01/03" ...
 $ Time    : chr  "012300" "012300" "012300" "012300" ...
 $ Name    : chr  "Anne" "Anne" "Anne" "Anne" ...
 $ Price   : num  1.35 1.35 1.35 1.35 1.35 1.35 1.35 1.35 1.35 1.35 ...
 $ Quantity: int  2 2 2 2 2 2 2 2 2 2 ...
 - attr(*, ".internal.selfref")=<externalptr> 
 - attr(*, "sorted")= chr "Name"
print(object.size(DT40k), units = "Mb")
1.4 Mb

对于方法2,需要至少5.9 Gb(4380 * 1.4 Mb)的内存来保存一个对象中的所有行(未过滤)。

如果您的计算机系统内存有限,那么方法1可能就是您的选择。 OP已经提到他只想保留几千个名称中的100个名称的交易数据。因此,在过滤之后,数据量最终可以减小到原始体积的1%到10%,即,到60Mb到600Mb。

速度

磁盘I / O通常是性能瓶颈。通过data.table包中包含的快速I / O功能,我们可以模拟读取所有4380个文件所需的时间。

# write file with 40 k rows
fwrite(DT40k, "DT40k.csv")

# measure time to read the file
microbenchmark::microbenchmark(
  fread = tmp <- fread("DT40k.csv", colClasses = c(Time = "character"))
)
Unit: milliseconds
  expr      min       lq     mean   median       uq    max neval
 fread 34.73596 35.43184 36.90111 36.05523 37.14814 52.167   100

因此,阅读所有4380个文件应该不到3分钟。