免费注册 查看新帖 |

Chinaunix

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

循环判断 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-12 10:59 |只看该作者 |倒序浏览
本帖最后由 papagogogo 于 2014-08-12 12:00 编辑

数据类型如下,希望按100000为宽度来查看数据中的值落在每100000宽度的区间内的情况,有则输出*,无则输出具体第几个区间。注意其中有两个208*****的数据,只需要计算一次。所以写的循环中做了一个判断,可是有错误,输出的时候到208以后就不显示*了,请大伙儿帮我看看,谢谢

另外,我处理的数据分别在一千个文件夹中,同一个名字,请问如何用perl写脚本遍历处理所有这样的数据,谢谢。

my $c=0;

       
        foreach $d(0..1000){
                if (($chr1[$c]>=$d*100000)&&($chr1[$c]<($d+1)*100000)&&(int(($chr1[$c+1])/100000)==int(($chr1[$c])/100000))){
                        $c+=1;
                }
                elsif (($chr1[$c]>=$d*100000)&&($chr1[$c]<($d+1)*100000)&&(int(($chr1[$c+1])/100000)>int(($chr1[$c])/100000))){
                        print OUTFILE "*\n";
                        $c+=1;
                        next;
        }
        else{
                print OUTFILE "$d\n";
        }
       
}


-------DATA--------
chr1            5404330
chr1           10849871        
chr1            12708335            
chr1            14535267         
chr1            16520264            
chr1            17028909           
chr1            18487098        
chr1            20845079        
chr1            20865872              
chr1            21742203              
chr1            23607338     
chr1            29240459      
chr1            30111135            
chr1            39720233      
chr1            39747770         
chr1            42174997

.......                 .......






======================
my $c=0;

        
        foreach $d(0..1000){
                if (($chr1[$c]>=$d*100000)&&($chr1[$c]<($d+1)*100000)&&(int(($chr1[$c+1])/100000)==int(($chr1[$c])/100000))){
                        $c+=1;
                        if (($chr1[$c]>=$d*100000)&&($chr1[$c]<($d+1)*100000)&&(int(($chr1[$c+1])/100000)>int(($chr1[$c])/100000))){
                        print OUTFILE "*\n";
                        $c+=1;
                        next;
        }
                }
                elsif (($chr1[$c]>=$d*100000)&&($chr1[$c]<($d+1)*100000)&&(int(($chr1[$c+1])/100000)>int(($chr1[$c])/100000))){
                        print OUTFILE "*\n";
                        $c+=1;
                        next;
        }
        else{
                print OUTFILE "$d\n";
        }
        
}

我把elsif的内容放到if里面去,可以了。可是如果遇到三个208这种情况,又不行了,这不科学。不可能一直嵌套吧。。

论坛徽章:
0
2 [报告]
发表于 2014-08-12 11:26 |只看该作者
本帖最后由 afukada 于 2014-08-12 11:34 编辑

看你的數據

我猜你想找的東西是不是鄰近的兩個位點是不是分別位於以每100000為單位區間的兩個不同區間

比方說

Chr1 12563     <- 第1點
Chr1 112431   <- 第2點
Chr1 312231   <- 第3點
Chr1 317231   <- 第4點
Chr1 600243   <- 第5點

這邊可以分成

1-100000, 100001-200000, 200001-300000, 300001-400000, 400001-500000, 500001-600000, 600001-700000, 700001-800000, ...
區間1          區間2                   區間3                   區間4                   區間5                    區間6                   區間7                   區間8

其中
第1點位於區間1
第2點位於區間2
第3點位於區間4
第4點位於區間4
第5點位於區間7

因為第2點和第3點位於同區間
所以區間1,區間2,區間4,區間7輸出*
      區間3,區間5,區間6,區間8輸出區間

是這樣嗎?

论坛徽章:
0
3 [报告]
发表于 2014-08-12 11:33 |只看该作者
差不多,但是是没有在这个区间的时候就输出区间号,在则输出*,如果有多个在只输出一个*。我知道我问题出在哪了,我以为当遇到208的时候第一个if执行完了会执行第二个elsif,可是事实上只能在for中执行一次,可是如果是这样的话,怎么写呢。

回复 2# afukada


   

论坛徽章:
0
4 [报告]
发表于 2014-08-12 11:39 |只看该作者
本帖最后由 papagogogo 于 2014-08-12 11:40 编辑

my $c=0;

       
        foreach $d(0..1000){
                if (($chr1[$c]>=$d*100000)&&($chr1[$c]<($d+1)*100000)&&(int(($chr1[$c+1])/100000)==int(($chr1[$c])/100000))){
                        $c+=1;
                        if (($chr1[$c]>=$d*100000)&&($chr1[$c]<($d+1)*100000)&&(int(($chr1[$c+1])/100000)>int(($chr1[$c])/100000))){
                        print OUTFILE "*\n";
                        $c+=1;
                        next;
        }
                }
                elsif (($chr1[$c]>=$d*100000)&&($chr1[$c]<($d+1)*100000)&&(int(($chr1[$c+1])/100000)>int(($chr1[$c])/100000))){
                        print OUTFILE "*\n";
                        $c+=1;
                        next;
        }
        else{
                print OUTFILE "$d\n";
        }
       
}

我把elsif的内容放到if里面去,可以了。可是如果遇到三个208这种情况,又不行了,这不科学。不可能一直嵌套吧。。

论坛徽章:
0
5 [报告]
发表于 2014-08-12 12:11 |只看该作者
你會使用hash嗎?

用區域當key

然後點的數目當value

只要value等於0

就表示沒有點

论坛徽章:
0
6 [报告]
发表于 2014-08-12 12:48 |只看该作者

用hash也要判断吧?具体应该怎么写呢
回复 5# afukada


   

论坛徽章:
0
7 [报告]
发表于 2014-08-12 13:08 |只看该作者
剛剛想了想 好像也不用用hash

主要是需要做兩次
  1. while(<DATA>)
  2. {
  3.         chomp;
  4.         ($chr,$pos)=split;
  5.         $chr1[int($pos/100000)]++;
  6. }

  7. foreach $d(0..1000)
  8. {
  9.         if($chr1[$d])
  10.         {
  11.                 print OUTFILE "*\n";
  12.         }
  13.         else
  14.         {
  15.                 print OUTFILE "$d\n";
  16.         }
  17. }
复制代码
先讀檔

然後在判斷有沒有點位於區間內

论坛徽章:
0
8 [报告]
发表于 2014-08-12 13:51 |只看该作者
($chr,$pos)=split;
$chr1[int($pos/100000)]++;

这两句没看懂呢?而且好像run不起来哇

回复 7# afukada


   

论坛徽章:
0
9 [报告]
发表于 2014-08-12 14:23 |只看该作者
($chr,$pos)=split; 讀檔進來切成 chromosome 和 position
$chr1[int($pos/100000)]++; 計算區域內有幾個位置存在

run不起來是沒有讀寫檔
我只是寫個大概想法

论坛徽章:
0
10 [报告]
发表于 2014-08-12 15:05 |只看该作者

我再看看非常感谢,我用之前我的方法把if下面加for实现了,但是代码就没有你这个那么精简,我仔细研究下。
回复 9# afukada


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP