我有一个包含1500万行的文件(无法放入内存)。我还有一个小向量,里面是我想要提取的行号。
如何一次性读取出这些行?
我希望有一个C语言函数能够在一次遍历中完成此操作。
我有一个包含1500万行的文件(无法放入内存)。我还有一个小向量,里面是我想要提取的行号。
如何一次性读取出这些行?
我希望有一个C语言函数能够在一次遍历中完成此操作。
关键在于使用连接并在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
,它更快且提供更多的控制。
关于此问题的讨论在这里:在 R 中仅读取 Stata .DTA 文件的一部分
如果它们是连续的并且在文件顶部,只需使用 ,nrows
参数来调用 read.csv
或任何 read.table
家族中的函数。如果不是,您可以将 ,nrows
和 ,skip
参数组合起来,重复调用 read.csv
(每次调用读入一行或一组连续的行),然后使用 rbind
将结果合并在一起。
read.table
似乎并没有这样写。如果你查看 read.table
的源代码,会发现修改起来并不太难。也许其他人会有更好的答案,提供一个现成的函数来实现这个功能。 - Ari B. Friedman如果您的文件具有固定的行长度,则可以使用“seek”跳转到任何字符位置。因此,只需为每个要读取的行跳转到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
快速运行(尽可能快地读取文件)。
我根据这里的讨论 编译了一个解决方案。
scan(filename,what=list(NULL),sep='\n',blank.lines.skip = F)
这只会显示行数,但不会读取任何内容。如果您真的想跳过空行,您可以将最后一个参数设置为TRUE。
scan
或readLines
函数。在R中,read.table
函数会对数据类型、维度等进行大量检查。此外,最好不要将变量命名为c
,因为它是R中最常用的函数之一(连接函数)。 - hatmatrixskip=5
之前调用了skip=20
,read.table或scan会如何表现? - Aleksandr Levchukread.table
将从连接中消耗skip+nrow行,下一个read.table
将从此点开始。以此类推。 - mbq