web-dev-qa-db-ja.com

大きなファイルから番号で行を読み取る

1,500万行のファイルがあります(メモリに収まりません)。行番号の小さなベクトルも持っています-抽出したい行です。

ワンパスで行を読み取るにはどうすればよいですか?

私はそれを1つのパスで実行するC関数を期待していました。

24

コツは、接続を使用し、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を試すこともできます。これはより速く、より多くの制御を提供します。

25
mbq

バイナリファイルの場合

いくつかの議論はここにあります: RのStata .DTAファイルの一部のみを読み取る

CSVまたはその他のテキストファイルの場合

それらが連続していてファイルの先頭にある場合は、,nrows引数をread.csvまたはread.tableファミリーのいずれかに使用するだけです。そうでない場合は、,nrows引数と,skip引数を組み合わせてread.csvを繰り返し呼び出し(各呼び出しで新しい行または連続する行のグループを読み取る)、次にrbind結果を一緒に呼び出すことができます。

5
Ari B. Friedman

ファイルの行の長さが固定されている場合は、「シーク」を使用して任意の文字位置にジャンプできます。したがって、必要な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」を使用することもできますが、上記の警告が当てはまるかどうかはわかりません!

4
Spacedman

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

高速に実行されます(ストレージがファイルを読み取ることができるのと同じ速さ)。

3

ディスカッション here に基づいてソリューションをコンパイルします。

scan(filename,what=list(NULL),sep='\n',blank.lines.skip = F)

これは行数のみを表示しますが、何も読みません。本当に空白行をスキップしたい場合は、最後の引数をTRUEに設定します。

2
Alex Feng

一般的にテキストファイルのみを読み取る場合

cat(readLines("filename.txt", n=10), sep="\n")

ここで、パラメータsepは分割文字を設定するためのものです。

関数readLineについては、公式ドキュメントを参照できます: https://www.rdocumentation.org/packages/base/versions/3.5.1/topics/readLines

0
千木郷