【问题标题】:How to skip extra lines before the header of a tab delimited delimited file in R如何在R中制表符分隔的文件的标题之前跳过额外的行
【发布时间】:2011-03-04 10:39:52
【问题描述】:

我使用的软件生成的日志文件包含可变数量的摘要信息行,后跟大量制表符分隔的数据。我正在尝试编写一个函数,它将这些日志文件中的数据读取到忽略摘要信息的数据框中。摘要信息从不包含选项卡,因此以下功能起作用:

read.parameters <- function(file.name, ...){
  lines <- scan(file.name, what="character", sep="\n")
  first.line <- min(grep("\\t", lines))
  return(read.delim(file.name, skip=first.line-1, ...))
}

但是,这些日志文件非常大,因此两次读取文件非常慢。肯定有更好的方法吗?

编辑添加:

Marek 建议使用textConnection 对象。他在答案中建议的方式在大文件上失败,但以下工作:

read.parameters <- function(file.name, ...){
  conn = file(file.name, "r")
  on.exit(close(conn))
  repeat{
    line = readLines(conn, 1)
    if (length(grep("\\t", line))) {
      pushBack(line, conn)
      break}}
  df <- read.delim(conn, ...)
  return(df)}

再次编辑:感谢 Marek 对上述功能的进一步改进。

【问题讨论】:

  • 为了安全地关闭连接,您可以使用on.exit 函数。在conn=file(...) 之后添加行on.exit(close(conn))。然后当一个函数完成一个任务(通常或有错误)时,连接将被关闭。否则,当您在fileclose 之间出现错误时,连接将打开。
  • 谢谢,好技术。我已经更新了。

标签: r csv delimiter


【解决方案1】:

您无需阅读两次。在第一个结果上使用textConnection

read.parameters <- function(file.name, ...){
  lines <- scan(file.name, what="character", sep="\n") # you got "tmp.log" here, i suppose file.name should be
  first.line <- min(grep("\\t", lines))
  return(read.delim(textConnection(lines), skip=first.line-1, ...))
}

【讨论】:

  • 我已修正错字。感谢您使用 textConnection 的建议,尽管您提供的功能不起作用。我想我需要先创建 textConnection,然后对其运行扫描,然后使用 pushBack 倒带文件。
  • 奇怪。我对其进行测试并为我的假数据工作。您收到错误消息或结果为空?
  • 示例:cat(c("ds","sdds","sddfsd","a\tb\tc","1\t2\t3","1\t2\t3"),file="test.txt", sep="\n") 然后read.parameters("test.txt") 返回data.frame 3 列和2 行。
  • 有趣。我可以确认它适用于你的假数据,但我的大数据文件 R 停止响应,我必须强制退出。但是受您建议的启发,我制作了一个工作版本(在问题中添加以保留格式)
【解决方案2】:

如果您可以确定标题信息不会超过 N 行,例如N = 200,然后尝试:

扫描(..., nlines = N)

这样你不会重读超过 N 行。

【讨论】:

  • 这是一个不错的方法,但我不能真正保证关于标题大小的任何事情。我对使用文件指针的函数感到非常满意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-08
  • 1970-01-01
相关资源
最近更新 更多