2015-09-01 6 views
0

Я пытаюсь извлечь данные из файла, который выглядит следующим образом:Extract и сравнить многострочное значение

XLOC_000001 Schx 1 385 339.597 339.597 11.2848 - OK 
XLOC_000001 Schx 0 620 671.378 671.378 20.8907 - OK 
XLOC_000001 Schxdex 0 493 530.642 530.642 16.1373 - OK 
XLOC_000001 Schxdex 1 384 368.611 368.611 12.5572 - OK 
XLOC_000002 Schx 1 486 428.686 428.686 5.75646 - OK 
XLOC_000002 Schx 0 503 544.683 544.683 7.25738 - OK 
XLOC_000002 Schxdex 0 584 628.59 628.59 8.6694 - OK 
XLOC_000002 Schxdex 1 497 477.083 477.083 6.52573 - OK 
XLOC_000003 Schx 1 667 588.341 588.341 3.6527 - OK 
XLOC_000003 Schx 0 578 625.898 625.898 4.10985 - OK 
XLOC_000003 Schxdex 0 607 653.346 653.346 4.35889 - OK 
XLOC_000003 Schxdex 1 521 500.121 500.121 3.24867 - OK 
XLOC_000004 Schx 1 27 23.8159 23.8159 29.2102 - OK 
XLOC_000004 Schx 0 27 29.2374 29.2374 224.533 - OK 

Информация в первом столбце показана модель гена, а второй показывает группу лечения (либо Schx, либо Schxdex). В третьем столбце показан технический репликат для каждой группы лечения (0 или 1). Так, для первой модели гена:

model treatment rep value 
XLOC_000001 Schx 1 11.2848 
XLOC_000001 Schx 0 20.8907 
XLOC_000001 Schxdex 0 16.1373 
XLOC_000001 Schxdex 1 12.5572 

Я пытаюсь сделать сравнение между данными (значение я заинтересован в находится в колонке 7)

1) в пределах каждой группе лечения : 20.8907 Vs. 11.2848 и 16.1373 Vs. 12.5572

и

2) Между каждая группа лечения: 20.8907 Vs. 12.5572 и 11.2848 Vs. 16.1373

Я написал код, который позволяет мне выполнить корреляционный тест для первого сравнения, но я не могу решить, как сделать то же самое для второго. Я фильтрую значения ($fpkm == 0 и $fpkm > 5000), а затем преобразую их. тест, что я делаю не позволяет отсутствующих данных, так что если 0 или (> 5000) присутствует в одной точке сравнения, то вся модель снимается:

my %data; 
while (<$in>){ 
    chomp; 
    next unless /^XLOC/; 
    my @split = split; 
    $data{$split[0]}{$split[1]}{$split[2]} = $split[6]; 
} 

open my $out, '>', 'output.csv'; 

print $out "fpkm1,fpkm2\n"; 

my (%rep_count, $log_trans_fpkm, %filter, $fpkm); 

for my $xloc (sort keys %data){ 
    for my $condition (keys $data{$xloc}){ 
     for my $replicate (sort keys $data{$xloc}{$condition}){ 
      $fpkm = $data{$xloc}{$condition}{$replicate}; 

      next if $fpkm == 0; 
      $rep_count{$xloc}{$condition}++; 

      $filter{$xloc}{$condition}{$replicate} = $fpkm if $replicate == 0 and $rep_count{$xloc}{$condition} == 1 and $condition eq 'Schx'; 
      $filter{$xloc}{$condition}{$replicate} = $fpkm if $replicate == 1 and $rep_count{$xloc}{$condition} == 2 and $condition eq 'Schx'; 
     } 
     delete $filter{$xloc} if $fpkm == 0 or $fpkm > 5000; 
    } 
} 

for my $id (sort keys %filter){ 
    for my $condition (keys $filter{$id}){ 
     for my $replicate (sort keys $filter{$id}{$condition}){ 
      my $fpkm = log2($filter{$id}{$condition}{$replicate}); 
      print $out "$fpkm," if $replicate == 0 and $condition eq 'Schx'; 
      print $out "$fpkm" if $replicate == 1 and $condition eq 'Schx'; 
     } 
     print $out "\n"; 
    } 
} 

кто бы быть в состоянии помочь я извлекаю данные для второго сравнения?

Просто для уточнения данных, я хочу, чтобы извлечь в этом примере:

XLOC_000001 Schx 0 20.8907 
XLOC_000001 Schxdex 1 12.5572 
XLOC_000002 Schx 0 7.25738 
XLOC_000002 Schxdex 1 6.52573 
XLOC_000003 Schx 0 4.10985 
XLOC_000003 Schxdex 1 3.24867 

Чтобы быть отформатирован так:

20.8907 12.5572 
7.25738 6.52573 
4.10985 3.24867 
+1

Может быть, вы можете уточнить ваш вопрос с примером, или написать некоторый код макета. – TLP

+0

log2() в вашем примере кода не определен. – xxfelixxx

+0

@xxfelixxx - извините, если я не ввел его - это всего лишь небольшая часть, которая принимает log2 fpkm – Rizzle

ответ

1

Из Вашего вопроса, весьма неясно, что ваши критерии для выбора конкретного значения для включения в ваш экстракт. Это появляется, что вы хотите реплицировать 0, когда тип лечения - Schx, и копировать 1, когда тип лечения - Schxdex (из вашего примера вывода). Если есть какая-то другая логика, это неочевидно для меня.

немного Изменение вашего сценария:

#!/usr/bin/env perl 

my $input = 'input'; 
open my $in, "<", $input 
    or die "Unable to open '$input' : $!"; 

my %data; 
while (<$in>) { 
    chomp; 
    next unless /^XLOC/; 
    my @split = split; 
    #  model  treatment replicate  value 
    $data{ $split[0] }{ $split[1] }{ $split[2] } = $split[6]; 
} 

open my $out, '>', 'output.csv'; 

print $out "fpkm1 fpkm2\n"; 

my (%rep_count, $log_trans_fpkm, %filter, $fpkm); 

for my $xloc (sort keys %data) { 

    my ($schx, $schxdex); 
    for my $treatment (keys $data{$xloc}) { 
     if ('Schx' eq $treatment) { 
      $schx = $data{$xloc}{$treatment}{ 0 }; 
     } elsif ('Schxdex' eq $treatment) { 
      $schxdex = $data{$xloc}{$treatment}{ 1 }; 
     } else { 
      die "Don't know what to do with treatment '$treatment'"; 
     } 
    } 
    my (@fpkm_ok) = grep { defined $_ and $_ != 0 and $_ <= 5000 } ($schx, $schxdex); 
    if (2 == scalar @fpkm_ok) { 
     print $out join ' ', (@fpkm_ok, "\n"); 
    } 
} 

Выхода

fpkm1 fpkm2 
20.8907 12.5572 
7.25738 6.52573 
4.10985 3.24867 
+0

Это точно отвечает на мой вопрос. Я не использовал grep в perl много, но это действительно приятное решение, поэтому спасибо! – Rizzle