使用R同时读取多个文件的第一行和最后一行



我得到了许多不同大小的.csv文件。我选择其中一些在某个条件下对应的(在示例中与我的id匹配的(。它们是按日期订购的,数量可能很大。我需要知道这些文件的最短和最长日期。

我可以阅读所有需要的,并且只针对列date.hour,然后我可以很容易地找到所有日期值的最小值和最大值。

但是,如果我能只读取文件的第一行和最后一行,那么它会快得多,因为我对一千个id重复这个过程。

有人知道如何解决这个问题吗?

这个代码运行良好,但我希望改进它

一次读取多个文件的函数

`read.tables.simple <- function(file.names, ...) {require(plyr)
ldply(file.names, function(fn) data.frame(read.table(fn, ...)))}`

阅读文件并选择所有论文的最短和最长日期

`diri <- dir()
dat <- read.tables.simple(diri[1], header = TRUE, sep = ";", colClasses = "character")
colclass <- rep("NULL", ncol(dat))
x <- which(colnames(dat) == "date.hour")
colclass[x] <- "character"
x <- grep("id", diri)
dat <- read.tables.simple(diri[x], header = TRUE, sep = ";", colClasses = colclass)
datmin <- min(dat$date.hour)
datmax <- max(dat$date.hour)`

以下函数将读取csv的前两行(标题行和第一个数据行(,然后seek到文件末尾并读取最后一行。然后,它将这三行粘在一起,将它们作为内存中的两行csv读取,并从中返回列date.time。这将有你的最小值和最大值,因为时间是按顺序排列的。

您需要告诉函数最大行长度。如果你高估了这个数字,也没关系,但要确保这个数字小于你文件大小的三分之一。

read_head_tail <- function(file_path, line_length = 100)
{
con <- file(file_path)
open(con)
seek(con, where = 0)
first <- suppressWarnings(readChar(con, nchars = 2 * line_length))
first <- strsplit(first, "n")[[1]][1:2]
seek(con, where = file.info(file_path)$size - line_length)
last <- suppressWarnings(readChar(con, nchars = line_length))
last <- strsplit(last, "n")[[1]]
last <- last[length(last)]
close(con)
csv <- paste(paste0(first, collapse = "n"), last, sep = "n")
df <- read.csv(text = csv, stringsAsFactors = FALSE)[-1]
return(df$date.hour)
}

一般来说,read.table非常慢。如果您使用readr库中的read_tsvread_csvread_delim,则速度会快得多。

如果你在Linux/Mac操作系统上,你也可以通过设置管道只读取第一部分或最后一部分,无论你的文件有多大,这或多或少都是即时的。假设你没有列标题:

library(readr)
read_last <- function(file) {
read_tsv(pipe(paste('tail -n 1', file)), col_names=FALSE)
}
# Readr can already read only a select number of lines, use `n_max`
first <- read_tsv(file, n_max=1, col_names=FALSE)

如果您想进行并行处理,您甚至可以并行读取文件,例如参见library(parallel)?mclapply

相关内容

  • 没有找到相关文章

最新更新