读取txt文件,其中每n行开始一个新行,由特殊字符分隔

问题描述

我正在阅读一个包含氨基酸序列数据的文件。 600000 蛋白质。 for whomever this might be of interest,here the source

由于文件大小和方便,我使用 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 package (v0.3.0) 于 2021 年 1 月 7 日创建

解决方法

分别读取奇数和偶数行,using 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",fread(cmd = "sed -n 'n;p' pdb_seqres.txt"))
cat("Finished in","\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 = "|")