1

プロジェクトの 1 点で立ち往生しています。私は生物医学です。だから、私はperlプログラミングをあまり知りません。タンパク質とリガンドの相互作用を説明するファイルがあります。ファイルは次のようになります。

H P L A    82 SER  1290  N   -->  O12  1668 GSH   106 A  2.90
H P L A    83 SER  1301  N   -->  O12  1668 GSH   106 A  2.93
N P L A    19 LYS   302  NZ  ---  O31  1682 GSH   106 A  3.86
N P L A    22 CYS   348  CB  ---  CB2  1677 GSH   106 A  3.75
N P L A    22 CYS   348  CB  ---  SG2  1678 GSH   106 A  3.02
N P L A    22 CYS   349  SG  ---  CB2  1677 GSH   106 A  3.03
N P L A    22 CYS   349  SG  ---  SG2  1678 GSH   106 A  2.02
N P L A    24 TYR   372  CB  ---  CG1  1670 GSH   106 A  3.68

これで、O12が 2 行で表示されます。同様に、 CB2も 2 つあることがわかります。これらの O12 と CB2 は原子記号です。O12は、原子中の12個の酸素を意味します。次に、ファイル内に異なる原子記号がいくつあるかを計算する必要があります。そのためには、perl スクリプトを使用する必要があります。perlを使用してこのファイルを1行ずつ読んでいます。 while (my $line = <MYFILE>) { };ここで、ファイルを 1 行ずつ読み取りながら、異なる原子記号がいくつあるかを計算する必要があります。私の問題を説明するのに十分明確であることを願っています。優しい返事待ってます…

4

4 に答える 4

1

問題の最適な解決方法は、データがどのように区切られているかによって異なります。固定幅のように見えるので、最初にその解決策を提示します。

use strict;
use warnings;

my %atom;
while (<DATA>) {
    my (undef,$atom) = unpack "A34A4 ", $_;
    $atom{$atom}++;
}

print scalar keys %atom;

__DATA__
H P L A    82 SER  1290  N   -->  O12  1668 GSH   106 A  2.90
H P L A    83 SER  1301  N   -->  O12  1668 GSH   106 A  2.93
N P L A    19 LYS   302  NZ  ---  O31  1682 GSH   106 A  3.86
N P L A    22 CYS   348  CB  ---  CB2  1677 GSH   106 A  3.75
N P L A    22 CYS   348  CB  ---  SG2  1678 GSH   106 A  3.02
N P L A    22 CYS   349  SG  ---  CB2  1677 GSH   106 A  3.03
N P L A    22 CYS   349  SG  ---  SG2  1678 GSH   106 A  2.02
N P L A    24 TYR   372  CB  ---  CG1  1670 GSH   106 A  3.68

ここで、 で使用されるオフセットを推定したことに注意してunpackください。そのため、データに合わせて微調整する必要がある場合があります。

データがタブ区切りの場合は、タブで分割するかText::CSV、データを解析するために使用することをお勧めします。基本的なスクリプトは同じです:

use Text::CSV;

my $csv = Text::CSV->new({
        binary => 1,
        sep_char => "\t",
    });
my %atom;
while (<DATA>) {
    $csv->parse($_);
    my $atom = ($csv->fields())[9];
    next unless defined $atom;
    $atom{$atom}++;
}

while (my $aref = $csv->getline(*DATA))より効率的なloop condition を使用することもできますが、csv データに一貫性がない場合は中断します。

より単純で、おそらく有効な (データの複雑さに応じて) ソリューションは、次を使用していsplitます。

while (<DATA>) {
    my $atom = (split /\t/)[9];  # implicitly splits $_
    $atom{$atom}++;
}

データがスペースで区切られている場合は、単純/\t/に上記から削除してください。

すべてのスペースが入力のタブであると想定したことに注意してください。そうでない場合は、カウントを微調整する必要があるかもしれません。

于 2012-05-14T12:29:38.553 に答える
0

この Perl クックブックのレシピをご覧ください。

ファイルを 1 行ずつ読み込んでいるときに、アトム シンボルを分割/抽出し、それらをハッシュでカウントします。

use strict;
use warnings;
# open FILE goes here...
my %seen; # we use this to count
while (<FILE>) {
  m/--[>-]\s+(\w+)\s/; # fetch the atom symbol after arrow-thing
  $seen{$1}++;
}
close FILE;
print scalar keys %seen; # number of unique atom symbols
print join ', ', keys %seen; # List as string
于 2012-05-14T12:15:14.533 に答える
0

コマンドライン (perl なし):

cat yourfile | awk '{print $10}' | sort | uniq | wc -l

あなたの入力で動作します。

于 2012-05-14T12:07:22.230 に答える
-1

またはperlで:

#!/usr/bin/perl

while(my $line = <DATA>){
  my $atom = (split / +/, $line)[9];

  $atoms{$atom}++;
}

print "$_: $atoms{$_}\n" for keys %atoms;

__DATA__
H P L A    82 SER  1290  N   -->  O12  1668 GSH   106 A  2.90
H P L A    83 SER  1301  N   -->  O12  1668 GSH   106 A  2.93
N P L A    19 LYS   302  NZ  ---  O31  1682 GSH   106 A  3.86
N P L A    22 CYS   348  CB  ---  CB2  1677 GSH   106 A  3.75
N P L A    22 CYS   348  CB  ---  SG2  1678 GSH   106 A  3.02
N P L A    22 CYS   349  SG  ---  CB2  1677 GSH   106 A  3.03
N P L A    22 CYS   349  SG  ---  SG2  1678 GSH   106 A  2.02
N P L A    24 TYR   372  CB  ---  CG1  1670 GSH   106 A  3.68
于 2012-05-14T12:14:52.690 に答える