如何快速找到目录中缺少第一行的所有文件?

How can I quickly find all the files in a directory that are missing a first row?

我有一个包含 .csv 格式文件的文件夹。它们中有必要的空行(这表明 LiDAR 单元没有测量,这是好的,需要保留)。但偶尔,第一行是空的,这会抛出代码和包,一切都会中止。

现在我必须打开每个 .csv 文件并查看第一行是否为空。

我想执行以下操作之一,但不知如何操作:

1) 编写一个代码,快速扫描目录中的所有文件并告诉我哪些文件缺少第一行

2) 能够跳过仅在开头的空行——这可能会有所不同,有时不止一行是空的

3) 有一个循环遍历所有 .csv 文件并插入虚拟第一行数字的代码,因此所有文件都可以正常导入。

谢谢!

下面是执行上述 1 和 2 的一些代码。鉴于能够执行 1 和 2,我不确定为什么要插入虚拟行;做起来很简单,但通常修改原始数据文件不是一个好主意。

# Create some test files
cat("x,y", "1,2", sep="\n", file = "blank0.csv")
cat("", "x,y", "1,2", sep="\n", file = "blank1.csv")
cat("", "", "x,y", "1,2", sep="\n", file = "blank2.csv")


files <- list.files(pattern = "*.csv", full.names = TRUE)

for(i in seq_along(files)) {
  filedata <- readLines(files[i])
  lines_to_skip <- min(which(filedata != "")) - 1
  cat(i, files[i], lines_to_skip, "\n")
  x <- read.csv(files[i], skip = lines_to_skip)
}

这会打印

1 ./blank0.csv 0 
2 ./blank1.csv 1 
3 ./blank2.csv 2 

并正确读取每个数据集。

我相信后面的两个函数可以做你想做的事want/need。
首先,一个判断第二行空白的文件的函数。

second_blank <- function(path = ".", pattern = "\.csv"){
    fls <- list.files(path = path, pattern = pattern)
    second <- sapply(fls, function(f) readLines(f, n = 2)[2])
    which(nchar(gsub(",", "", second)) == 0)
}

然后,一个函数来读取包含这些行的文件,一次一个。请注意,我假设第一行是 header 列,并且至少第二行留空。有一个点参数,...,你可以将其他参数传递给 read.table,例如 stringsAsFactors = FALSE.

skip_blank <- function(file, ...){
    header <- readLines(file, n = 1)
    header <- strsplit(header, ",")[[1]]
    count <- 1L
    while(TRUE){
        txt <- scan(file, what = "character", skip = count, nlines = 1)
        if(nchar(gsub(",", "", txt)) > 0) break
        count <- count + 1L
    }
    dat <- read.table(file, skip = count, header = TRUE, sep = ",", dec = ".", fill = TRUE, ...)
    names(dat) <- header
    dat
}

现在,一个用法示例。

second_blank(pattern = "csv")  # a first run as an example usage
inx <- second_blank()          # this will be needed later

fl_names <- list.files(pattern = "\.csv")  # get all the CSV files

df_list <- lapply(fl_names[inx], skip_blank)  # read the problem ones
names(df_list) <- fl_names[inx]               # tidy up the result list
df_list