2016-06-20 9 views
1

40,000行以上の大きなデータファイルがあります。これは、ログ入力のリストだし、このようなビットに見える:特定の行のAデータファイルを読み込む方法

D 20160602 14:15:43.559 F7982D62 Req Agr:131 Mra:0 Exp:0 Mxr:0 Mnr:0 Mxd:0 Mnd:0 Nro:0  
    D 20160602 14:15:43.559 F7982D62 Set Agr:130 Mra:0 Exp:0 Mxr:0 Mnr:0 Mxd:0 Mnd:0 Nro:0 I 20160602 14:15:43.559 F7982D62 GET 156.145.15.85:36773 xqixh8sl AES "/pcgc/public/Other/exome/fastq/PCGC0065109_HS_EX__1-04692__v3_FCAD2HMUACXX_L4_p1of1_P2.fastq.gz" "" 
    M 20160602 14:15:43.595 DOC1: F7982D62 Request for unencrypted meta data on encrypted transaction 
    M 20160602 14:15:48.353 DOC1: F7982D62 Transaction has been acknowledged at 722875647 
    F 20160602 14:15:48.398 F7982D62 GET 156.145.15.85:36773 xqixh8sl AES "/pcgc/public/Other/exome/fastq/PCGC0065109_HS_EX__1-04692__v3_FCAD2HMUACXX_L4_p1of1_P2.fastq.gz" "" 50725464 (4,32) "Remote Application: Session Aborted: Aborted by user interrupt" 
    M 20160602 14:15:48.780 DOC1: F7982D63 New download request D 20160602 14:15:48.780 F7982D63 META: 134 Path: /pcgc/public/CTD/exome/fastq/PCGC0033175_HS_EX__1-00304-01__v1_FCBC0RE4ACXX_L3_p32of96_P2.fastq.gz user: xqixh8sl pack: arg: feat: cE,s 

それはとても大きいですので、私はメモリに全体の事を読みたくありません。

F 20160602 14:25:11.321 F7982D50 GET 156.145.15.85:37525 xqixh8sl AES "/pcgc/public/Other/exome/fastq/PCGC0077248_HS_EX__1-06808__v3_FCC49HJACXX_L7_p1of1_P1.fastq.gz" "" 3322771022 (0,0) "1499.61 seconds (17.7 megabits/sec)" 

私は無視することができる他のすべて:私はこれだけのように、ライン識別子「F」で始まる行を必要とすると、(0、0)の誤差を持っています。私の問題は次のとおりです。このファイルを1行ずつ読み込み、その行をインポートする必要があるかどうかを評価する方法が必要です。現在、forループを使用して各行を実行しており、readLines()機能を使用しています。

library(stringr) 
con <- file("dataSet.txt", open = "r") 
Fdata <- data.frame 
i <- 1 
j <- 1 
lineLength <- length(readLines(con)) 
for (i in 1:lineLength){ 
    line <- readLines("dataSet.txt", 1) 
    if (str_sub(line, 1, 1) == 'F' && grepl("\\(0\\,0\\)", line)[i]){ 
    print(line) 
    Fdata[j,] <- rbind(line) 
    i <- i + 1 
    j <- j + 1 
    } 
    i <- i + 1 
} 
print(Fdata) 

これはうまく動作しますが、それは私に欲しいものではありません。それは、ファイルの最初の行を何度も何度も印刷し続けます。私はそれが私がラインを必要とするかどうかを評価するために取得することができ、そしてどのように私はそれを正しく保存することができますどのように

[1] "C 20160525 05:27:47.915 Rotated log file: /var/log/servedat-201605250527.log" 
    [1] "C 20160525 05:27:47.915 Rotated log file: /var/log/servedat-201605250527.log" 
    [1] "C 20160525 05:27:47.915 Rotated log file: /var/log/servedat-201605250527.log" 
    [1] "C 20160525 05:27:47.915 Rotated log file: /var/log/servedat-201605250527.log" 

(ベクトル、データフレーム、マトリクスとして、それは本当に問題ではありません)私はできるように、 forループの外側に出力しますか?

UPDATE

私はこれに私のコードを変更しました:

library(stringr) 
    con <- file("dataSet.txt", open = "r") 
    Fdata <- data.frame 
    i <- 1 
    j <- 1 
    lineLength <- length(readLines(con)) 
    for (i in 1:lineLength){ 
     line <- readLines(con, 1) 
     print(line) 
     if (str_sub(line, 1, 1) == 'F' && grepl("\\(0\\,0\\)", line)[i]){ 
     print(line) 
     Fdata[j,] <- rbind(line) 
     i <- i + 1 
     j <- j + 1 
     } 
     i <- i + 1 
    } 
    print(Fdata) 

をしかし、私はそれが空であることを述べている行に格納されている値をチェックするとき。それがなぜ変わったのか分かりません。さらに、if文にはTRUE/FALSEという適切な条件がないため、grepl()がTRUE/FALSEの値を返さなければならないため、私も混乱します。

