2012-03-13 49 views
3

首先我道歉,如果這或類似的查詢,之前已經公佈,但我沒有按照步驟,並期待在這裏和超越,這就是爲什麼我訴諸問一個問題,我很少會做一些事情。我查詢之前如何從製表符分隔的數據文件中平均列值,忽略標題行和左列?

背景 - 我最後一年的生物醫學學生,我決定採取生物信息學論文 - 這只是剛剛開始在我的大學今年提供的論文。我認爲這將是一個很好的改變,但現在我已經有兩個星期的經驗,我沒有覺得它特別吸引人。具有挑戰性,是的,但沒有吸引力,因爲我從來沒有在我的生活中做過任何編程,我期望這麼突然地學習。因此,我向你展示的任何東西都是一個完整的「新手」,我承認我幾乎沒有任何線索去了解如何去做事,我真的很想嘗試和學習。

反正到我的查詢......

我的任務是計算從下面的數據文件均線,題爲Lab1_table.txt

retrovirus  genome gag  pol  env 
HIV-1   9181 1503 3006 2571 
FIV    9474 1353 2993 2571 
KoRV   8431 1566 3384 1980 
GaLV   8088 1563 3498 2058 
PERV   8072 1560 3621 1532 

我必須寫一個腳本,將打開和讀取該文件,由內容分成數組和計算機的數值(genomegagpolenv)的平均讀取每一行,並且從上述各列的寫入一個新文件的平均值。

我一直在努力弄清楚如何不考慮第一行或第一列,但每次我嘗試在命令行上執行時,我都不斷地提出'明確的包名'錯誤。

Global symbol @average requires explicit package name at line 23. 
Global symbol @average requires explicit package name at line 29. 
Execution aborted due to compilation errors. 

我明白,這涉及@$,但即使知道,我已經無法改變錯誤。

這是我的代碼,但我要強調的是,我已經開始這只是上週初學者:

#!/usr/bin/perl -w 
use strict; 

my $infile = "Lab1_table.txt"; # This is the file path 
open INFILE, $infile or die "Can't open $infile: $!"; 

my $count = 0; 
my $average =(); 

while (<INFILE>) { 
    chomp; 
    my @columns = split /\t/; 
    $count++; 
    if ($count == 1) { 
     $average = @columns; 
    } 
    else { 
     for(my $i = 1; $i < scalar $average; $i++) { 
      $average[$i] += $columns[$i]; 
     } 
    } 
} 

for(my $i = 1; $i < scalar $average; $i++) { 
    print $average[$i]/$count, "\n"; 
} 

我會很感激任何見解,我也將極大的感激讓我通過列表知道在每個步驟中編號您正在做的事情 - 如果合適的話。我想學習,如果我能夠讀懂某人的過程是什麼,那對我來說會更有意義。

+0

好吧,我看到你已經把'使用警告'和'使用嚴格'的誡命放在心上。這就是你的錯誤來自哪裏。你聲明'平均'是一個數組參考(有點),然後你用它作爲一個數組。 嘗試下列其中一項(但不是兩項): 1.將行更改爲@average或2.使用'$ average - > [i]'正確解除引用' 注意,這並不能解決整個問題,但它會擺脫你的錯誤信息,讓你專注於邏輯。 – lhagemann 2012-03-13 02:28:35

+0

哦,我只是不得不解除引用。這確實擺脫了最後兩個錯誤,你說得對,它不能解決整個問題,因爲我現在想到了這一點:不能使用字符串(「5」)作爲ARRAY ref,而「嚴格參考」在第23行使用第2行。 雖然我不確定這裏發生了什麼,但... – PkC 2012-03-13 02:42:27

+0

@PkC您可能希望更新您的代碼示例以顯示代碼的最新狀態。這對調試更有幫助。 – oalders 2012-03-13 03:00:00

回答

2

這裏有您需要更改
使用另一個變量的頭點

my $count = 0; 
my @header =(); 
my @average =(); 

然後更改邏輯中的if語句

if ($count == 1) { 
    @header = @columns; 
} 

現在不使用@average對於限制,請使用$i < scalar @columns作爲else語句。 最初@average爲零,永遠不會進入for循環。

else { 
    for(my $i = 1; $i < scalar @columns; $i++) { 
     $average[$i] += $columns[$i]; 
    } 
} 

最後加入-1到您的櫃檯。記住你增加你的計數器,當你分析你的頭

for(my $i = 1; $i < scalar @average; $i++) { 
    print $average[$i]/($count-1), "\n"; 
} 

下面是最終代碼
你可以採取的@header優勢,顯示效果整齊

#!/usr/bin/perl -w 

use strict; 

my $infile = "Lab1_table.txt"; # This is the file path 
open INFILE, $infile or die "Can't open $infile: $!"; 

my $count = 0; 
my @header =(); 
my @average =(); 

while (<INFILE>) { 
    chomp; 


    my @columns = split /\t/; 
    $count++; 
    if ($count == 1) { 
     @header = @columns; 
    } 
    else { 
     for(my $i = 1; $i < scalar @columns; $i++) { 
      $average[$i] += $columns[$i]; 
     } 
    } 
} 

for(my $i = 1; $i < scalar @average; $i++) { 
    print $average[$i]/($count-1), "\n"; 
} 

還有其他的方法來寫這個代碼但是我認爲只修改你的代碼會更好,這樣你就可以很容易地理解你的代碼出了什麼問題。希望它有幫助

+0

我只是想非常感謝你。我真的這樣做。它完美的工作,我可以看到正確的平均值。 0表示第一列,其他表示爲'標題'。 – PkC 2012-03-14 06:12:21

+0

我現在已經創建了一個'outfile'動作,以便我可以將結果打印到文本文件中。生成.txt文件,但其中沒有文本。 首先,輸出從我修改劇本弄出來有這樣的說法: 「代碼」論證「」是不是在行X ddition(+)數值,線Y.'code」 發生以上情況5次,我認爲這是由於我的源文件中的非數字標題(如上面的評論中所述)。 然後是'0'(我認爲是第一列),然後是4個所需的平均值。 我似乎無法打印到文件,出於某種原因。 – PkC 2012-03-14 09:34:04

+0

如果你爲此創建另一個問題會更好。 – jchips12 2012-03-15 01:28:26

相關問題