如何快速找到目录中缺少第一行的所有文件?
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
我有一个包含 .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