R 一种文本文件过滤算法

R 一种文本文件过滤算法,r,import,R,Import,假设您有一个结构如下的.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 ... 我想读取所有数据,除了>>表示的行和>>>文件末尾行下方的行。 到目前为止,我已经使用read.table(comment.char=“>”,

假设您有一个结构如下的
.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
...
我想读取所有数据,除了
>>
表示的行和
>>>文件末尾
行下方的行。 到目前为止,我已经使用
read.table(comment.char=“>”,skip=x,nrow=y)解决了这个问题。
x
y
目前是固定的)。这将读取头和文件结尾之间的数据

cat("/^>>> end of file/ { exit }; /^>>>/ { next }; 1\n", file = "foo.awk")
read.table(pipe('gawk -f foo.awk foo.txt'), header = TRUE)
但是,我想让我的函数在行数方面更具可塑性。数据的值可能大于800,因此会有更多行


我可以
扫描
读取行
文件,查看哪一行对应于文件末尾,并计算要读取的行数。您将使用什么方法?

这里有一种方法:

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)

在您提供的数据片段上(在文件
foo.txt中,删除…行之后)。

以下是几种方法

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)
2) 另一种可能是使用sed或awk/gawk。考虑这一行GAWK程序。如果程序看到标记数据结束的行,则退出;否则,如果当前行以>>>开头,则跳过该行,如果两者都没有发生,则打印该行。我们可以通过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)

一种变体是我们可以省略
/^>>>/{next}部分,它跳过开头的
>
行,并在
read.table`call中使用
comment=“>”。

请提供一些虚拟数据。=)@aL3xa:代码片段是否已经显示不足?+1,很高兴了解
rle
,这是我以前没有使用过的。我想知道是否有办法修改
read.table
(和/或
scan
和/或
readLines
)的定义,方法是添加一个可选的
EOF
参数,这样当遇到
EOF
字符串时,它就会退出。这样我们就可以一次完成而不是2次。EOF参数将是一个很好的添加。我希望有一种方法可以将可选的EOF参数添加到
scan
的源定义中,但它调用
.Internal(scan…
),所以唯一的方法是更改内部(C?)代码进行扫描…textConnection()的一个小副作用在函数(lappy)中,连接得到gc()-ed,这会产生一个恼人的警告(无害)。这可以在调用textConnection()后使用closeAllConnections()解决。@Roman;说得好。如果我经常使用上面的方法,我会将其封装在一个函数中,保存
con的输出。如果您不能提前预见文件的结构,那么awk/gawk解决方案将非常方便。
cat("/^>>> end of file/ { exit }; /^>>>/ { next }; 1\n", file = "foo.awk")
read.table(pipe('gawk -f foo.awk foo.txt'), header = TRUE)