1

我有一个文件,它比我的计算机上的总 RAM 大大约 10 倍。我试图将它读入一个 R 对象,让我查看它并提取更易于管理的块。我尝试了各种方法来解决这个问题,但都遇到了问题——不同的问题——每种方法。我有一个固定宽度格式的文件副本,另一个是 CSV 文件。我相信这些文件在其他方面是相同的。我已经能够读取前 5000 行,并且对于固定宽度文件中的每一列都有一个暂定的字段宽度,并且对于两个文件的每一列都有一个暂定的数据类。在这一点上,我不是在问如何实现我的总体目标。相反,我想排除(或证明)数据的畸形是我错误的根源。如果我阅读了整个文件,我会知道如何做到这一点。事实上,我没有。

所以这是我的问题:在 R 中有没有一种方法可以逐行读取固定宽度或 CSV 数据,而无需将整个文件读入内存,并且:对于 CSV,请检查: • 字段数是否始终相同,并返回不存在的行号;• 如果每个字段中的数据与列类一致,则返回不符合的行号和列号或名称

对于固定宽度,检查: • 字符数是否始终相同,否则返回行号;• 每个字段中的数据是否与列类一致;如果不是,则返回行号和字段中第一个字符的编号,或者列号,或者列名;

最后,对于这两种情况,我希望该方法告诉我它总共检查了多少行(以确保它到达文件的末尾),并且我想要一种按行号提取任意行副本的方法,这样我就可以查看它们(同样无需将整个文件读入内存)。

在固定宽度和 CSV 情况下,对列类的检查必须对某些字段或字符不存在或格式错误具有鲁棒性,即,它仍然应该告诉我有关行的合理信息,并且仍然继续查看在下一行。

也许有一个包或功能可以做到这一点?这似乎是一个相当标准的数据清理任务,除了大文件问题。

任何帮助将不胜感激。

真诚的,安德鲁

4

1 回答 1

4

选项 1:我在“现实生活情况”中使用 fwf 数据的经验有限,但对于大型 CSV 文件,我发现该count.fields功能非常有用。尝试这个:

 (table(cnts <- 
      count.fields(paste0(path,filename), sep=",", quote="", comment.char="") )

然后您可以搜索cnts具有异常值的行号。例如,如果您注意到只有 10-20 个字段计数为 47,而其余字段计数为 48,您可能会打印出这些位置:

which(cnts=47)

选项 2:我很确定我已经看到了在系统级别使用 sed 和 grep 来计算字段分隔符的解决方案。我从一些 NIX 论坛拼凑起来,它给了我一个结构良好的四行文件中的字段计数表:

fct <- table(system("awk -F ',' '{print NF}' A.csv", intern=TRUE))
fct

#3 
#4 

统计一个 1.2 MM 记录数据集中的字段需要 6 秒,并且没有任何数据被带入 R:

system.time( fct <- table(system("awk -F ',' '{print NF}' All.csv", intern=TRUE)) )
#   user  system elapsed 
#  6.597   0.215   6.552 

您可以通过以下方式获取行数:

sum(fct)
于 2013-09-29T21:46:05.127 回答