0

我有以下数据:

eya XLOC_000445_Change:10.3_q:0.003 atonal1
six XLOC_00099_Change:70.0_q:0.095  atonal1
six-eya XLOC_0234324_Change:19.8_q:0.05 atonal1
eya XLOC_00010_Change:6.5_q:0.22    c-myc
six XLOC_025437_Change:1.1_q:0.018  c-myc
six-eya XLOC_001045_Change:2.3_q:0.0001 c-myc
eya XLOC_000115_Change:7.3_q:0.03   ezrin
six XLOC_000001_Change:7.9_q:0.00006    ezrin
six-eya XLOC_0234322_Change:9.0_q:0.0225    ezrin
six-eya XLOC_091345_Change:9.3_q:0.005  slc12a2
eya XLOC_000445_Change:9.9_q:0.3    atonal1
six XLOC_00099_Change:7.0_q:0.95    atonal1
six-eya XLOC_0234324_Change:9.8_q:0.5   atonal1

并尝试按如下方式构建 HoHoA:

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

方法 1:将数组值推送到 HoH:

while (<$input>) { 
    chomp;
    push @xloc, $1 if ($_ =~ /(XLOC_\d+)/);
    push @change_val, $1 if ($_ =~ /Change:(-?\d+\.\d+|-?inf)/);
    push @q_value, $1 if ($_ =~ /q:(\d+\.\d+)/);
    my @split = split('\t');            
    push @condition, $split[0];
    push @gene, $split[2];
}           
push @{ $experiment{$gene[$_]}{$condition[$_]} }, [ $xloc[$_], $change_val[$_], $q_value[$_] ] for 0 .. $#change_val;

方法 2:动态为 HoHoA 赋值:

while (<$input>) { 
    chomp;
    my $xloc = $1 if ($_ =~ /(XLOC_\d+)/);
    my $change = $1 if ($_ =~ /Change:(-?\d+\.\d+|-?inf)/);
    my $q_value = $1 if ($_ =~ /q:(\d+\.\d+)/);
    my @split = split('\t');
    my $condition = $split[0];
    my $gene = $split[2];
    $experiment{$gene}{$condition} = [ $xloc, $change, $q_value ];
}

两者都工作正常 - 只要我得到我想要的数据结构。然而,只有第一种方法(推)确保作为重复存在的基因(在这种情况下atonal1)在 HoHoA 中被表示两次。

我的下游代码最初是为了处理以第二种方式构建的 HoHoA,我终生无法弄清楚为什么两种方法在以下代码中的处理方式不同:

下游代码:

my (%change, %seen, $xloc, $change_val, $q_value);
for my $gene (sort keys %experiment) {
     for my $condition (sort keys %{$experiment{$gene}}) {
         $seen{$gene}++; # Counts for each occurrence of gene 
         if ( (not exists $change{$gene}) || (abs $change{$gene} < abs $experiment{$gene}{$condition}[1]) ) { # Has a larger change value
             $change{$gene} = $experiment{$gene}{$condition}[1];
         }               
    }
}
print Dumper \%change;

当我以任何一种方法运行上述代码时,我得到:

方法 1的输出:

$VAR1 = {
          'atonal1' => [
                         'XLOC_0234324',
                         '9.8',
                         '0.5'
                       ],
          'c-myc' => undef,
          'ezrin' => undef,
          'slc12a2' => undef,
        };

方法 2的输出:

$VAR1 = {
          'atonal1' => '9.9', # i.e. the largest change value for each condition/gene
          'c-myc' => '6.5',
          'ezrin' => '9.0',
          'slc12a2' => '9.3',
        };

我想要的是:

$VAR1 = {
          'atonal1' => [
                          '9.9',
                          '70.0' # This is the difference - i.e the both values are added to the hash `%change`
                       ], 
          'c-myc' => '6.5',
          'ezrin' => '9.0',
          'slc12a2' => '9.3',
        };

我不知道是什么造成了差异

更新

%experiment在使用方法 1推送值之后,我将发布 Dumper 输出:

