我第一次不知道要搜索什麼,因爲我知道如何在Excel中做到這一點,但無法找到一個簡單的方法(用我有限的知識)在Perl中做到這一點。我需要對譜系文件重新編號(超過140萬條記錄),但不幸的是,由於PC功能和excel電子表格功能,excel vlookup不足以滿足要求。Perl:使用引用有其他散列
的文件需要被重新編號,所以個人沒有比他們的父母一個較低的數字,所以我的測試文件看起來是這樣的:
Ani | Sire | Dam
----------------
15 | 1 | 2
12 | 1 | 2
30 | 15 | 12
18 | 15 | 2
26 | 15 | 30
48 | 18 | 30
32 | 26 | 48
50 | 26 | 30
1和2表示未知的父(我會讓他們爲1/2),並重新編號從10開始,使「新的ID」如下:
Old_ID | New_ID
---------------
15 | 10
12 | 11
30 | 12
18 | 13
26 | 14
48 | 15
32 | 16
50 | 17
所以,我想看到的輸出將被
new_ani | new_sire | new_dam
----------------------------
10 | 1 | 2
11 | 1 | 2
12 | 10 | 11
13 | 10 | 2
14 | 10 | 12
15 | 13 | 30
16 | 14 | 15
17 | 14 | 12
使用兩個散列函數,我嘗試(不成功)首先將第一列鏈接到新ID(我可以這樣做),然後是陛下和dam列(我不能這樣做)。
爲了減少代碼量,我忽略了計算新壩標的塊,因爲它將是父系的複製品。我在我的代碼迄今如下:
use strict;
use warnings;
my $input_file = .../pedigree.csv;
open (INPUT, "<", $input_file) or die "Cant open $input_file: $!";
my new_id = 0;
my %old_ped =();
my %new_id =();
while (<INPUT>){
my $line = $_;
$line =~ s/\s*$//g;
my ($ani,$sire,$dam) = split('\,',$line);
next if $ani eq 'db_animal' or !$ani or $ani eq 'ani';
$old_ped{$ani}[0] = $ani;
$old_ped{$ani}[1] = $sire;
$old_ped{$ani}[2] = $dam;
$new_id++;
$new_id{$ani}[0] = $ani;
$new_id{$ani}[1] = $new_id;
}
close INPUT;
foreach my $tt (sort keys %old_ped){
#animal
if ($old_ped{$tt}[0] == $new_id{$tt}[0]){
print "$new_id{$tt}[1],";
#sires
if ($old_ped{$tt}[1] == 1){
print " 1,";
}
else{
foreach my $tt (sort keys %new_id) {
if ($old_ped{$tt}[1] == $nuwe_id{$tt}[0]){
print "$new_id{$tt}[1],";
}
}
}
}
# AND REPEAT SIRE BLOCK FOR DAM
print "\n";
}
但是...我顯然得到錯誤的輸出作爲引用未連接,所以沒有對公畜(或水壩)匹配。
我試圖而不是創建2個額外的散列,一個用於父親和母親,使用父親和母親ID作爲參考:
$sire{$sire}[0] = $sire;
$sire{$sire}[1] = $dierid;
$dam{$dam}[0] = $dam;
$dam{$dam}[1] = $dierid;
和在foreach使用它們如下:
foreach my $tt (sort keys %old_ped){
#animal
if ($old_ped{$tt}[0] == $new_id{$tt}[0]){
print "$new_id{$tt}[1],";
#sires
if ($old_ped{$tt}[1] == 1){
print " 1,";
}
else{
foreach my $tt (sort keys %sire) {
if ($sire{$tt}[0] == $nuwe_id{$tt}[0]){
print "$new_id{$tt}[1],";
}
}
}
}
# AND REPEAT SIRE BLOCK FOR DAM
print "\n";
}
我猜我沒有正確使用我的散列,或者我可能需要使用不同的循環?然而,我的知識仍然非常基礎和缺乏。
任何幫助將非常感謝!
您的文件很簡單的CSV?您能否包含不像表格那樣縮進的演示數據?你可以[編輯]你的問題。你也可以不使用文件而是使用文件尾部的'__DATA__'塊,除去'open',而只是從''中讀取。這將使你的代碼在[mcve]上更容易工作。 – simbabque
'my new_id'處還有一個缺少'$'的地方。請勿將您的代碼重新寫入Stack Overflow。顯示你的真實代碼。我們不想追逐那些並不真正存在的語法錯誤。我相信那是因爲你將一些荷蘭語(或南非荷蘭語)的變量名翻譯成了英語。你在循環的最深處確實錯過了一個。 – simbabque
謝謝 - 是的,我翻譯過(南非荷蘭語),但是將來會謹記準確的代碼和CSV!也感謝你的回答 - 這就是爲什麼我喜歡stackoverflow,你真的學到很多 - 特別是當你的知識非常缺乏時! –