免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7271 | 回复: 15
打印 上一主题 下一主题

【问题】连续区间合并 [复制链接]

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-12 16:55 |只看该作者 |倒序浏览
30可用积分
本帖最后由 huang6894 于 2014-08-13 09:10 编辑

额,是我上一个帖子的简化版~

现在得到一些这样的文本:

  1. 16642     chr1    2336225 18      HOM     del
  2. 16642     chr1    2336226 17      HOM     del
  3. 16642     chr1    2336227 17      HOM     del
  4. 16642     chr1    2336228 18      HOM     del
  5. 16642     chr1    2336236 17      HOM     del
  6. 16642     chr1    2336237 17      HOM     del
  7. 16642     chr1    2336309 24      HOM     del
  8. 16642     chr1    2336320 24      HOM     del
  9. 16642     chr1    2336321 24      HOM     del
  10. 16642     chr1    2336322 24      HET     del
  11. 16642     chr1    2336323 24      HET     del
  12. 16642     chr1    2336324 24      HET     del
  13. 16642     chr1    2336325 24      HOM     del
复制代码
我想对上面文本进行处理,如果第2、5、6列相同时,判断第3列是否连续,如果连续的数字达到3行以上,合并之~最后得到:

  1. 16642     chr1    2336225-2336228      HOM     del
  2. 16642     chr1    2336322-2336324      HET     del
复制代码
我记得之前有人回答过相关的问题,可是找不到原贴了,只好厚颜请求大神帮帮忙了,谢谢谢谢



----------------------------update--------------------------------------

问题解决,非常感谢两位大师@stanley_tam@yestreenstars
因为只能给一个最佳答案,选了一个时间相对短一点的。。。
stanley_tam大神的答案见:9楼

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
2 [报告]
发表于 2014-08-12 16:55 |只看该作者
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4. my $first_line = <DATA>;
  5. my $str = join(" ", (split /\s+/, $first_line)[0, 1, 4, 5]);
  6. my($min, $max);
  7. $min = $max = (split /\s+/, $first_line)[2];
  8. while(<DATA>){
  9.         my @fields = split;
  10.         if(join(" ", (split)[0, 1, 4, 5]) eq $str){
  11.                 if($fields[2] - $max == 1){
  12.                         $max = $fields[2];
  13.                         next;
  14.                 }else{
  15.                         print join("\t", (split /\s+/, $str)[0, 1], "$min-$max", (split /\s+/, $str)[2, 3]), $/ if $max - $min >= 2;
  16.                 }
  17.         }else{
  18.                 print join("\t", (split /\s+/, $str)[0, 1], "$min-$max", (split /\s+/, $str)[2, 3]), $/ if $max - $min >= 2;
  19.         }
  20.         $str = join(" ", (split)[0, 1, 4, 5]);
  21.         $min = $max = $fields[2];
  22. }
  23. print join("\t", (split /\s+/, $str)[0, 1], "$min-$max", (split /\s+/, $str)[2, 3]), $/ if $max - $min >= 2;
  24. __DATA__
  25. 16642     chr1    2336225 18      HOM     del
  26. 16642     chr1    2336226 17      HOM     del
  27. 16642     chr1    2336227 17      HOM     del
  28. 16642     chr1    2336228 18      HOM     del
  29. 16642     chr1    2336236 17      HOM     del
  30. 16642     chr1    2336237 17      HOM     del
  31. 16642     chr1    2336309 24      HOM     del
  32. 16642     chr1    2336320 24      HOM     del
  33. 16642     chr1    2336321 24      HOM     del
  34. 16642     chr1    2336322 24      HET     del
  35. 16642     chr1    2336323 24      HET     del
  36. 16642     chr1    2336324 24      HET     del
  37. 16642     chr1    2336325 24      HOM     del
复制代码

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
3 [报告]
发表于 2014-08-12 17:28 |只看该作者
以前是写过一个. 但解决不了楼主的问题.

个人以为, 楼主自己要的未必只是合并这么简单. 可否先对源文件进行排序, 然后再处理. 这样, 由于只是处理连续读进来的数据, 所以, 不会消耗太多的内存. 也更简单.

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
4 [报告]
发表于 2014-08-12 17:29 |只看该作者
回复 2# q1208c


    是的,我也是这么做的,可是突然不怎么记得如何合并了,他们确实排序了

