Как использовать столбец значений индекса для создания нового столбца в отдельном наборе данных - PullRequest
3 голосов
/ 26 апреля 2019

У меня были проблемы с объединением значений между двумя наборами данных, и мне было интересно, может ли кто-нибудь мне помочь. Я думаю, что я близок к решению, так что, надеюсь, кто-то может указать, что может быть не так.

Итак, у меня есть два типа наборов данных. Один из них выглядит так, назовем его dataset1:

1 Asia 
2 Australia
3 Europe

dataset1 содержит мой набор ссылок, где каждое число связано со значением. Другой набор данных, набор данных2, выглядит примерно так:

4638  3
14372 3
4464  1
3498  2

Что я хочу сделать, так это использовать значения второго столбца из набора данных2 и найти соответствующее значение индекса в наборе данных1, чтобы я добавил новый столбец, например:

4638  3 Europe  
14372 3 Europe  
4464  1 Asia
3498  2 Australia

Я пытался создать хеш значений в первом наборе данных и использовать их в качестве ссылки для второй базы данных, например:

open($fh, "<", $dataset1) || die "Could not open file $dataset $!/n"; 

while (<$fh>) {
    @tmp = split /\t/, $_;
    $area{$tmp[0]} = $tmp[1];
}

open($fh2, "<", $dataset2) || die "Could not open file $dataset $!/n;

while (<$fh2>) {
   @tmp2 = split /\t/, $_;
    $code = $tmp2[0];
    $index= $tmp2[1];
    if(defined($area{$index})){
        print "$code\t$index\t$area{$index}\n";
    }
}

Когда я выполняю вышеупомянутую команду, я не получаю предупреждений, но ничего не распечатывается. Я предполагаю, что есть проблема с "определенным" разделом, но я не уверен, как решить это. Любая помощь будет оценена .

Лучший, A.

Ответы [ 2 ]

3 голосов
/ 26 апреля 2019

Вот, пожалуйста. Я использовал хэш-ссылку, потому что они мне нравятся, и я думаю, что ваше разделение на \ t стало основной причиной невозможности правильно отобразить карту.

EDIT: added chomp and ability to deal with space separated language names

#!/usr/bin/env perl
use strict;
use warnings;

my $ds1_map;

open(my $fh1, "<", 'dataset1') || die "Could not open file dataset1 $!/n"; 
while (my $line = <$fh1> ) {
    chomp($line);
    my @tmp = split(/\s+/, $line);
    my $i = shift @tmp;
    my $str = join(' ', @tmp);
    $ds1_map->{$i} = $str;
}
close $fh1;

open(my $fh2, "<", 'dataset2') || die "Could not open file dataset2 $!/n";
while (my $line = <$fh2>) {
    chomp($line);
    my ($code, $index) = split(/\s+/, $line);
    if(defined($ds1_map->{$index})){
        print "$code\t$index\t$ds1_map->{$index}\n";
    }
}
close $fh2;
1 голос
/ 27 апреля 2019

Вот способ сделать это, используя анонимные массивы, созданные с помощью split -в каждой строке в файле справочных данных и map -введения их элементов в набор хеш-ключей / значений.

NB. Я использовал IO::All для сокращения сценария, поэтому может быть неэффективно отбирать очень большие файлы таким образом.

use IO::All ;                       
my @idx = io->file("dataset1.txt")->chomp->slurp  ;               
my @data = io->file("dataset2.txt")->chomp->slurp  ;

# make an index hash_ref with successive elements of split lines           
my $index_hr = { map { [split]->[0] => [split]->[1] } @idx };

# print lines where the second element matches index hashref key
foreach my $line (@data) {                                
  my $key = (split /\s+/, $line)[1] ;                              
  print join " ", $line, $index_hr->{$key}, "\n" ;    
}

Вывод

4638  3 Europe 
14372 3 Europe 
4464  1 Asia 
3498  2 Australia 
...