UPDATE

私はエラーを取り除くために管理し、私はFDATAを呼び出すとき、私はまだ何も届きません。私は自分の変数をチェックし、Rは行が空で文字がないと言った。私はそれを間違って割り当てましたか?私は、データファイルを解析していて、それを保存する必要があるかどうかを評価する行になるようにしたい。

con <- file("test1.txt", "r") 
lines <- c() 
while(TRUE) { 
    line = readLines(con, 1) 
    if(length(line) == 0) break 
    else if(grepl("^\\s*F{1}", line) && grepl("(0,0)", line, fixed = TRUE)) lines <- c(lines, line) 
} 

lines 
# [1] "F 20160602 14:25:11.321 F7982D50 GET 156.145.15.85:37525 xqixh8sl AES \"/pcgc/public/Other/exome/fastq/PCGC0077248_HS_EX__1-06808__v3_FCC49HJACXX_L7_p1of1_P1.fastq.gz\" \"\" 3322771022 (0,0) \"1499.61 seconds (17.7 megabits/sec)\"" 

はそれが行ずつそれを読むことができるようにreadLinesにファイルストリームを渡します。この

library(stringr) 
 
con <- file("dataSet.txt", open = "r") 
 
Fdata <- data.frame 
 
i <- 1 
 
j <- 1 
 
