因此,我有一个数据文件(以分号分隔),该文件包含很多详细信息和不完整的行(导致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效率较低......在,巨蟒通过要吃掉3.5GB的文件中5分钟,同时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)
while (length(line)) {
line.split <- strsplit(line, ';')
if (length(line.split[[1]]) > 1) {
if (line.split[[1]][3] == '2009') {
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
}
}
line<- readLines(file.in, n=1)
}
close(file.in)
close(file.out)
失败的方法:
- sqldf
- 如果数据格式正确,这绝对是我以后将要用于此类问题的方法。但是,如果不是这样,则SQLite会阻塞。
- MapReduce
- 老实说,文档使我对此感到有些恐惧,所以我没有去尝试它。看起来它也要求该对象也要在内存中,如果是这样的话,这将使问题无济于事。
- 大内存
- 这种方法与数据干净地链接在一起,但是一次只能处理一种类型。结果,我的所有字符向量在放入big.table时都掉了。但是,如果我需要为将来设计大型数据集,我会考虑仅使用数字只是为了使此选项有效。
- 扫描
- 扫描似乎具有与大内存相似的类型问题,但是具有readLines的所有机制。简而言之,这次不符合要求。
sed
和/或awk
创建可以直接读取的CSV格式精简版。由于这不是解决方案,而是答案,因此,我将其保留为评论。