Всего один столбец файла, сгруппированный по двум другим столбцам - PullRequest
0 голосов
/ 27 апреля 2018

Я хочу суммировать строки на основе аналогичной строки перед первым знаком "-". Я пробовал R, но файл слишком большой.

в

URS0000001D42-antisense_ATTTCGGTTGGGGAA 208
URS0000001D42-antisense_CATGCTCATAAGGAA 24
URS0000003804-lncRNA_GAGATCCTGGGTTTT    6
URS0000003CBA-antisense_CTGGGCTAGTGAACGCGGCGAAGT        14
URS0000003F61-antisense_AAAGTGCACTTGGACG        55
URS0000003F61-antisense_AAAGTGCACTTGGACGAA      4

из

URS0000001D42-antisense 232
URS0000003804-lncRNA 6
URS0000003CBA-antisense 14
URS0000003F61-antisense 59

Ответы [ 3 ]

0 голосов
/ 27 апреля 2018

Использование хеша perl:

Сценарий:

#!/usr/bin/env perl

while (my ($key, $value) = <> =~ /^(.+)_.+\s+(\d+)/) {
  $hash{$key} += $value;
}

while(my($k, $v) = each %hash) { 
  print "$k\t$v\n";
}

Называя это:

$ script.pl < file
URS0000003CBA-antisense:  14
URS0000003F61-antisense:  59
URS0000003804-lncRNA:  6
URS0000001D42-antisense:  232
$

Возможно, это можно сделать и короче. ; -)

И вот еще один вопрос для очень похожей задачи с множеством ответов.

0 голосов
/ 27 апреля 2018

Вот решение Perl

use strict;
use warnings 'all';

my %data;

while ( <DATA> ) {
    my ( $f1, $f2, $seq, $n ) = m/[^-_\s]+/g;
    $data{$f1}{$f2} += $fields[3];
}

for my $f1 ( keys %data ) {

    for my $f2 ( keys %{ $data{$f1} } ) {
        printf "%s-%s %d\n", $f1, $f2, $data{$f1}{$f2};
    }
}

__DATA__
URS0000001D42-antisense_ATTTCGGTTGGGGAA 208
URS0000001D42-antisense_CATGCTCATAAGGAA 24
URS0000003804-lncRNA_GAGATCCTGGGTTTT    6
URS0000003CBA-antisense_CTGGGCTAGTGAACGCGGCGAAGT        14
URS0000003F61-antisense_AAAGTGCACTTGGACG        55
URS0000003F61-antisense_AAAGTGCACTTGGACGAA      4

выход

URS0000003CBA-antisense 14
URS0000001D42-antisense 232
URS0000003804-lncRNA 6
URS0000003F61-antisense 59

Вывод неупорядочен, поскольку хеши Perl не имеют собственного порядка. Немного сложнее сохранить выходные данные в том же порядке, что и входные данные, так как необходимо хранить массив для каждого хэша, который отслеживает порядок создания ключей

use strict;
use warnings 'all';

my ( %data, @keys );

while ( <DATA> ) {

    my ( $f1, $f2, $seq, $n ) =/ [^-_\s]+/g;

    push @keys, $f1 unless $data{$f1};

    my $h2 = $data{$f1} //= {};

    push @{ $h2->{''} }, $f2 unless $h2->{$f2};

    $h2->{$f2} += $n;
}

for my $f1 ( @keys ) {

    for my $f2 ( @{ $data{$f1}{''} } ) {
        printf "%s-%s %d\n", $f1, $f2, $data{$f1}{$f2};
    }
}

__DATA__
URS0000001D42-antisense_ATTTCGGTTGGGGAA 208
URS0000001D42-antisense_CATGCTCATAAGGAA 24
URS0000003804-lncRNA_GAGATCCTGGGTTTT    6
URS0000003CBA-antisense_CTGGGCTAGTGAACGCGGCGAAGT        14
URS0000003F61-antisense_AAAGTGCACTTGGACG        55
URS0000003F61-antisense_AAAGTGCACTTGGACGAA      4

выход

URS0000001D42-antisense 232
URS0000003804-lncRNA 6
URS0000003CBA-antisense 14
URS0000003F61-antisense 59
0 голосов
/ 27 апреля 2018

Использование awk:

awk '{a[$1]+=$NF}END{for (i in a){print i,a[i]}}' FS='_| ' file

Результат

URS0000003804-lncRNA 6
URS0000001D42-antisense 232
URS0000003CBA-antisense 14
URS0000003F61-antisense 59
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...