두 행렬의 열 동기화

두 행렬의 열 동기화

이 문제를 해결하는 방법을 안내해 주십시오. 동일한 공통 열을 동일한 순서로 갖도록 수정해야 하는 한 쌍의 파일이 있습니다.

내 파일이 다음과 같이 File1과 File2인 경우

  R1 C1 C2 C3 C4
  R2 1 2 3 4 
  R3 5 6 7 8


  R6 C4 C3 C6 C7
  R7 9 10 11 12
  R8 13 14 15 16

mod_File1과 mod_File2를 찾고 있습니다.

  R1 C3 C4
  R2 3 4 
  R3 7 8

  R6 C3 C4
  R7 10 9
  R8 14 13

내가 시도한 것은 다음과 같습니다.

awk '
  FNR==1        {F++}
  F==1          {
        if (NR==1) 
        for (i=2;i<NF;i++) 
        {
        col1[$i];
        }
        next
        }
  F==2          {
        if (NR==1) 
        for (i=2;i<NF;i++) 
        {
        col2[$i];
        }
        next
        }
  F=3           {   NR==1 { 
            for (i=2;i<NF;i++)
                         if ($i in cols2)
                         c1[i];
                          }
                    NR>1 { for (j in c1)
                        print $j >> mod_file1
                 }
  F=4           {   NR==1 { 
            for (i=2;i<NF;i++)
                             if ($i in cols1)
                             c1[i];
                           }
                     NR>1 { for (j in c1)
                        print $j >> mod_file2
                 }
     ' file1 file1 file2 file2   

답변1

보이는 것보다 조금 더 복잡합니다. 아마도 더 나은 기능을 제공하는 라이브러리가 있을 것입니다(Perl에는 많은 수학 라이브러리가 있습니다).

하지만 이렇게 하면 원하는 결과를 얻을 수 있습니다.

#!/usr/bin/perl

use strict;
use warnings;


#read file 1
open( my $file1, "<", "data1.txt" ) or die $!;

my $header_line = <$file1>;
chomp($header_line);
my ( $column1, @headers1 ) = split( ' ', $header_line );

my %results;
my %headers_in_file1 = map { $_ => 1 } @headers1;

for (<$file1>) {
    my ( $column, @values ) = split;
    my %these_results;
    @these_results{@headers1} = @values;
    $results{$column}         = \%these_results;
}
close ( $file1);


#read file 2
open( my $file2, "<", "data2.txt" ) or die $!;
$header_line = <$file2>;
chomp($header_line);
my ( $column2, @headers2 ) = split( ' ', $header_line );

my %results2;
my %headers_in_file2 = map { $_ => 1 } @headers2;

for (<$file2>) {
    my ( $column, @values ) = split;
    my %these_results;
    @these_results{@headers2} = @values;
    $results2{$column}        = \%these_results;
}
close ( $file2 );

#figure out the columns in both
my %in_both;
foreach my $header ( @headers1, @headers2 ) {
    if (    $headers_in_file1{$header}
        and $headers_in_file2{$header} )
    {
        $in_both{$header}++;
    }
}

#sort out headers for output. 
my @output_headers = sort keys %in_both;

print join( " ", $column1, @output_headers ), "\n";
foreach my $row ( sort keys %results ) {
    print $row, " ";
    for my $header (@output_headers) {
        print $results{$row}{$header}, " ";
    }
    print "\n";
}

print "Second\n";
print join( " ", $column2, @output_headers ), "\n";
foreach my $row ( sort keys %results2 ) {
    print $row, " ";
    for my $header (@output_headers) {
        print $results2{$row}{$header}, " ";
    }
    print "\n";
}

관련 정보