【问题标题】:How to Read Specific Lines of A Large Irregular Data File in R如何在 R 中读取大型不规则数据文件的特定行
【发布时间】: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,主要是因为它占用的空间量。每行都有“字段”(我想要组织和分隔的),指定如下:

  1. F -- 行的标识符
  2. 20160525 -- 日期 (yyyymmdd)
  3. 17:52:38.791 -- 时间戳 (HH:MM:SS.sss)
  4. F798259D -- 传输标识符
  5. 156.145.15.85:46634 -- IP 地址和相关端口
  6. xqixh8sl -- 用户名
  7. AES -- 加密级别(可以是 -(破折号))
  8. "/pcgc...fastq.gz" -- 传输文件(在"中)
  9. "" -- 附加字符串(应为空"")
  10. 2951144113 -- 传输的字节数
  11. (0,0) -- 错误
  12. “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) 错误)。

我尝试了很多方法:

  1. 使用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”

  1. 我在网上找到了这个例子,所以我复制它并尝试类似地使用它。然而,它并没有给我我想要的。如果有人可以解释这是如何工作的,那也将不胜感激。但是,我使用它的方式也导入了整个文件。

> 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


【解决方案1】:

也许这是一种逃避,但如果您担心在R 会话期间保存内存,请不要在R 会话中这样做。您可以在将文件读入R 之前使用 grep 对其进行预处理。

grep "^F.*(0,0)" dataSet.txt > processed_dataSet.txt

【讨论】:

  • 我一直在我的 Mac 上使用 TextWrangler 或 TextEdit 来传输数据。我应该切换到其他东西,还是其中之一能够预先处理数据?
  • 使用grep。更快。
  • 然后在处理器中。您知道与 RStudio 兼容的好软件吗?我只是想用一大块数据尝试一下,但我用来打开日志文件的控制台似乎都无法使用 grep() 解析数据。
  • 我说的是名为 grep 的 unix 命令行工具,而不是名为 grep() 的 R 函数。你有类似unix的终端吗?
【解决方案2】:

假设您使用 readLines 函数和 for 循环或其他方式阅读了第一行。然后,您可以使用简单的搜索来查看您的行是否以“F”开头以及是否包含“(0,0)”。例如:

library(stringr)
line='F 20160525 09:51:11.825 F798257E GET 10.19.100.24:62274 van8tc - "/pcgc/public/Other/" "*li" 441 (0,0) "0.10 seconds (36.8 kilobits/sec)" D 20160525 09:51:11.825 F798257E GET 10.19.100.24:62274 van8tc - "/pcgc/public/Other/" "*li" - "Freeing Package Unit"'

if(str_sub(line,1,1)=='F' & grepl('\\(0\\,0\\)', line)[1]){
    relevant_guys<-c(relevant_guys, line)
}

通过这种方式,您不必将整个文件放入内存中,并逐行评估。

【讨论】:

  • 我可以使用 while 循环来代替吗?数据行的数量取决于我使用哪个控制台打开它,所以我不完全确定我需要使用多少次 readLines()。
  • 这是一个使用 while 的好例子:stackoverflow.com/questions/4106764/…
猜你喜欢
  • 2013-10-31
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-20
  • 2013-06-18
  • 2014-04-09
相关资源
最近更新 更多