我正在编写一个使用文本文件的脚本,其中一列中可以有两个字母(A,B,C或D),并以“,”分隔。此列也可以只包含这些字母之一。在脚本的其余部分中,我必须将两个字母都用于进一步的计算。这是我的输入文件(此处为$variants)的简化示例:

C1    C2    C3   C4   C5  C6 ... C9
text   2    A    D    values and text in the other columns
text   4    B    C    values and text in the other columns
text   5    A    B,D  values and text in the other columns


因此,在C4的第3行中有一个B和D。在C4之后,还有许多列,由于我在脚本的其他部分中需要它们,因此无法更改这些列。

我有第二个输入文件,根据C3和C4中存在的字母从中提取一些值。这是第二个输入文件的外观(此处为$frequency

C1    C2    A  a   B   b   C   c   D   d
text   1    0  1   0   0   0   0   0   0
text   2    1  0   5   4   0   0   0   0
text   3    0  0   0   0   10  11  3   6
text   4    1  0   9   4   0   2   0   0
text   5    5  3   0   0   6   7   4   0


这是我的输出应如下所示:

C1    C2    C3    C4    C5   C6   C7   C8  C9  C10
text  2     A     D     1    0    0    0   empty
text  4     B     C     9    4    0    2   empty
text  5     A     B,D   5    3    0    0    4   0


因此,对于第1行,C3中有A,然后脚本从$frequency中提取A和a的值,并将它们放在C5和C6中。然后,将C4中的值从输出文件中放入C7和C8中。现在在第三行中,C4中有B,D。因此,脚本现在需要做的是将C和C8中B和b的对应值以及C9和C10中D和d的值放入。

我的脚本中唯一仍然有问题的就是在有','的情况下拆分此C4。其余的工作。

这就是我脚本中有问题的部分的样子

while(<$variants>){
    next if /^\s*#/;
    next if /^\s*"/;
    chomp;
    my ($chr, $pos, $refall, @altall) = split /\t/; # How should I specify here the C4, as an array? So that I don't know
    my @ref_data = @{$frequency_data[$pos]}{$refall, lc($refall)};
    my @alt_data = @{$frequency_data[$pos]}{$altall, lc($altall)}; # this works for C3 ($refall), but not for C4 when there are two letters
    $pos = $#genes if $circular and $pos > $#genes; # adding annotation # this can be ignored here, since this line isn't part of my question
    print join("\t","$_ ", $genes[$pos] // q(), @ref_data, @alt_data), "\n"; # printing annotation
}


因此有人可以帮助我将C4除以',并仍然使用该信息从$variants中提取值

最佳答案

我认为最简单的方法是将第3列和第4列视为一开始的列表:

while(<$variants>){
    next if /^\s*#/;
    next if /^\s*"/;
    chomp;
    my ($chr, $pos, $refall_string, $altall_string, @other) = split /\t/;
    my @refall = split(",", $refall_string);
    my @altall = split(",", $altall_string);

    my @ref_data_all = (); # Treat C3 as array just in case...
    foreach my $refall (@refall) {
        push @ref_data_all, @{$frequency_data[$pos]}{ $refall, lc($refall) };
    }
    my @alt_data_all = ();
    foreach my $altall (@altall) {
        push @alt_data_all, @{$frequency_data[$pos]}{ $altall, lc($altall) };
    }

    $pos = $#genes if $circular and $pos > $#genes;
    print join("\t","$_ ", $genes[$pos] // q(),
               @ref_data_all, @alt_data_all), "\n";
}


我没有对此进行测试,但是即使存在一些小错误,该方法也应该清晰。

关于perl - 用“,”分隔一列,然后在计算中使用这些值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18533005/

10-13 02:12