为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕姐4208626 2019-11-05 15:56:24
因此,我有一个数据文件(以分号分隔),该文件包含很多详细信息和不完整的行(导致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 positionfile.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 wantcat(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 linesline <- readLines(file.in, n=1)失败的方法:sqldf如果数据格式正确,这绝对是我以后将使用的此类问题。但是,如果不是,则SQLite会阻塞。MapReduce老实说,文档使我对此感到有些恐惧,所以我没有去尝试它。看起来它也要求该对象也要在内存中,如果是这样的话,这将使问题无济于事。大内存这种方法干净地链接到数据,但一次只能处理一种类型。结果,我的所有字符向量在放入big.table时都掉了。但是,如果我需要为将来设计大型数据集,我将考虑仅使用数字只是为了使此选项有效。扫描扫描似乎具有与大内存类似的类型问题,但是具有readLines的所有机制。简而言之,这一次不符合要求。
查看完整描述

3 回答

?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

我的尝试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 headers


B <- 300000 # depends how large is one pack

while(length(x)) {

    ind <- grep("^[^;]*;[^;]*; 20(09|10)", x)

    if (length(ind)) writeLines(x[ind], file_out)

    x <- readLines(file_in, n=B)

}

close(file_in)

close(file_out)


查看完整回答
反对 回复 2019-11-05
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

有没有类似的方法可以一次在R中读取文件?


是。的readChar()函数将在字符的块读取,而不假定它们是空终止。如果要一次读取一行中的数据,可以使用readLines()。如果读取块或行,请执行操作,然后将数据写出,可以避免出现内存问题。尽管如果您想在Amazon EC2上启动大内存实例,则可以获取高达64GB的RAM。那应该保存您的文件,还有足够的空间来处理数据。


如果需要更高的速度,那么Shane建议使用Map Reduce是一个很好的建议。但是,如果您打算在EC2上使用大内存实例,则应该查看多核软件包以使用计算机上的所有内核。


如果您发现自己想将大量带分隔符的数据读入R中,则至少应研究sqldf程序包,该程序包可让您从R中直接导入sqldf,然后对R中的数据进行操作。我发现sqldf是其中之一如上一个问题所述,将大量数据导入R的最快方法。


查看完整回答
反对 回复 2019-11-05
  • 3 回答
  • 0 关注
  • 658 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信