首页 > 解决方案 > 读取 txt 文件,其中每 n 行开始一个新行,由特殊字符分隔

问题描述

我正在阅读一个包含大约氨基酸序列数据的文件。600000 种蛋白质。 对于任何可能感兴趣的人,这里的来源

data.table::fread由于文件大小和方便起见,我正在使用。“问题”是该文件仅每第二行包含一个新条目,并以“>”引入。这不是什么大问题,因为我可以做一些小的争吵,我想要它就可以了。(请参阅所需的输出,甚至是“理想输出”)。

我想知道是否有直接的方法来读取具有这种结构的文件。当然也欢迎任何其他包,但它应该能很好地处理这种尺寸。

library(tidyverse)

# "text = ..." contains a shortened version of the first two entries of the downloaded txt file
prot <- data.table::fread(text = 
">101m_A mol:protein length:154  MYOGLOBIN
QGAMNKALEL
>102l_A mol:protein length:165  T4 LYSOZYME
RAKRVITTFR", 
header = FALSE
)

prot <- as.data.frame(prot)

# expected output
exp_out <- bind_cols(prot = prot[c(T, F), ], aminoseq = prot[c(F, T), ] )
exp_out
#> # A tibble: 2 x 2
#>   prot                                        aminoseq  
#>   <chr>                                       <chr>     
#> 1 >101m_A mol:protein length:154  MYOGLOBIN   QGAMNKALEL
#> 2 >102l_A mol:protein length:165  T4 LYSOZYME RAKRVITTFR

# ideal output
exp_out %>%
  separate(prot, c("mol", "length"), sep = ":protein length:") %>%
  separate(length, c("length", "name"), sep = "\\s{2}+")
#> # A tibble: 2 x 4
#>   mol         length name        aminoseq  
#>   <chr>       <chr>  <chr>       <chr>     
#> 1 >101m_A mol 154    MYOGLOBIN   QGAMNKALEL
#> 2 >102l_A mol 165    T4 LYSOZYME RAKRVITTFR

reprex 包(v0.3.0)于 2021-01-07 创建

标签: rdata.tablebioinformaticsfasta

解决方案


使用 sed分别读取奇数行和偶数行,然后使用列绑定fread,这将使您获得“预期输出”,它也非常快,解压缩输入大约需要 2 秒:

# get the data
# wget ftp://ftp.wwpdb.org/pub/pdb/derived_data/pdb_seqres.txt.gz
library(data.table)

# unzip on the fly
started.at = proc.time()
d <- cbind(
  fread(cmd = "zcat pdb_seqres.txt.gz | sed -n 'p;n'", sep = "|"),
  fread(cmd = "zcat pdb_seqres.txt.gz | sed -n 'n;p'"))
cat("Finished in", timetaken(started.at), "\n")
# Finished in 4.585s elapsed (1.788s cpu)

# read unzipped input
started.at = proc.time()
d <- cbind(
  fread(cmd = "sed -n 'p;n' pdb_seqres.txt", sep = "|"),
  fread(cmd = "sed -n 'n;p' pdb_seqres.txt"))
cat("Finished in", timetaken(started.at), "\n")
# Finished in 1.796s elapsed (1.111s cpu)

理论上,下面应该可以工作,即我们在freading之前使用 bash paste进行列绑定,但它不断给我有关临时文件权限的错误,可能适用于您的设置。

fread(cmd = "paste -d'|' <(sed -n 'p;n' pdb_seqres.txt) <(sed -n 'n;p' pdb_seqres.txt)",
      sep = "|")

推荐阅读