【发布时间】:2016-06-14 12:40:01
【问题描述】:
我从事数据管理工作,这意味着人们给我原始数据,我必须对其进行格式化和解析以获取我需要的部分并以有意义的方式组织它。目前我正在使用的数据是一个日志文件,但我已经打开并将其保存为文本文件。有点像这样:
M 20160525 09:51:11.822 DOC1:在 39411 毫秒后的 13 内清除陈旧的 DENIED 发送到 1864130A.62274
D 20160525 09:51:11.824 F798257E GET 10.19.100.24:62274 van8tc - "/pcgc/public/Other/" "*li" 完成
M 20160525 09:51:11.825 DOC1: F798257E 交易已在 15804727 确认
F 20160525 09:51:11.825 F798257E GET 10.19.100.24:62274 van8tc - "/pcgc/public/Other/" "*li" 441 (0,0) "0.10 秒 (36.8 千比特/秒)" D 20160525 09:51:11.825 F798257E GET 10.19.100.24:62274 van8tc - “/pcgc/public/Other/” “*li” - “释放包单元”
这是一个相当大的文件,我不希望将整个内容导入 R,主要是因为它占用的空间量。每行都有“字段”(我想要组织和分隔的),指定如下:
- F -- 行的标识符
- 20160525 -- 日期 (yyyymmdd)
- 17:52:38.791 -- 时间戳 (HH:MM:SS.sss)
- F798259D -- 传输标识符
- 156.145.15.85:46634 -- IP 地址和相关端口
- xqixh8sl -- 用户名
- AES -- 加密级别(可以是 -(破折号))
- "/pcgc...fastq.gz" -- 传输文件(在"中)
- "" -- 附加字符串(应为空"")
- 2951144113 -- 传输的字节数
- (0,0) -- 错误
- “2289.47 秒(10.3 兆位/秒)”——关于传输的数据
我需要的唯一行是以 F 开头并且有 (0, 0) 错误的行。这是一个示例行:
F 20160525 17:52:38.791 F798259D GET 156.145.15.85:46634 XQIXH8SL AES“/PCGC/PUBLIC/ETHER/exome/fastq/pcgc0053681_hs_ex__1-02598__v1_fcad18p7acxx_l8_p92of93_p1.fastq.gz”“”2951144113(0,0)“2289.47秒(10.3 兆比特/秒)"
我不会考虑这样的一行:
f 20160602 14:15:48.398 F7982D62 GET 156.145.15.85:36773 XQIXH8SL AES“/PCGC/PUBLIC/其他”/ QUACTQ/PCGC0065109_HS_EX__1-04692__V3_FCAD2HMUACXX_L4_P1OF1_P2.FASTQ.gz“”“50725464(4,32)”远程应用: Session Aborted: Aborted by user interrupt"
上面一行没有 (0, 0) 错误,所以不考虑。
我的问题是:由于文件太大,我希望能够解析它并只挑选出我事先需要的行。然后,一旦我导入它,我想要最好的方式来整齐地组织它。我知道有多种读取文件的方法(我一直在尝试使用readLines()和scan())但我不知道如何在条件语句中写入(该行必须以F开头,并且必须有 (0, 0) 错误)。
我尝试了很多方法:
-
使用
scan()将整个文件作为列表导入R。x <- scan("dataSet.txt", what = list(lineID = "", date = "", timestamp = "", transferID = "", IP = "", username = "", encryption = "", transferredFile = "", error = "", data = ""), sep = " ", fill = TRUE, strip.white = TRUE)logs <- list(x)logs
虽然我喜欢编号和行,但它遗漏了很多我需要的字段。这是它给我的输出:
[9062]“”
[9063] “”
[9064] “”
[9065] “”
[9066] “”
[9067] “”
[9068] “”
[9069] “”
[9070] “”
[9071] “”
[9072] “”
[9073] “Mnr:0”
[9074] “”
[9075]“Mnr:0”
[9076] “”
[9077] “”
[9078] “数据”
[9079] “”
[9080] “2”,
[9081] “12”,
[9082] “”
[9083] “”
[9084] “550F919C.60099”
- 我在网上找到了这个例子,所以我复制它并尝试类似地使用它。然而,它并没有给我我想要的。如果有人可以解释这是如何工作的,那也将不胜感激。但是,我使用它的方式也导入了整个文件。
> setwd("/Users/kimm5w/Intern Work")
> dataset <- list()
> con <- file("dataSet.txt")
> open(con)
> dataset <- grep("F", scan("dataSet.txt", what = list(lineID = "", date = "", timestamp = "", transferID = "", IP = "", username = "", encryption = "", transferredFile = "", error = "", data = ""), sep = " ", fill = TRUE, strip.white = TRUE), perl = TRUE, value = TRUE)
> dataset
这是它给我的输出,不是我想要的格式:
\"[0]\", \"\", \"xqixh8sl:\", \"\", \"\", \"\", \"\", \"Mnr:0\", \"\", \"Mnr:0\", \"\", \"\", \"data\", \"\", \"at\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"Mnr:0\", \"\", \"Mnr:0\", \"\", \"\", \"data\", \"\", \"at\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"Mnr:0\", \"\", \"Mnr:0\", \"\", \"\", \"data\", \"\", \"550F919C.36474\", \"\", \"550F919C.42385\", \"\", \"550F919C.49879\", \"\", \"550F919C.53923\", \"\", \"6,\", \"18,\", \"\", \"550F919C.36773\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"at\", \"\", \"\", \"\", \"\", \"\", \n\"\", \"\", \"550F919C.37525\", \"\", \"6,\", \"18,\", \"\")"
我是 R 的新手;我学习了 Java,虽然概念相似,但语法不熟悉。如果有人可以帮助我,请这样做!我已经为此工作了大约一个星期,但无法弄清楚。感谢您的帮助!
更新
在听取了您的建议后,我尝试了以下方法:
setwd("/Users/kimm5w/Intern Work")
df<-data.frame(readLines("dataSet.txt"))
F_dataSet <- grep("^F.*(0,0)", "dataSet.txt")
F_dataSet
library(stringr)
x = 0
while(x < length(readLines("dataSet.txt"))){
line <- readLines("dataSet.txt")
if (str_sub(line, 1, 1) == 'F' & grepl('\\(0\\,0\\)', line)[1]){
F_data <- c(F_data, line)
}
}
display(F_data)
由于某种原因,当我尝试在 R 中运行它时,它不会显示结果。但是,它确实运行没有错误。我的问题是其中之一是否可行。我不能使用 for 循环,因为不知道确切的行数。因此,我尝试在第二个版本中使用 while 循环。该链接很有帮助,但有点令人困惑,因为我不熟悉语法。如果有人可以解释每个部分,我认为会更容易理解。在第一次尝试时,我只是尝试使用 grep() 来整理我需要的行,但我不确定它是否有效。如果有人可以从这里提供帮助,那将非常感激。对于那些给我发来答案的人,也谢谢你。这对我帮助很大,是我一段时间以来取得的最大进步。
这是另一个更新。它运行良好,但由于某种原因,while 循环不打印任何内容。当我尝试显示 F_data 时,它没有显示出来。有人能指出错误在哪里吗?
setwd("/Users/kimm5w/Intern Work")
F_data <- data.frame
print(F_data)
library(stringr)
x <- length(readLines("dataSet.txt"))
print(x)
while(x != 0)
{
line <- readline("dataSet.txt")
print(line)
if (str_sub(line, 1, 1) == 'F' & grepl('\\(0\\,0\\)', line)[1]){
F_data <- c(F_data, line)
print(F_data)
}
x <- x + 1
}
close(con)
F_data
【问题讨论】:
-
嗨,如何使用 readLines 在 for 循环中逐行重新排列,并且只保存到变量或文件中符合您的条件的那些?我认为这至少有助于过滤相关行的任务。
-
但我感到困惑的是,如果文件甚至没有读入 R,我应该如何告诉计算机我希望它查看每行的第一个字符?我的第一个冲动是使用 substring 函数,但除非文件完全导入,否则我认为它不起作用。我还研究过使用正则表达式来匹配我想要的行的格式,但我也不熟悉这些。我在实际编写代码和语法时遇到了最大的麻烦;我知道我想怎么做,但不完全确定我需要写的方式。
-
嗨,我把回复作为答案,在这里格式化代码很难:)
标签: r