1,500万行のファイルがあります(メモリに収まりません)。行番号の小さなベクトルも持っています-抽出したい行です。
ワンパスで行を読み取るにはどうすればよいですか?
私はそれを1つのパスで実行する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
結果を一緒に呼び出すことができます。
ファイルの行の長さが固定されている場合は、「シーク」を使用して任意の文字位置にジャンプできます。したがって、必要なNごとにN * line_lengthにジャンプし、1行を読み取ります。
ただし、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に設定します。
一般的にテキストファイルのみを読み取る場合
cat(readLines("filename.txt", n=10), sep="\n")
ここで、パラメータsep
は分割文字を設定するためのものです。
関数readLine
については、公式ドキュメントを参照できます: https://www.rdocumentation.org/packages/base/versions/3.5.1/topics/readLines