0
この投稿は、DVK によるコメントと回答に基づいて更新されました。

オープンの 3 引数形式を使用するように変更し、ID を配列に正しくプッシュしました

以下の更新されたコード

use warnings;
use strict;
use Data::Dumper;


my $file1 = "Inputfile.txt";
my $file2 = $ARGV[0];
my $file3 = $ARGV[1];

open (OF, " > Results.txt") or die "Can't write new file: $!";

my %hash;
open(INPUT1, "<" , $file1)or die("Failed to open file1: $!");
while (!eof(INPUT1)) {
    my @elements = split(/\t/, <INPUT1>);
    my $F1catagory = $elements[2];
    my $F1IDs = $elements[3];
    push @{$hash{$F1catagory}}, $F1IDs;
}
close(INPUT1);

my @array1;
open(INPUT2, "<" , $file2) or die ("Failed to open file2: $!");
while (!eof(INPUT2)) {
    my @line = split(/\t/, <INPUT2>);
    my $F2catagory = $line [0];
    my $F2IDs    = $line [1];
    push (@array1, $F2IDs);
}
print OF @array1;
close(INPUT2);

my @array2;
open(INPUT3, "<" , $file3) or die ("Failed to open file3: $!");
while (!eof(INPUT3)) {
    my @lines = split(/\t/, <INPUT3>);
    my $F3catagory     = $lines [0];
    my $F3IDs = $lines [1];
    push (@array2, $F3IDs );


}
print OF @array2;
close(INPUT3);

入力データは次のようになります

以下

ファイル 1 にはプロセスに関する情報が含まれています。以下のように、3 列目にプロセス ID が含まれ、4 列目にアイテム ID が含まれています (これらは %hash の作成に使用されます)。

process 9606    0051712 3458    [25 Jul 2011]
process 9606    0051712 2208    [25 Jul 2011]
process 9606    0051712 2150    [25 Jul 2011]
process 9606    0051712 4843    [25 Jul 2011]
process 9606    0032513 2280    [25 Jul 2011]
process 9606    0032513 2281    [25 Jul 2011]
process 9606    0006285 23583   [25 Jul 2011]
process 9606    0006285 6996    [25 Jul 2011]
process 9606    0006285 4913    [25 Jul 2011]
process 9606    0006285 10309   [25 Jul 2011]
process 9606    0006285 4350    [25 Jul 2011]
process 9606    0006285 4968    [25 Jul 2011]
process 9606    0006285 4595    [25 Jul 2011]
process 9606    0006285 8930    [25 Jul 2011]
process 9606    0051503 284439  [25 Jul 2011]
process 9606    0051503 2697    [25 Jul 2011]
process 9606    0051503 291 [25 Jul 2011]
process 9606    0051503 10478   [25 Jul 2011]

file2 には、列 1 にアイテムのカテゴリ、列 2 にアイテム ID が含まれています。

CS1G2   1455
TM65    157378
PFN1    5216
HUL1    11100
ERI3    79033
PR12    57479
HIFN    55662
HNPD    3184
 HI2    28996
 LD1    84316
GRB2    2885
 AL6    84964
PCM1    5108
 ZN7    126208
MAK2    5605
BCL3    602

ファイル 3 は、アイテム ID が異なることを除いて、ファイル 2 と同じです。

ファイル 1 のプロセスにファイル 2 とファイル 3 の両方のアイテムが含まれているかどうかを確認する必要があります。

これで質問がより明確になることを願っています

######元の質問

書こうとしているスクリプトで問題が発生しています

プロセス情報を含むファイルがあります。プロセス ID とアイテム ID を、プロセス ID をキーとして、アイテム ID を値として配列のハッシュに読み込みました (単一プロセス内の複数のアイテムとしての配列のハッシュ)。

アイテム ID @F2IDs と @F3IDs の 2 つの配列があります。

@F2IDs と @F3IDs の両方に同じプロセス (%hash の同じ値) にあるアイテム ID がある場合、同じプロセスにあることを識別したい

私はこれまでこのコードを持っています

use warnings;
use strict;
use Data::Dumper;

my $file1 = "Infile.txt";
my $file2 = $ARGV[0];
my $file3 = $ARGV[1];

open (OF, " > Results.txt") or die "Can't write new file: $!";


my %hash;
open(INPUT, $file1)or die("Failed to open file2");
while (!eof(INPUT)) {
    my @elements = split(/\t/, <INPUT>);
    my $F1catagory = $elements[2];
    my $F1IDs = $elements[3];
    push @{$hash{$catagory}}, $F1IDs;
}
close(INPUT);

open(INPUT, $file2) or die "Can't write new file: $!";
while (!eof(INPUT)) {
    my @line = split(/\t/, <INPUT>);
    my $F2catagory = $line [0];
    my @F2IDs    = $line [1];
}
close(INPUT);

open(INPUT, $file3) or die "Can't write new file: $!";
while (!eof(INPUT)) {
    my @lines = split(/\t/, <INPUT>);
    my @F3catagory     = $lines [0];
    my @F3IDs = $lines [1];
}
close(INPUT);    

以下の疑似コードのようなことをする必要がありますが、Python にあるような "if in" 構造が perl にあるかどうかわかりません。

$insameprocess = False;
foreach value in %hash;
    if F2IDs and F3IDs are in {$hash{$catagory}};;
       $insameprocess = True;
       print OF "the key the value and if they are in the same process";

perlでこれを行う方法について何かアイデアを持っている人はいますか?

よろしくお願いします。

S

4

1 に答える 1

0

3 つの問題があります。

  1. 一般に、スクリプトにはデータの読み取りに関する多くのバグが含まれているようです。それはあなたが尋ねたものではないので、今はカバーしません。たとえば、配列に割り当てるのではなく、ループ 2/3 で ID を配列にプッシュする必要があります (最初のループで正しく行います)。

  2. あなたの主な技術的な質問は、「ハッシュ値 (配列参照) に ID があるかどうかを確認する方法」のようです。

    ID の arrayref ではなく、ID の hashref (「1」にマップ) にデータを格納し、ハッシュ ルックアップを使用するのが最善の方法です。

    # This is in your first loop reading file 1
    # OLD CODE:    push @{$hash{$catagory}}, $F1IDs;
    # NEW CODE:
    # # Each hash value is a hashref, with keys being IDsx and values simply 1
    $hash{$catagory}->{$F1IDs} = 1; 
    
    # This is the code in the end, to check if some ID is in the hash:
    if ($hash{$catagory}->{$F1IDs}) {
        # $id_is_in_hash = 1;
    }
    
  3. 率直に言って、あなたの疑似コードは私 (あなたの説明も) にはあまり意味がありません。そのため、箇条書き 2 のソリューションを使用して疑似コードを置き換える完全なチェックを作成することはできません。より明確な説明を提供するか、3 つのファイルと必要な出力のサンプル データを提供していただければ、さらに多くのことを行うことができます。

于 2013-03-27T13:31:58.353 に答える