我刚开始使用R并尝试掌握一些内置函数。我试图组织一个基本的FASTA文本文件,如下所示:
>ID1
AGAATAGCCAGAACCGTTTCTCTGAGGCTTCC
>ID2
TCCAATTAAGTCCCTATCCAGGCGCTCCG
>ID3
GAACCGGAGAACGCTTCAGACCAGCCCGGAC
进入一个看起来像这样的表:
ID Sequence
ID1 AGAATAGCCAGAACCGTTTCTCTGAGGCTTCC
ID2 TCCAATTAAGTCCCTATCCAGGCGCTCCG
ID3 GAACCGGAGAACGCTTCAGACCAGCCCGGAC
或者至少以类似方式组织的事情。不幸的是,每当我尝试使用read.table
时,我都被迫设置fill = TRUE
,以避免以下错误:
> read.table("ReadingText.txt", header=F, fill=F, sep=">")
Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings, :
line 2 did not have 2 elements
设置fill = TRUE
并不能解决问题,因为它只会引入不需要的空白字段。我觉得我的问题是R想要将输入中的每一个新行视为输出中的一个新行,而我希望它只在每个">&#34处开始一个新行。 ;并移动到输入的每个新行的同一行的下一列。
那么,你怎么能让这个工作? read.table只是错误的功能,试图这样做或是否有其他东西?另外,我真的很想在不使用任何软件包的情况下完成此任务!我希望能够很好地掌握R中的内置函数。
感谢您花时间阅读此内容并向我道歉,如果我在此处发布错误的话。这是我第一次问任何事情。
答案 0 :(得分:5)
使用read.table()
或readLines()
执行此操作需要一些棘手的后期处理。 seqinr 包中有一个函数read.fasta()
可以帮助您完成大部分工作。然后我们将结果列表转换为数据框。
library(seqinr)
(fasta <- read.fasta("so.fasta", set.attributes = FALSE, as.string = TRUE, forceDNAtolower = FALSE))
# $ID1
# [1] "AGAATAGCCAGAACCGTTTCTCTGAGGCTTCC"
#
# $ID2
# [1] "TCCAATTAAGTCCCTATCCAGGCGCTCCG"
#
# $ID3
# [1] "GAACCGGAGAACGCTTCAGACCAGCCCGGAC"
setNames(rev(stack(fasta)), c("ID", "Sequence"))
# ID Sequence
# 1 ID1 AGAATAGCCAGAACCGTTTCTCTGAGGCTTCC
# 2 ID2 TCCAATTAAGTCCCTATCCAGGCGCTCCG
# 3 ID3 GAACCGGAGAACGCTTCAGACCAGCCCGGAC
文件 so.fasta 是
writeLines(">ID1
AGAATAGCCAGAACCGTTTCTCTGAGGCTTCC
>ID2
TCCAATTAAGTCCCTATCCAGGCGCTCCG
>ID3
GAACCGGAGAACGCTTCAGACCAGCCCGGAC", "so.fasta")
注意: Pascal在评论中提出了一个很好的观点。当您的特定任务已存在工具时,请利用该工具并使用它。当有人已经麻烦地创建这个工具并在一个包中共享它以试图帮助其他尝试解决问题的用户时,实际上没有必要花时间尝试使用那些不适合这项工作的功能。同样的问题。
更新:实际上,使用readLines()
并不困难,只要你有一个漂亮的干净文件。这是一个仅使用基本函数的可能解决方案。
x <- readLines("so.fasta")
ids <- grepl("^>", x)
data.frame(ID = sub(">", "", x[ids]), Sequence = x[!ids])
# ID Sequence
# 1 ID1 AGAATAGCCAGAACCGTTTCTCTGAGGCTTCC
# 2 ID2 TCCAATTAAGTCCCTATCCAGGCGCTCCG
# 3 ID3 GAACCGGAGAACGCTTCAGACCAGCCCGGAC