论坛徽章:
33
荣誉会员
日期:2011-11-23 16:44:17天秤座
日期:2014-08-26 16:18:20天秤座
日期:2014-08-29 10:12:18丑牛
日期:2014-08-29 16:06:45丑牛
日期:2014-09-03 10:28:58射手座
日期:2014-09-03 16:01:17寅虎
日期:2014-09-11 14:24:21天蝎座
日期:2014-09-17 08:33:55IT运维版块每日发帖之星
日期:2016-04-17 06:23:27操作系统版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-24 06:20:0015-16赛季CBA联赛之天津
日期:2016-05-06 12:46:59
5 [报告]
发表于 2014-08-12 17:37 |只看该作者
回复 3# huang6894


排序了还不简单, 把你要的几个变量合并成一个. 存为 $aa

如果 $aa 为 空, 说明是第一行, 读下一行, 然后比较 $3, 如果 $3 跟前一个 $3 是连续的, 那就再读一行. 满足条件就输出. 不然就重置.     

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
6 [报告]
发表于 2014-08-12 17:55 |只看该作者
回复 4# q1208c


    满足条件就输出. 不然就重置.就是这个不懂 而且实际数据时我是需要满足200行。。。

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
7 [报告]
发表于 2014-08-12 18:23 |只看该作者
回复 1# huang6894


    看你自己发表的帖子就能找到原帖

论坛徽章:
8
技术图书徽章
日期:2013-08-22 11:21:28未羊
日期:2015-01-19 22:22:25巳蛇
日期:2014-08-11 16:53:08子鼠
日期:2014-05-29 09:04:44摩羯座
日期:2014-04-11 14:15:07丑牛
日期:2014-01-24 12:41:28金牛座
日期:2013-11-21 17:38:28射手座
日期:2015-01-21 08:50:32
8 [报告]
发表于 2014-08-12 21:06 |只看该作者
回复 6# yinyuemi


    谢谢SS兄。。。我应该没问过,不然我应该记得~谢谢~

论坛徽章:
6
丑牛
日期:2014-03-21 15:42:04子鼠
日期:2014-04-12 11:50:17处女座
日期:2014-09-01 09:25:1115-16赛季CBA联赛之吉林
日期:2015-12-22 14:01:5215-16赛季CBA联赛之广东
日期:2016-03-08 18:49:422016科比退役纪念章
日期:2016-07-06 12:19:55
9 [报告]
发表于 2014-08-12 21:30 |只看该作者
本帖最后由 stanley_tam 于 2014-08-12 21:36 编辑

貌似设置几个变量记录上一行的信息和start number就可以了,这样行不行{:3_193:}
  1. #!perl
  2. use Modern::Perl;
  3. use FileHandle;

  4. my $your_data_file = 'a.txt';
  5. my $fh = FileHandle->new($your_data_file, 'r');

  6. my $start_num = q{};
  7. my $last_line = [ q{}, q{}, 0, q{}, q{}, q{} ];

  8. my $count = 0;
  9. while (my $line = $fh->getline) {
  10.     # remove trailing newline
  11.     chomp $line;

  12.     # get columns of current line
  13.     my $current_line = [(split /\s+/, $line)];

  14.     # compare currentline with last line
  15.     if ($current_line->[2] == $last_line->[2] + 1) { # number increase by one
  16.         
  17.         if ($last_line->[1] eq $current_line->[1] and
  18.             $last_line->[4] eq $current_line->[4] and
  19.             $last_line->[5] eq $current_line->[5]) { # column 2, 5, 6 are equal
  20.             # valid consecutive row, note it
  21.             ++$count;
  22.         }
  23.         else {
  24.             # column 2, 5, 6 not equal
  25.             # the first line doesn't count, $count equal 2 suffice
  26.             if ($count >= 2) {
  27.                 my @copy = @{ $last_line };
  28.                 $copy[2] = "$start_num-$copy[2]";
  29.                 say join "\t", @copy;
  30.             }

  31.             # reset
  32.             $start_num = $current_line->[2];
  33.             $count     = 0;
  34.         }
  35.     }
  36.     else {
  37.         # number not consecutive
  38.         if ($count >= 2) {
  39.             my @copy = @{ $last_line };
  40.             $copy[2] = "$start_num-$copy[2]";
  41.             say join "\t", @copy;
  42.         }

  43.         # reset
  44.         $start_num = $current_line->[2];
  45.         $count     = 0;
  46.     }

  47.     $last_line = $current_line;
  48. }

  49. $fh->close;

  50. __END__
复制代码

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00
10 [报告]
发表于 2014-08-12 22:45 |只看该作者
貌似可以用BEDtools, mergeBED和multiIntersectBed..自己google之。
遇到生信的问题先想别人已经写过的binary,多上Seqanswers和Biostar查查看。就像写代码的查查CPAN,去stackoverflow一样..
而不是直接写Perl。
BEDtools是C写的,代码效率也不错。

https://www.biostars.org/p/49581/
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP