修剪巨大的(3.5 GB)CSV文件以读入R

因此,我有一个数据文件(以分号分隔),该文件包含很多详细信息和不完整的行(导致Access和SQL阻塞)。它是40年的县级数据集,细分为细分,子细分和子细分(共200个因子)。简而言之,它是巨大的,如果我尝试简单地阅读它,它将不适合内存。


所以我的问题是,考虑到我想要所有县,但是只有一年(并且只有最高级别的细分……最终导致约100,000行),什么是获得该收入的最佳方法?此汇总到R?


目前,我正在尝试与Python无关的事情,通过一次读取和操作一行来绕过文件大小限制,但是我更喜欢仅R的解决方案(CRAN包可以)。有没有类似的方法可以一次在R中读取文件?


任何想法将不胜感激。


更新:


约束条件

需要使用我的机器,所以没有EC2实例

尽可能仅R。在这种情况下,速度和资源不是问题...只要我的机器不爆炸...

如下所示,数据包含混合类型,稍后我需要对其进行操作

数据

数据为3.5GB,约850万行和17列

几千行(〜2k)格式错误,只有一列而不是17

这些完全不重要,可以删除

我只需要该文件中的约100,000行(见下文)

数据示例:


County; State; Year; Quarter; Segment; Sub-Segment; Sub-Sub-Segment; GDP; ...

Ada County;NC;2009;4;FIRE;Financial;Banks;80.1; ...

Ada County;NC;2010;1;FIRE;Financial;Banks;82.5; ...

NC  [Malformed row]

[8.5 Mill rows]

我想删掉一些列并从40个可用年份(1980-2020年的2009-2010年)中选择两个,以便使数据适合R:


County; State; Year; Quarter; Segment; GDP; ...

Ada County;NC;2009;4;FIRE;80.1; ...

Ada County;NC;2010;1;FIRE;82.5; ...

[~200,000 rows]

结果:


修正所有提出的建议后,我决定由JD和Marek提出的readLines效果最好。我给了Marek支票,因为他提供了一个示例实现。


我在这里为我的最终答案复制了Marek实现的稍作改编的版本,使用strsplit和cat仅保留我想要的列。


还应当指出,这是MUCH比Python效率较低......在,巨蟒通过要吃掉5分钟3.5GB文件,而R取约60 ...但如果你只为R,那么这是罚单。


## Open a connection separately to hold the cursor position

file.in <- file('bad_data.txt', 'rt')

file.out <- file('chopped_data.txt', 'wt')

line <- readLines(file.in, n=1)

line.split <- strsplit(line, ';')

# Stitching together only the columns we want

cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)

## Use a loop to read in the rest of the lines

line <- readLines(file.in, n=1)

失败的方法:


sqldf

如果数据格式正确,这绝对是我以后将使用的此类问题。但是,如果不是,则SQLite会阻塞。

MapReduce

老实说,文档使我对此感到有些恐惧,所以我没有去尝试它。看起来它也要求该对象也要在内存中,如果是这样的话,这将使问题无济于事。

大内存

这种方法干净地链接到数据,但一次只能处理一种类型。结果,我的所有字符向量在放入big.table时都掉了。但是,如果我需要为将来设计大型数据集,我将考虑仅使用数字只是为了使此选项有效。

扫描

扫描似乎具有与大内存类似的类型问题,但是具有readLines的所有机制。简而言之,这一次不符合要求。


慕姐4208626
浏览 713回答 3
3回答

白猪掌柜的

我的尝试readLines。这部分代码是根据csv选定的年份创建的。file_in <- file("in.csv","r")file_out <- file("out.csv","a")x <- readLines(file_in, n=1)writeLines(x, file_out) # copy headersB <- 300000 # depends how large is one packwhile(length(x)) {&nbsp; &nbsp; ind <- grep("^[^;]*;[^;]*; 20(09|10)", x)&nbsp; &nbsp; if (length(ind)) writeLines(x[ind], file_out)&nbsp; &nbsp; x <- readLines(file_in, n=B)}close(file_in)close(file_out)

慕运维8079593

有没有类似的方法可以一次在R中读取文件?是。的readChar()函数将在字符的块读取,而不假定它们是空终止。如果要一次读取一行中的数据,可以使用readLines()。如果读取块或行,请执行操作,然后将数据写出,可以避免出现内存问题。尽管如果您想在Amazon EC2上启动大内存实例,则可以获取高达64GB的RAM。那应该保存您的文件,还有足够的空间来处理数据。如果需要更高的速度,那么Shane建议使用Map Reduce是一个很好的建议。但是,如果您打算在EC2上使用大内存实例,则应该查看多核软件包以使用计算机上的所有内核。如果您发现自己想将大量带分隔符的数据读入R中,则至少应研究sqldf程序包,该程序包可让您从R中直接导入sqldf,然后对R中的数据进行操作。我发现sqldf是其中之一如上一个问题所述,将大量数据导入R的最快方法。
打开App,查看更多内容
随时随地看视频慕课网APP