找回密码
 注册
查看: 3707|回复: 4

求助,这种情况能否用perl解决

[复制链接]
发表于 2011-7-27 03:46:05 | 显示全部楼层 |阅读模式
本帖最后由 blairw 于 2011-7-27 03:47 编辑

我的数据是
22        rs4819391        0        14550436
22        rs11089128        0        14560203
22        rs7288972        0        14564328
22        rs2032141        0        14676285
22        rs11912265        0        14715506
22        rs4321465        0        14836970
22        rs11167319        0        14850625
22        rs8138488        0        14870204
22        rs2186521        0        14878387
...

有几万行吧。

我想做的事是按照第四列分区,每一个区长度为20480,然后返回给我第二列的值,并且只要每个区间第一个和最后一个值。比如,上述数据中红色的两个数字就是第一个区间的头跟尾,但应该返回给我的是黄绿色的两个值。然后再从下一行起重新进行上述选择,也就是紫色的数值为第二个区间的头尾,但只要给我粉色的数值即可。由于得出的数值还要进行别的运算,所以要用循环来做。

有大侠知道怎么弄这个么??能用Perl搞定么?万分感谢。
回复

使用道具 举报

发表于 2011-7-27 22:53:44 | 显示全部楼层
本帖最后由 xiaoliu 于 2011-7-27 22:55 编辑

#!/usr/bin/perl
my @array;
my $temp;
my $i;
my $num;
open MYFILE,("c://data.txt");
open OUT,("+>c://out.txt");
$num=1;
$_=<MYFILE>;
chomp($_);
@array=split/\s+/;
$i=$array[3];
print "Interval $num start: $array[1] $array[3] - ";
while(<MYFILE>){
   chomp($_);
   @array=split/\s+/;
    if(($array[3]-$i)>20480){

       print "Interval $num end:$array[1] $array[3]\n";
           $num=$num+1;
$_=<MYFILE>;
chomp($_);
@array=split/\s+/;
$i=$array[3];
  print "Interval $num start: $array[1] $array[3] - ";
    }

}



运行结果

Interval 1 start: rs4819391 14550436 - Interval 1 end:rs2032141 14676285
Interval 2 start: rs11912265 14715506 - Interval 2 end:rs4321465 14836970
Interval 3 start: rs11167319 14850625 - Interval 3 end:rs2186521 14878387
Interval 4 start:   -

输出print里面的部分根据自己的需要,调一下就行了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-7-28 03:00:12 | 显示全部楼层
xiaoliu 发表于 2011-7-27 22:53
#!/usr/bin/perl
my @array;
my $temp;

大侠啊,万分感谢。

但我code不是看的很懂,请问$i 是做什么用的?我需要得出每个区间的起始跟结束,然后用在后面的程序中--from $start --to $end这样的,每得出一个区间,就做一遍我下面的程序,在这里是不是可以直接把一个$i 换成两个变量:$start 跟$end?我是想做如下:

$num=1;
get $start and $end;
{my code here: --from $start --to $end}
$num=$num+1;

也就是说我不仅仅要得出起始点跟结束点,还要将其用在其他的code中,请问perl里可以提取出这两个值嘛?谢谢~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-7-28 03:31:37 | 显示全部楼层
xiaoliu 发表于 2011-7-27 22:53
#!/usr/bin/perl
my @array;
my $temp;

谢谢你的code,我刚研究了一下,已经知道怎么做了,我的做法是:
my @array;
my $i;
my $temp;
my $start;
my $end;
my $num;
open MYFILE,("c:/Users/Jing/Desktop/chr21.map");
open OUT,("+>c:/Users/Jing/Desktop/out.txt");
$num=1;
$_=<MYFILE>;
chomp($_);
@array=split/\s+/;
$i=$array[3];
$start=$array[1];print "Interval $num start: $array[1] $array[3] - ";
while(<MYFILE>){
   chomp($_);
   @array=split/\s+/;
    if(($array[3]-$i)>20480){
       $end=$array[1];  
print "Interval $num endarray[1] $array[3]\n";
           $num=$num+1;
print "look here $start and $end\n";
MY OTHER CODE HERE;

$_=<MYFILE>;
chomp($_);
@array=split/\s+/;
$start=$array[1];
  print "Interval $num start: $array[1] $array[3] - ";
    }

}
不知道是不是有更好的方法呢?不过我得到我想要的结果了,谢谢你噢!我刚开始用Perl,感觉有好多要学习啊,像牛人学习!
回复 支持 反对

使用道具 举报

发表于 2011-8-2 10:59:40 | 显示全部楼层
本帖最后由 genechip 于 2011-8-2 11:06 编辑

对于楼主所述问题,我还是不是非常清楚。不过总体感觉用R语言也可以做
楼主的数据如下
> rad
         V1         V2 V3       V4
14550436 22  rs4819391  0 14550436
14560203 22 rs11089128  0 14560203
14564328 22  rs7288972  0 14564328
14676285 22  rs2032141  0 14676285
14715506 22 rs11912265  0 14715506
14836970 22  rs4321465  0 14836970
14850625 22 rs11167319  0 14850625
14870204 22  rs8138488  0 14870204
14878387 22  rs2186521  0 14878387

> class(rad)
[1] "data.frame"

> temp<-is.element(as.numeric(rad[,4]),c(14550436,14676285,14715506,14836970))
> temp
[1]  TRUE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE

> rad[temp,]
         V1         V2 V3       V4
14550436 22  rs4819391  0 14550436
14676285 22  rs2032141  0 14676285
14715506 22 rs11912265  0 14715506
14836970 22  rs4321465  0 14836970

> rad[temp,][2]
                 V2
14550436  rs4819391
14676285  rs2032141
14715506 rs11912265
14836970  rs4321465


不知是否是你需要的
回复 支持 反对

使用道具 举报

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

本版积分规则

手机版|小黑屋|生物统计家园 网站价格

GMT+8, 2024-11-23 15:55 , Processed in 0.027027 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表