lineLength <- length(readLines("dataSet.txt)) 
 
for (i in 1:lineLength){ 
 
    line <- readLines(con, 1) 
 
    print(line) 
 
    if (str_sub(line, 1, 1) == 'F' && grepl("\\(0\\,0\\)", line)){ 
 
    print(line) 
 
    Fdata[j,] <- rbind(line) 
 
    i <- i + 1 
 
    j <- j + 1 
 
    } 
 
    i <- i + 1 
 
} 
 
print(Fdata)

+0

文字列で指定するのではなく、ファイル接続を 'readLines'に渡す必要があります。 forループの最初の行を 'line < - readLines(con、1)'に変更して、ここで問題を解決する必要があります。 – Psidom

+0

また、コンマをエスケープする必要はないと思います。 'grepl(" \\(0,0 \\)、line) '。 – Psidom

+0

あなたが持っている問題は、 grepが長さ1のベクトルを返す間に 'i'は大量になる可能性があります。' [i] 'を削除してください。 – Psidom

答えて

2

チェックアウト:ここに私の更新されたコードです。可能な空白でFという文字で始まる行をキャプチャするには、正規表現^\\s*F{1}を使用します。^は、文字列の先頭を示します。 fixed=Tを使用して、完全一致をキャプチャするには(0,0)を使用してください。両方のチェックがTRUEの場合は、結果を行に追加します。

データ

D 20160602 14:15:43.559 F7982D62 Req Agr:131 Mra:0 Exp:0 Mxr:0 Mnr:0 Mxd:0 Mnd:0 Nro:0  
D 20160602 14:15:43.559 F7982D62 Set Agr:130 Mra:0 Exp:0 Mxr:0 Mnr:0 Mxd:0 Mnd:0 Nro:0 I 20160602 14:15:43.559 F7982D62 GET 156.145.15.85:36773 xqixh8sl AES "/pcgc/public/Other/exome/fastq/PCGC0065109_HS_EX__1-04692__v3_FCAD2HMUACXX_L4_p1of1_P2.fastq.gz" "" 
M 20160602 14:15:43.595 DOC1: F7982D62 Request for unencrypted meta data on encrypted transaction 
M 20160602 14:15:48.353 DOC1: F7982D62 Transaction has been acknowledged at 722875647 
F 20160602 14:15:48.398 F7982D62 GET 156.145.15.85:36773 xqixh8sl AES "/pcgc/public/Other/exome/fastq/PCGC0065109_HS_EX__1-04692__v3_FCAD2HMUACXX_L4_p1of1_P2.fastq.gz" "" 50725464 (4,32) "Remote Application: Session Aborted: Aborted by user interrupt" 
M 20160602 14:15:48.780 DOC1: F7982D63 New download request D 20160602 14:15:48.780 F7982D63 META: 134 Path: /pcgc/public/CTD/exome/fastq/PCGC0033175_HS_EX__1-00304-01__v1_FCBC0RE4ACXX_L3_p32of96_P2.fastq.gz user: xqixh8sl pack: arg: feat: cE,s 
F 20160602 14:25:11.321 F7982D50 GET 156.145.15.85:37525 xqixh8sl AES "/pcgc/public/Other/exome/fastq/PCGC0077248_HS_EX__1-06808__v3_FCC49HJACXX_L7_p1of1_P1.fastq.gz" "" 3322771022 (0,0) "1499.61 seconds (17.7 megabits/sec)" 
+0

ありがとうございました!このワークd素晴らしい。ちょうど1つの簡単な質問:whileループは条件が真である場合にのみ実行されるため、条件が偽になるラインにヒットするとすぐに停止します。私はなぜそれが動作するように少し混乱しています。しかし他のすべては意味をなさない。 – stargirl

+0

はい、それは真実です、そして私たちがここで使っている論理です。条件を常にTRUEと指定し、最後の行(行の長さがゼロであることを意味する)に到達するたびに、キーワードbreakと同じループを抜けてwhileを停止します。 – Psidom

1

あなたは十分なメモリを持っている場合は、40,000行はRが処理するにはあまりすべきではありません。パフォーマンス上の理由から、すべての行を一度に読み込み、ベクトルパフォーマンスを使用して結果を分析する方がよいでしょう。

あなたのコードは、このように単純化することができます。

library(stringr) 

line <- readLines("dataSet.txt") 

foundset<-line[which(str_sub(line, 1, 1) == 'F' & grepl("(0,0)", line, fixed = TRUE))] 
#rm("line") #include this line to free up memory if there is a concern 

これは文字「F」で始まる1アウトラインおよびサブセットの全てに読み込みます。これらの行はすべてベクトルのセットに含まれています。

+0

私の仕事の一部は、データセット全体をRに読み込ませようとしていないことです。私はそれをやりましたが、目的は行ごとに読み込む方法を学ぶことでした。理由の一部は、効率性とパフォーマンスの問題です。また、私はすぐに何百万行ものコードを処理するので、私はループを書く必要があります。必要な行だけを解析して保存する必要があります。しかし、あなたの提案をありがとう。 – stargirl

+0

何百万行ものコードを読む必要がある場合は、行ごとに読むのが非常に遅くなります。より良いアプローチは、ラインのブロックを読み取らず、それらを解析し、次のブロックを読み取ることです。 – Dave2e

1

この回答(What is a good way to read line-by-line in R?)のようなものでも動作するだろう:私は目的にそこにいる最後の行を追加

cat(' D 20160602 14:15:43.559 F7982D62 Req Agr:131 Mra:0 Exp:0 Mxr:0 Mnr:0 Mxd:0 Mnd:0 Nro:0',  
    'D 20160602 14:15:43.559 F7982D62 Set Agr:130 Mra:0 Exp:0 Mxr:0 Mnr:0 Mxd:0 Mnd:0 Nro:0 I 20160602 14:15:43.559 F7982D62 GET 156.145.15.85:36773 xqixh8sl AES "/pcgc/public/Other/exome/fastq/PCGC0065109_HS_EX__1-04692__v3_FCAD2HMUACXX_L4_p1of1_P2.fastq.gz" ""', 
    'M 20160602 14:15:43.595 DOC1: F7982D62 Request for unencrypted meta data on encrypted transaction', 
    'M 20160602 14:15:48.353 DOC1: F7982D62 Transaction has been acknowledged at 722875647', 
    'F 20160602 14:15:48.398 F7982D62 GET 156.145.15.85:36773 xqixh8sl AES "/pcgc/public/Other/exome/fastq/PCGC0065109_HS_EX__1-04692__v3_FCAD2HMUACXX_L4_p1of1_P2.fastq.gz" "" 50725464 (4,32) "Remote Application: Session Aborted: Aborted by user interrupt"', 
    'M 20160602 14:15:48.780 DOC1: F7982D63 New download request D 20160602 14:15:48.780 F7982D63 META: 134 Path: /pcgc/public/CTD/exome/fastq/PCGC0033175_HS_EX__1-00304-01__v1_FCBC0RE4ACXX_L3_p32of96_P2.fastq.gz user: xqixh8sl pack: arg: feat: cE,s")', 
    'F 20160602 14:15:48.398 F7982D62 GET 156.145.15.85:36773 xqixh8sl AES "/pcgc/public/Other/exome/fastq/PCGC0065109_HS_EX__1-04692__v3_FCAD2HMUACXX_L4_p1of1_P2.fastq.gz" "" 50725464 (4,32) "Remote Application: Session Aborted: Aborted by user interrupt" (0,0)', 
    file="test", 
    sep="\n") 


library(stringr) 
con <- file("test", open = "r") 
res<-c() 

while (length(oneLine <- readLines(con, n = 1, warn = FALSE)) > 0) { 
    if (substr(str_trim(oneLine),1,1) =="F" & (regexpr("(0,0)",oneLine)[1] > 0)){ 

    res<-c(res,oneLine) 
    } 

} 

close(con) 
res 
[1] "F 20160602 14:15:48.398 F7982D62 GET 156.145.15.85:36773 xqixh8sl AES \"/pcgc/public/Other/exome/fastq/PCGC0065109_HS_EX__1-04692__v3_FCAD2HMUACXX_L4_p1of1_P2.fastq.gz\" \"\" 50725464 (4,32) \"Remote Application: Session Aborted: Aborted by user interrupt\" (0,0)" 

注意がどのようにwhileループ作品を表示します。

+0

あなたが使ったcat()関数について説明できますか?また、それは大きなファイルなので、ファイル名と区切り記号だけを使用して、すべての行を文字列としてコピーできませんか? – stargirl

関連する問題