这是一种可扩展的方法。首先,将整个文件读入带有readLines 的变量。我将使用textConnection 在 SO 上进行重现,但您应该从文件中读取。
x <- readLines(con=textConnection('
SOURCE
Boxofficemojo.com
STORY
These lines, of variable length and number, would contain the story behind the dataset.
USAGE
"Course" "Year" "Section" "Exercise"
"Course1" 5 9 "ex 3"
"Course1" 5 9 "ex 4"
"Course1" 5 9 "ex 5"
"Course2" 5 9 "ex 3"
"Course2" 5 9 "ex 4"
DATASET
Dataset with headers follows.'))
过滤掉前面我介绍的空行:
head(x)
# [1] ""
# [2] "SOURCE"
# [3] "Boxofficemojo.com"
# [4] ""
# [5] "STORY"
# [6] "These lines, of variable length and number, would contain the story behind the dataset."
allcaps <- grep("^[A-Z]+$", x)
if (allcaps[1] > 1) x <- x[-(1:(allcaps[1]-1))]
我推断只有大写字母的行表示“标题”。这也可以通过cumsum(x %in% c("USAGE",...)) 来完成:
str( x2 <- split(x, cumsum(grepl("^[A-Z]+$", x))) )
# List of 4
# $ 1: chr [1:3] "SOURCE" "Boxofficemojo.com" ""
# $ 2: chr [1:3] "STORY" "These lines, of variable length and number, would contain the story behind the dataset." ""
# $ 3: chr [1:8] "USAGE" "\"Course\" \"Year\" \"Section\" \"Exercise\"" "\"Course1\" 5 9 \"ex 3\"" "\"Course1\" 5 9 \"ex 4\"" ...
# $ 4: chr [1:2] "DATASET" "Dataset with headers follows."
(您也可以选择删除尾随的空字符串,也许使用x2 <- lapply(x2, head, n=-1) 之类的东西,尽管最后一个会受到影响,因为它没有它。使用Filter(nchar, x2) 也可能有效,但它假设没有“有意的”空行。交给你。)
下一步可能是装饰性的,但将“标题”作为列表元素名称,随后的行作为数据:
str( x3 <- setNames(lapply(x2, `[`, -1L),
sapply(x2, `[`, 1L)) )
# List of 4
# $ SOURCE : chr [1:2] "Boxofficemojo.com" ""
# $ STORY : chr [1:2] "These lines, of variable length and number, would contain the story behind the dataset." ""
# $ USAGE : chr [1:7] "\"Course\" \"Year\" \"Section\" \"Exercise\"" "\"Course1\" 5 9 \"ex 3\"" "\"Course1\" 5 9 \"ex 4\"" "\"Course1\" 5 9 \"ex 5\"" ...
# $ DATASET: chr "Dataset with headers follows."
最后,你可以对嵌入的元素做任何你需要的事情:
x3$USAGE <- read.table(textConnection(x3$USAGE), header=TRUE)
str(x3)
# List of 4
# $ SOURCE : chr [1:2] "Boxofficemojo.com" ""
# $ STORY : chr [1:2] "These lines, of variable length and number, would contain the story behind the dataset." ""
# $ USAGE :'data.frame': 5 obs. of 4 variables:
# ..$ Course : Factor w/ 2 levels "Course1","Course2": 1 1 1 2 2
# ..$ Year : int [1:5] 5 5 5 5 5
# ..$ Section : int [1:5] 9 9 9 9 9
# ..$ Exercise: Factor w/ 3 levels "ex 3","ex 4",..: 1 2 3 1 2
# $ DATASET: chr "Dataset with headers follows."