Perl 若值介于两个值之间,则将另一个值添加到相应的行中

Perl 若值介于两个值之间,则将另一个值添加到相应的行中,perl,Perl,这是对我的问题的描述:我有两个文本文件(这里是$variants和$annotation)。我想检查$variants中第2列的值是否位于$annotation中第2列和第3列的值之间。如果这是真的,则应将$annotation中第1列的值添加到$variants中的新列中 这就是我的示例输入文件的样子 $annotation表示以制表符分隔的文本文件 C0 C1 ... 5 ... 10 ... 100 ... 540 ... 990 这些值可能是重叠的,不能完全

这是对我的问题的描述:我有两个文本文件(这里是
$variants
$annotation
)。我想检查
$variants
中第2列的值是否位于
$annotation
中第2列和第3列的值之间。如果这是真的,则应将
$annotation
中第1列的值添加到
$variants
中的新列中

这就是我的示例输入文件的样子

$annotation
表示以制表符分隔的文本文件

C0    C1
...   5 
...   10
...   100
...   540
...   990
这些值可能是重叠的,不能完全排序,因为我正在处理一个圆形基因组

C0    C1    C2   
gene1 0     100
gene2 500   1000
gene3 980   1200
gene4 1500  5
$variants
表示以制表符分隔的文本文件

C0    C1
...   5 
...   10
...   100
...   540
...   990
输出应如下所示(
$variants
添加了两列)

这就是我的剧本目前的样子

my %hash1=();
while(<$annotation>){
    my @column = split(/\t/);  #split on tabs
    my $keyfield = $column[1] && $column[2]; # I need to remember values from two columns   here. How do I do that?
    }   

while(<$variants>){
    my @column=split(/\t/);  # split on tabs
    my $keyfield = $column[1];
    if ($hash1{$keyfield} >= # so the value in column[1] should be between the values from   column[1] & [2] in $annotation
        push # if true then add values from column[0] in $annotation to new column in $variants
    }
my%hash1=();
while(){
我的@column=split(/\t/)#在选项卡上拆分
我的$keyfield=$column[1]&&&$column[2];#我需要记住这里两列的值。我该怎么做?
}   
while(){
我的@column=split(/\t/)#在选项卡上拆分
my$keyfield=$column[1];
如果($hash1{$keyfield}>=#那么列[1]中的值应该介于$annotation中列[1]和[2]中的值之间
按#如果为true,则将$annotation中[0]列的值添加到$variants中的新列
}

因此,我最大的问题是如何使用散列来记住文件中的两个值,以及如何将一个文件中的值放到另一个文件中的列中。有人能帮我吗?

根本不需要散列。这个示例希望注释被排序,而不是重叠,它也只适用于打印来自变体的所有值d

#!/usr/bin/perl
use warnings;
use strict;

open my $VAR, '<', 'variants' or die $!;
<$VAR>; # skip header
my ($str, $pos) = split ' ', <$VAR>;

open my $ANN, '<', 'annotation' or die $!;
<$ANN>; # skip header

while (<$ANN>) {
    my ($gene, $from, $to) = split;
    while ($from <= $pos and $pos <= $to) {
        print "$str $pos $gene\n";
        ($str, $pos) = split ' ', <$VAR> or last;
    }
}
!/usr/bin/perl
使用警告;
严格使用;

打开我的$VAR,“如果输入文件不大且位置不太高,则可以使用数组表示所有位置:

#!/usr/bin/perl
use warnings;
use strict;

sub skip_header {
    my $FH = shift;
    <$FH>;
}


open my $ANN, '<', 'annotation' or die $!;

my $max = 0;
while (<$ANN>) {
    $_ > $max and $max = $_ for (split)[1, 2];
}
seek $ANN, 0, 0; # Rewind the file back.

my $circular;
my @genes;
while (<$ANN>) {
    my ($gene, $from, $to) = split;
    if ($from <= $to) {
        $genes[$_] .= "$gene " for $from .. $to;
    } else {
        $circular = 1;
        $genes[$_] .= "$gene " for 0 .. $to, $from .. $max + 1;
    }
}

chop @genes;

open my $VAR, '<', 'variants' or die $!;
skip_header($VAR);
while (<$VAR>) {
    next if /^\s*#/;
    chomp;
    my ($str, $pos) = split;
    $pos = $#genes if $circular and $pos > $#genes;
    print "$_ ", $genes[$pos] // q(), "\n";
}
!/usr/bin/perl
使用警告;
严格使用;
子跳转头{
我的$FH=班次;
;
}

打开我的$ANN,“绑定两个文件可能会起作用。@choroba你能再解释一下吗?@simbabque你能再解释一下吗?@user1987607:提供一个输入和输出示例。@choroba我添加了一个输入和输出示例output@choroba.这将不起作用,因为
$annotations
中的值重叠且不完美排序,这也是不可能的。我更改了输入和输出示例以更好地适应实际情况。您是否可以添加更多的
#
这是一个脚本,以提供更多信息,因为并非所有内容都清楚me@user1987607:它只是创建一个表示所有位置的数组。数组的索引对应于posi假设,该值包含该位置的所有基因。然后在给定位置搜索基因就相当容易了:它们直接存储在给定的索引中。子例程skip_头被设置为只跳过第一行,我想?我刚刚在我的数据上测试了这一点,肯定有一些错误,很多东西被分类到没错。我会尽力找出原因,然后再回来找你then@user1987607是的。原因:我很好奇。