$VAR1 = {
          'atonal1' => {
                         'eya' => [
                                    [
                                      'XLOC_000445',
                                      '10.3',
                                      '0.003'
                                    ],
                                    [
                                      'XLOC_000445',
                                      '9.9',
                                      '0.3'
                                    ]
                                  ],
                         'six' => [
                                    [
                                      'XLOC_00099',
                                      '70.0',
                                      '0.095'
                                    ],
                                    [
                                      'XLOC_00099',
                                      '7.0',
                                      '0.95'
                                    ]
                                  ],
                         'six-eya' => [
                                        [
                                          'XLOC_0234324',
                                          '19.8',
                                          '0.05'
                                        ],
                                        [
                                          'XLOC_0234324',
                                          '9.8',
                                          '0.5'
                                        ]
                                      ]
                       },
          'c-myc' => {
                       'eya' => [
                                  [
                                    'XLOC_00010',
                                    '6.5',
                                    '0.22'
                                  ]
                                ],
                       'six' => [
                                  [
                                    'XLOC_025437',
                                    '1.1',
                                    '0.018'
                                  ]
                                ],
                       'six-eya' => [
                                      [
                                        'XLOC_001045',
                                        '2.3',
                                        '0.0001'
                                      ]
                                    ]
                     },

          'ezrin' => {
                       'eya' => [
                                  [
                                    'XLOC_000115',
                                    '7.3',
                                    '0.03'
                                  ]
                                ],
                       'six' => [
                                  [
                                    'XLOC_000001',
                                    '7.9',
                                    '0.00006'
                                  ]
                                ],
                       'six-eya' => [
                                      [
                                        'XLOC_0234322',
                                        '9.0',
                                        '0.0225'
                                      ]
                                    ]
                     },
          'slc12a2' => {
                         'six-eya' => [
                                        [
                                          'XLOC_091345',
                                          '9.3',
                                          '0.005'
                                        ]
                                      ]
                       },

        };
4

1 回答 1

4

让我们把你的数据重新格式化一下。我并不是说这是您格式化数据所需的方式。我这样做是为了更好地理解它所代表的含义:

GENE      XLOC                  CHANGE   Q VALUE   CONDITION
========  ====================  =======  ========  ==========
eya       XLOC_000445_Change:   10.3_q:  0.003     atonal1
six       XLOC_00099_Change:    70.0_q:  0.095     atonal1
six-eya   XLOC_0234324_Change:  19.8_q:  0.05      atonal1
eya       XLOC_00010_Change:    6.5_q:   0.22      c-myc
six       XLOC_025437_Change:   1.1_q:   0.018     c-myc
six-eya   XLOC_001045_Change:   2.3_q:   0.0001    c-myc
eya       XLOC_000115_Change:   7.3_q:   0.03      ezrin
six       XLOC_000001_Change:   7.9_q:   0.00006   ezrin
six-eya   XLOC_0234322_Change:  9.0_q:   0.0225    ezrin
six-eya   XLOC_091345_Change:   9.3_q:   0.005     slc12a2
eya       XLOC_000445_Change:   9.9_q:   0.3       atonal1
six       XLOC_00099_Change:    7.0_q:   0.95      atonal1
six-eya   XLOC_0234324_Change:  9.8_q:   0.5       atonal1

我的列假设是否正确?

首先,我建议您使用split拆分值而不是正则表达式。逐行执行此操作。Perl 在优化方面非常有效。90% 的编程是调试和支持你的程序。试图通过将多个步骤压缩成一个步骤来提高效率只会让事情变得更难理解,而优化中返回的价值很少。

让我们把每一行都分解一下:

