想象一下,你有一个以下结构的.txt
文件:
>>> header
>>> header
>>> header
K L M
200 0.1 1
201 0.8 1
202 0.01 3
...
800 0.4 2
>>> end of file
50 0.1 1
75 0.78 5
...
我想读取除>>>
表示的行和>>> end of file
行下面的行以外的所有数据。
到目前为止,我已使用read.table(comment.char = ">", skip = x, nrow = y)
(x
和y
目前已修复)解决了这个问题。这将读取标头和>>> end of file
之间的数据。
但是,我想让我的功能在行数上更加可塑。数据的值可能大于800,因此行数更多。
我可以scan
或readLines
该文件,看看哪一行对应>>> end of file
并计算要读取的行数。你会用什么方法?
答案 0 :(得分:11)
这是一种方法:
Lines <- readLines("foo.txt")
markers <- grepl(">", Lines)
want <- rle(markers)$lengths[1:2]
want <- seq.int(want[1] + 1, sum(want), by = 1)
read.table(textConnection(Lines[want]), sep = " ", header = TRUE)
给出了:
> read.table(textConnection(Lines[want]), sep = " ", header = TRUE)
K L M
1 200 0.10 1
2 201 0.80 1
3 202 0.01 3
4 800 0.40 2
在您提供的数据代码段中(在文件foo.txt
中,并在删除...行后)。
答案 1 :(得分:11)
以下是两种方法。
1)readLine
将文件行读入L
并将skip
设置为开头要跳过的行数,end.of.file
为行号标记数据结尾的行。然后read.table
命令使用这两个变量重新读取数据。
File <- "foo.txt"
L <- readLines(File)
skip <- grep("^.{0,2}[^>]", L)[1] - 1
end.of.file <- grep("^>>> end of file", L)
read.table(File, header = TRUE, skip = skip, nrow = end.of.file - skip - 2)
变体是使用textConnection
代替File
行中的read.table
:
read.table(textConnection(L), header = TRUE,
skip = skip, nrow = end.of.file - skip - 2)
2)另一种可能性是使用sed或awk / gawk。考虑这一行gawk程序。如果程序看到标记数据结尾的行,则程序退出;否则,如果该行以&gt;&gt;&gt;开头,它会跳过当前行如果这些都不发生,则打印出该行。我们可以通过gawk程序管道foo.txt
并使用read.table
读取它。
cat("/^>>> end of file/ { exit }; /^>>>/ { next }; 1\n", file = "foo.awk")
read.table(pipe('gawk -f foo.awk foo.txt'), header = TRUE)
这样做的一个变体是我们可以省略gawk程序的/^>>>/ {next};
部分,该部分跳过开头的>>>
行,并使用comment = ">" in the
read.table`调用代替。