【发布时间】:2011-11-01 16:12:15
【问题描述】:
我有一个包含 1500 万行的文件(不适合内存)。我还有一个小的行号向量 - 我要提取的行。
我怎样才能一次读出这些行?
我希望有一个 C 函数可以一次性完成。
【问题讨论】:
标签: r large-files line-numbers
我有一个包含 1500 万行的文件(不适合内存)。我还有一个小的行号向量 - 我要提取的行。
我怎样才能一次读出这些行?
我希望有一个 C 函数可以一次性完成。
【问题讨论】:
标签: r large-files line-numbers
诀窍是使用连接并在read.table之前打开它:
con<-file('filename')
open(con)
read.table(con,skip=5,nrow=1) #6-th line
read.table(con,skip=20,nrow=1) #27-th line
...
close(con)
你也可以试试scan,它速度更快,控制力更强。
【讨论】:
scan 或readLines 来提高速度。 read.table 对数据类型、维度等进行了大量检查。最好不要将 c 用作 R 中的变量,因为它是最常用的函数之一(连接)。
skip=5 之前调用skip=20,read.table 或scan 会如何表现?
read.table 将消耗连接中的skip+nrow 行,下一个read.table 将从这一点开始。以此类推。
这里有一些讨论: Reading in only part of a Stata .DTA file in R
如果它们是连续的并且位于文件的顶部,只需使用 ,nrows 参数到 read.csv 或任何 read.table 系列。如果没有,您可以结合,nrows 和,skip 参数重复调用read.csv(每次调用读取新行或一组连续行),然后将结果一起rbind。
【讨论】:
read.table 似乎不是这样写的。如果您查看read.table 的源代码,它似乎不会太难修改。也许其他人会对执行此操作的现有功能有更好的答案。
如果您的文件有固定的行长,那么您可以使用“seek”跳转到任何字符位置。因此,只需为您想要的每个 N 跳转到 N * line_length,然后读取一行。
但是,来自 R 文档:
Use of seek on Windows is discouraged. We have found so many
errors in the Windows implementation of file positioning that
users are advised to use it only at their own risk, and asked not
to waste the R developers' time with bug reports on Windows'
deficiencies.
你也可以在C中使用标准C库中的'seek',但不知道上面的警告是否也适用!
【讨论】:
在获得 R 解决方案/答案之前,我已经在 Ruby 中完成了:
#!/usr/bin/env ruby
NUM_SEQS = 14024829
linenumbers = (1..10).collect{(rand * NUM_SEQS).to_i}
File.open("./data/uniprot_2011_02.tab") do |f|
while line = f.gets
print line if linenumbers.include? f.lineno
end
end
运行速度快(只要我的存储可以读取文件)。
【讨论】:
我根据here 的讨论编写了一个解决方案。
scan(filename,what=list(NULL),sep='\n',blank.lines.skip = F)
这只会显示行数,但不会读取任何内容。如果你真的想跳过空行,你可以将最后一个参数设置为 TRUE。
【讨论】: