微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

根据第4列值过滤的行与上一行和下一行的差大于80

如何解决根据第4列值过滤的行与上一行和下一行的差大于80

我有一个这样的文件,大约有2000万行。

val

我需要检查第二列是否相同,第三列中的值距上一行大于80,而距下一行小于80。表格示例如下。

[![在此处输入图片描述] [1]] [1]

最终期望结果是第5列或第6列均不小于80的那些

因此所需的表格将如下所示

11.tsv       SDSS01001000.1 M1  100021
11.tsv       SDSS01001000.1 M1  100082
11.tsv       SDSS01001000.1 M1  100140
11.tsv       SDSS01001000.1 M1  100270
11.tsv       SDSS01001000.1 M1  100634
11.tsv       SDSS01001000.1 M1  100849
11.tsv       SDSS01001000.1 M1  100865
11.tsv       SDSS01001000.1 M1  101037
11.tsv       SDSS01001000.1 M1  101086
11.tsv       SDSS01001000.1 M1  101164
11.tsv       SDSS01001000.1 M1  101203
11.tsv       SDSS01001000.1 M1  101338
11.tsv       SDSS01001000.1 M1  101844
11.tsv       SDSS01001000.1 M1  102117
11.tsv       SDSS01001000.1 M1  102224

简而言之,我想过滤第4列中的值与上一行和下一行的差异大于80的行。 这是一个生物学问题,第二列和第四列分别对应于染色体数目和染色体位置。我需要过滤那些在80个碱基附近没有其他报告位置的位置。

预先感谢您的帮助。

目前,我从该位置添加和减去了80,使其像床文件一样具有开始和结束位置,然后使用此命令检入文件中是否在开始和结束位置都没有位置。

11.tsv  SDSS01001000.1  M1  100270
11.tsv  SDSS01001000.1  M1  100634
11.tsv  SDSS01001000.1  M1  101338
11.tsv  SDSS01001000.1  M1  101844
11.tsv  SDSS01001000.1  M1  102117
11.tsv  SDSS01001000.1  M1  102224

但这很耗时。处理每个文件需要几天的时间。请帮忙 [1]:https://i.stack.imgur.com/u48Vx.png [2]:https://i.stack.imgur.com/3EPGe.png

解决方法

#!/usr/bin/perl
use warnings; use strict;
sub second_col {(split(/\s+/,shift))[1]}
sub fourth_col {(split(/\s+/,shift))[3]}
my($prev,$this,$next);
while(<>){
    ($prev,$next)=($this,$next,$_);
    next if not defined $prev;
    next if second_col($prev) ne second_col($this);
    next if second_col($this) ne second_col($next);
    next if fourth_col($this) - fourth_col($prev) < 80;
    next if fourth_col($next) - fourth_col($this) < 80;
    print $this;
}

运行:

chmod +x program.pl
./program.pl datafile
,
myfun() {
  perl -ane 'if($F[3]-$pos[1] > 80 and $pos[1]-$pos[0] > 80) { print $last_line; }
             $last_line=$_;
             push(@pos,$F[3]);
             $#pos > 1 and shift @pos;
             END{if($pos[1]-$pos[0] > 80) { print $last_line; }}';
}
export -f myfun
cat bigfile | parallel -N1 --pipe --group-by 2 myfun

这在我的笔记本电脑上以20 MB / s的速度处理。

它使用GNU Parallel的--group-by查看第2列,对于第2列的值相同的每个块,在该块上运行myfun

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。