while ( my $line = <$input> ) {
    chomp $line;
    my ( $gene, $more_data, $condition ) = split /\s+/, $line;

在此刻:

$gene = 'eye'
$more_data = 'XLOC_000445_Change:10.3_q:0.003';
$condition = 'atonal1`    # I'm not sure what this is...

现在,我们可以拆分$more_data

my ( $xloc, $change, $q_value ) = split /:/, $more_data;
$xloc =~ s/^XLOC_//;
$change =~ s/_q$//;

现在我们有:

$xloc = '000445';
$change = '10.3';
$q_value = '0.003';

这更有意义吗?

您的问题之一是您试图将数据存储在一个非常非常复杂的结构中,而没有真正考虑该数据代表什么。

假设您的数据是这样的:

  • 一个基因可能包含多个条件
  • 每个基因条件组合都可以有一个结果
  • 此结果包含xlocq_valuechange

这意味着您的数据应如下所示:

$experiment{$gene}->{$condition}->{XLOC}    = $xloc;
$experiment{$gene}->{$condition}->{Q_VALUE} = $q_value;
$experiment{$gene}->{$condition}->{CHANGE}  = $change;

但是,我在您的列表中看到了 gene = eya, condition =atonal1两次。也许您需要更多类似的东西:

  • 一个基因可能包含多个条件
  • 每个基因条件组合可以有多个结果
  • 每个结果都包含一个xlocq_valuechange

如果是这种情况,您的数据结构应该如下所示:

$experment{$gene}->{$condition}->[0]->{XLOC}    = $xloc;
$experment{$gene}->{$condition}->[0]->{Q_VALUE} = $q_value;
$experment{$gene}->{$condition}->[0]->{CHANGE}  = $change;

这不是答案。我只是想了解您的数据是什么以及您要在该数据中存储什么。一旦我们解决了这个问题,我就可以帮助您完成其余的程序。

让我知道我对您的数据所代表的理解是否准确。对此答案添加评论,并稍微更新您的问题。

一旦我知道我走在正确的轨道上,我将向您展示如何更轻松地管理此结构并跟踪其中的所有内容。

现在我知道我走在了正确的轨道上,解决方案相当简单:面向对象编程!

让我解释一下:每个实验都由一对基因条件组成。这就是我的实验重点。

Local::Condition为这些基因条件对中的每一个创建一个。在这里面我存储了我的结果数组。

我的结果包含三个项目。


看:答案!

我决定做的是创建一个结果对象。该对象包含该结果的 XLoc、Change 和 Q 值。通过将我的结果打包到一个对象中,我在尝试跟踪它时遇到的问题更少。

所以我们拥有的是:

  • 我们有实验
  • 每个 _experiment 都包含一个基因/条件对,我们将其作为实验的关键。
  • 每个基因/条件实验都包含一系列结果。

现在,跟踪正在发生的事情要容易得多。对于每一行,我创建一种Local::Result对象,其中包含该基因/条件对的结果集。

所以,我所要做的就是将我的结果推送到代表我的结果集的基因/条件数组上

#
# Create a Result for this experiment
#

my $result = Local::Result->new( $xloc, $change, $q_value );

#
# Push this result onto your $gene/condition experiment
#
push @{ $experiments{$gene}->{$condition} }, $result;

请注意,我在这里的语法非常清楚。我有一个%experimentsGenes键入的散列。每个基因都包含该基因的条件。这个基因/条件对是一个结果数组。

面向对象的语法使用起来可能有点复杂,但是 Perl 文档中有一个很好的教程。通过使用面向对象的编程,您可以将必须​​跟踪的细节组合在一起。

#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
use autodie;
use Data::Dumper;

my %experiments;

while ( my $line = <DATA> ) {
    my ($condition, $more_data, $gene) = split /\s+/, $line;

    my ($xloc, $change, $q_value) = split /:/, $more_data;
    $xloc   =~ s/^XLOC_(.*)_Change/$1/;
    $change =~ s/_q$//;

    my $result = Local::Result->new( $xloc, $change, $q_value );
    push @{ $experiments{$gene}->{$condition} }, $result;
}

printf "%-10.10s  %-10.10s  %10.10s  %-4s  %-7s\n\n",
    "Gene", "Condition", "XLoc", "Chng", "Q Value";
for my $gene ( sort keys %experiments ) {
    for my $condition ( sort keys %{ $experiments{$gene} } ) {
        for my $result ( @{ $experiments{$gene}->{$condition} } ) {
            printf "%-10.10s  %-10.10s  %10.10s  %-4.1f  %-7.1f\n",
                $gene, $condition, $result->xloc, $result->change, $result->q_value;
        }
    }
}

package Local::Result;

sub new {
    my $class       = shift;
    my $xloc        = shift;
    my $change      = shift;
    my $q_value     = shift;

    my $self        = {};
    bless $self, $class;

    $self->xloc($xloc);
    $self->change($change);
    $self->q_value($q_value);

    return $self;
}

sub xloc {
    my $self        = shift;
    my $xloc        = shift;

    if ( defined $xloc ) {
        $self->{XLOC} = $xloc;
    }
    return $self->{XLOC};
}

sub change {
    my $self        = shift;
    my $change      = shift;

    if ( defined $change ) {
        $self->{CHANGE} = $change;
    }
    return $self->{CHANGE};
}

sub q_value {
    my $self        = shift;
    my $q_value     = shift;

    if ( defined $q_value ) {
        $self->{Q_VALUE} = $q_value;
    }
    return $self->{Q_VALUE};
}

package main;


__DATA__
eya XLOC_000445_Change:10.3_q:0.003 atonal1
six XLOC_00099_Change:70.0_q:0.095  atonal1
six-eya XLOC_0234324_Change:19.8_q:0.05 atonal1
eya XLOC_00010_Change:6.5_q:0.22    c-myc
six XLOC_025437_Change:1.1_q:0.018  c-myc
six-eya XLOC_001045_Change:2.3_q:0.0001 c-myc
eya XLOC_000115_Change:7.3_q:0.03   ezrin
six XLOC_000001_Change:7.9_q:0.00006    ezrin
six-eya XLOC_0234322_Change:9.0_q:0.0225    ezrin
six-eya XLOC_091345_Change:9.3_q:0.005  slc12a2
eya XLOC_000445_Change:9.9_q:0.3    atonal1
six XLOC_00099_Change:7.0_q:0.95    atonal1
six-eya XLOC_0234324_Change:9.8_q:0.5   atonal1
于 2013-10-07T15:44:54.873 回答