2016-06-29 6 views
2

私はタブ区切りファイルを解析しています。いくつかの列は、明らかに数字であるにもかかわらず、数字として認識されていません。これらの値を合計しようとすると、エラーが表示されます。とPerlは0を返します。文字列を数値に変換しています "引数は数値エラーではありません"

私はScalar::Util qw(looks_like_number);を使用しようとしましたが、同じ結果が「0」でした。私が試すことができる何か他にありますか?

がここにコードされています(また)、余分な引用符を処理するText::CSVを使用する

open my $out_fh, '>', $final_variants or die qq{Unable to open "$final_variants" for output: $!}; 

open my $in_fh, '<', $tsv_file_new 
      or die qq{Unable to open "$tsv_file_new" for input: $!}; 

while (<$in_fh>) { 

     my @fields = split; 

     my $forward_reference = $fields[67]; 
     my $reverse_reference = $fields[68]; 
     my $forward_variant_reads = $fields[77]; 
     my $reverse_variant_reads = $fields[78]; 

     my $total_reads = (looks_like_number($forward_reference)) 
       + (looks_like_number($reverse_reference)) 
       + (looks_like_number($forward_variant_reads)) 
       + (looks_like_number($reverse_variant_reads)); 

     my $current_final_line = $headerline . "\t" 
        . $forward_reference . "\t" 
        . $reverse_reference . "\t" 
        . $forward_variant_reads . "\t" 
        . $reverse_variant_reads . "\t" 
        . $total_reads . "\t"; 

     print $out_fh $current_final_line, "\n"; 
} 
+4

は ' "97"' '確か97'とは異なり、多数のようにしていません。あなたのフィールドに引用符があるように聞こえます。 – melpomene

答えて

6

あなたのエラーメッセージはすでにそれを言う:引数 "" 97 ""数値ではありません。

my $num = '"42"'; 
my $sum = $num + 1; 

これが与える:

引数 "" 42 "" ではありませんがが実際に引用符(")に囲まれている文字列、そのようなある場合に発生しますさらに(+)で数値...

あなた番号からの引用符を取り除くようにしてください:

$num =~ s/"//g; 
+1

代替パターンとして、数値コンポーネントをマッチさせます。 'my($ num)= $ str =〜m /(\ d +)/;' – Sobrique

+0

@Sobriqueもっと良いです。私がしたように引用符を外すことは、quick'n'dirty sledge hammerアプローチです。 – PerlDuck

4

 勧告が終了


であるというエラーは、余分な引用符が原因であります最初にコーディングの問題について言及したいと思います。 looks_like_number($var) + ...を実行して値を追加するのはエラーです。 perlがEXPRは番号であると考えるならばScalar::Utilからlooks_like_number

trueを返します。

のテスト変数が数値かどうかを表します。ゼロまたは大きな正の整数を返します。だから、最初にgrepでフィルタリングして、どれが数字であるかを調べる必要があります。そして数字だけを使ってください。

answer by perlduckで説明されているように、余分な引用があることは明らかです。しかし、実際には数字ではないものを公開する可能性があるので、引用符をすべて削除するだけで十分です。また、他の処理が含まれている場合は、の内部に文字列が必要な場合があります。

私は最終的には、囲み引用符を取り除いた変数を最終的にはlooks_like_numberでテストし、数字のものを組み立てます。ここsumList::Utilモジュールが使用されているコアから、おそらく

use List::Util qw(sum); 
# Remove extra (leading and trailing) quotes, for example 
my @references = map { s/^"//; s/"$//; $_ } ($forward_reference, ...); 
my @numeric_refs = grep { looks_like_number($_) } @references; 
my $total_reads = sum @numeric_refs; 

。上記のすべては、各演算が戻り値を取るので、加算以外の何も行われなければ、1つのステートメントに入ることができます。


いっそのこと、あなたは非常にきれいに引用符を処理する、Text::CSVでタブ区切りファイルを解析することができます。

use warnings; 
use strict; 
use Text::CSV; 
use List::Util qw(sum); 

my $csv = Text::CSV->new( 
    { binary => 1, sep_char => "\t", allow_loose_quotes => 1 } 
) or die "Cannot use CSV: " . Text::CSV->error_diag(); 

my $file = $tsv_file_new; 
open my $fh, '<', $file or die "Can't open $file: $!"; 

while (my $row = $csv->getline($fh)) { 
    my @fields = @$row; 
    # process. double quotes around fields are gone 
    # ... 
    my @references = ($forward_reference, ...); 
    my $total_reads = sum grep { looks_like_number($_) } @references; 
} 
$csv->eof or $csv->error_diag(); 
close $fh; 
+1

@ user3781528あなたは直接回答を得ました。これは素晴らしいですが、私はここで更新を見なければならないと思います。 – zdim

関連する問題