Имам голям файл с данни, който има 40 000+ реда. Това е списък на входните данни на журнала и изглежда малко така:
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" и имат грешка (0, 0), като тази:
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)"
Всичко останало мога просто да пренебрегна. Проблемът ми е следният: искам начин да прочета този файл по ред и да преценя дали е необходимо да се запази редът за внос. В момента използвам 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 каза, че редът е празен, че няма символи. Назначих ли го неправилно? Искам ред да е реда, който анализирам във файла с данни и оценявам дали трябва да го съхраня или не. Ето моят актуализиран код:
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)
Отговори:
2 за отговор № 1Виж това:
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
за да може да го чете ред по ред. Използвайте редовен израз ^\s*F{1}
за заснемане на линия, започваща с буква F
с възможни бели пространства където ^
означават началото на низ. употреба 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)"
1 за отговор № 2
Ако имате достатъчно памет, 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 за отговор № 3
Нещо като този отговор (Какъв е добър начин да четете ред по ред в 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
цикъл работи.