我会像评论中提到的@Frank 一样解决这个问题。我会将整个内容作为一个大文件读取,然后根据文件路径信息将其拆分为一个列表。lapply
一旦这些被拆分成一个列表,每个数据集都可以循环清理。
我正在通过 via阅读,但如果您愿意,您可以从XLconnectreadxl::read_excel
的 via 函数中读取整个文件。
library(readxl)
orig = read_excel("test.xlsx", col_names = FALSE)
一些假数据的前六行如下所示:
X0 X1 X2 X3 X4 X5 X6
<chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 c:\\file directory\\acoustic data\\Site 10\\20160517 <NA> <NA> <NA> <NA> <NA> <NA>
2 identification summary <NA> <NA> <NA> <NA> <NA> <NA>
3 ID EPFU LANO <NA> MID <NA> <NA>
4 N 70 12 <NA> 4 <NA> <NA>
5 % 16 3 <NA> 13 <NA> <NA>
6 MLE(p) 1E-3 2E-3 <NA> <NA> <NA> <NA>
这个原始文件应该被拆分成单独的表,这可以基于包含以“c:”开头的文件路径信息的行来完成。要找出这些在哪里,请在整个数据集的第一列上使用cumsum
with 。grepl
groups = cumsum(grepl("c:", orig$X0))
使用此向量拆分文件,通过 . 将每个单独的表保存到列表中split
。
orig_list = split(orig, groups)
现在剩下的工作是清理每个数据集,转置内容并删除任何额外的行和列。这也是您可以从文件路径中提取站点和日期信息以添加到数据集以保持事物井井有条的地方,我对此进行了演示,但并非绝对必要。我把这一切都放在一个函数中,以便在lapply
. 请注意,我曾readr::type_convert
一度用于确保数值变量已正确转换。
clean_data = function(data) {
# Get rid of any empty headers (missing values in first column)
new = data[!is.na(data[,1]),]
# Transpose
new = t(new)
# Put into data.frame, removing extraneous columns 1 to 2
# and using first row as variable names
# Convert variables to appropriate type at same time using readr::type_convert
new2 = readr::type_convert(as.data.frame(new[-1, -(1:2)]))
names(new2) = new[1, -(1:2)]
# Add site and date columns by pulling info from original "c:\\..." cell
new2$site = unlist(strsplit(new[1], "\\\\"))[4]
new2$date = unlist(strsplit(new[1], "\\\\"))[5]
# Remove everything after first missing ID
new2[cumsum(is.na(new2$ID)) == 0,]
}
现在遍历所有块并清理每一块。生成的清理文件将在列表中。如果需要,您可以将这些行绑定到一个数据集中。
lapply(orig_list, clean_data)