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)