我正在尝试从R中的单个文件中提取多个表。我的文件包含具有相同数量的变量但具有可变数量的记录的表。我想只提取表(数字)并将它们转移到单独的文件中。在表之间有4行(空行,运行:nr,变量名,单位),我想摆脱它们。在每个空行处打破的替代方案对我来说也是一个很好的解决方案,但我还没有设法做到这一点。下面我提供了文件示例 - 我的真实文件包含多个运行(表),每个运行超过30个变量和150-300个记录。 非常感谢你的帮助!
示例:
> data <- readLines(textConnection("
+ MODEL OUTPUT
+
+ Run: 1
+ V1 V2 V3
+ mm
+ 20 2 2.0
+ 21 2 1.5
+ 22 2 3.5
+
+ Run: 2
+ V1 V2 V3
+ mm
+ 1 1 1.5
+ 2 1 2.5
+
+ Run: 3
+ V1 V2 V3
+ mm
+ 11 5 1.5
+ 12 5 2.5
+ 13 5 1.0
+ 14 5 4.5"))
答案 0 :(得分:0)
如果我们没有将此标记为重复,我会回答。您可以通过一些预处理来处理这个问题,然后cumsum
来枚举文本的连续部分,最后read.table
将这些部分作为表来阅读。
创建示例数据:
file_text <- readLines(textConnection("
+ MODEL OUTPUT
+
+ Run: 1
+ V1 V2 V3
+ mm
+ 20 2 2.0
+ 21 2 1.5
+ 22 2 3.5
+
+ Run: 2
+ V1 V2 V3
+ mm
+ 1 1 1.5
+ 2 1 2.5
+
+ Run: 3
+ V1 V2 V3
+ mm
+ 11 5 1.5
+ 12 5 2.5
+ 13 5 1.0
+ 14 5 4.5"))
预处理:消除MODEL OUTPUT
,领先+
,以及只有mm
的行。
file_text = file_text[!grepl('MODEL OUTPUT', file_text)]
file_text = file_text[!grepl('Run: \\d+', file_text)]
file_text = sapply(file_text, sub, pattern = "^\\s*\\+", replacement = "")
file_text = file_text[!grepl('^\\s*mm\\s*$', file_text)]
识别空行 - 将这些段称为段之间的断点 - 然后按节对行进行编号。
is_break = unname(sapply(file_text, function(x) trimws(x) == ""))
section_id = unname(cumsum(is_break))
section_id
# [1] 1 2 2 2 2 2 3 3 3 3 4 4 4 4 4 4
最后将文件文本拆分为多个部分并将其作为表格读取:
tabs = lapply(unique(section_id), function(i) {
# the first line of a section will always be empty
section_lines = file_text[section_id == i][-1]
if (length(section_lines)) {
# there's a section of text
read.table(text = section_lines, header = TRUE)
} else {
# there were two consecutive section breaks, so after the first break
# there's an empty 'section'
NA
}
})
结果是data.frames列表。根据需要,现在或更早地处理丢失的表。
tabs
# [[1]]
# [1] NA
#
# [[2]]
# V1 V2 V3
# 1 20 2 2.0
# 2 21 2 1.5
# 3 22 2 3.5
#
# [[3]]
# V1 V2 V3
# 1 1 1 1.5
# 2 2 1 2.5
#
# [[4]]
# V1 V2 V3
# 1 11 5 1.5
# 2 12 5 2.5
# 3 13 5 1.0
# 4 14 5 4.5
#