【问题标题】:Is it possible to merge data frames with different amounts of rows using Perl?是否可以使用 Perl 合并具有不同行数的数据帧?
【发布时间】:2021-04-30 05:21:43
【问题描述】:

我有一个小问题无法解决。

我有两个数据框(DF):第一个(主 DF)有 8 列和 45918 行,第二个(互补 DF)有 4 列和 97969 行。 如果你想看完整的 DF,这里是我的 GitHub 的链接:https://github.com/MauriAndresMU1313/Example_Merge_Dataframes

这是一个看起来像 DF 的示例。

主DF:

ID1          ID2         dN          dS          Omega       Label_ID1       Label_ID2       Group
AVP78042     AVP78031    0.0059      0.1188      0.0500      SARSr-bat-CoV   SARSr-bat-CoV   Intra
ATO98108     AVP78031    0.1373      1.4673      0.0936      SARSr-bat-CoV   SARSr-bat-CoV   Intra
ATO98108     AVP78042    0.1371      1.4224      0.0964      SARSr-bat-CoV   SARSr-bat-CoV   Intra

互补DF:

Distance    ID_1        ID_2        Value
DISTANCE    AVP78042.1  ATO98108.1  0.29731
DISTANCE    AVP78042.1  ATO98120.1  0.29281
DISTANCE    AVP78042.1  ATO98132.1  0.33095

在这种情况下,我的主要目标是将互补的列(ID_1、ID_2Value)合并到主 DF。两种情况下的 ID_1 和 ID_2 相同,但顺序不同。

为此,我认为在两个数据帧之间的 ID_1 和 2 之间进行匹配,并且当匹配为真时将列值(互补 DF)添加到主 DF。 我认为在“如果”条件下这样做。 这里的问题可能是每个 DF 之间的行数和标签(ID_1 和 ID_2)的顺序不同。
之前,我使用 Perl 脚本来合并 DF:


use strict;
use warnings;
use feature qw{ say };

sub load {
    my ($file, $table, $phase) = @_;
    open my $in, '<', $file or die "$file: $!";
    while (<$in>) {
        chomp;
        my @columns = split /\t/;
        my $id = join '_', @columns[0, 1];
        die "Duplicate $id."
            if 'first' eq $phase && exists $table->{$id};

        push @{ $table->{$id} }, $columns[2];
        say join "\t", @columns[0, 1], @{ $table->{$id} }
            if 'print' eq $phase;
    }
}

my %table;
my $phase = 'first';
while (my $file = shift @ARGV) {
    load($file, \%table, $phase);
    $phase = 1 == @ARGV ? 'print' : '';
}

我认为要完成这个脚本以实现我的新目标,我需要一个“if”条件来生成 ID 之间的匹配。 下面是一个可能的输出示例:

ID1          ID2         dN          dS          Omega   Value   Label_ID1       Label_ID2       Group
AVP78042     AVP78031    0.0059      0.1188      0.0500 0.29731  SARSr-bat-CoV   SARSr-bat-CoV   Intra
ATO98108     AVP78031    0.1373      1.4673      0.0936    -     SARSr-bat-CoV   SARSr-bat-CoV   Intra

我将“-”放在“值”列中,以显示 ID_1 和 ID_2 之间“不匹配”的示例。

我尝试了不同的方法,但是我还不能解决问题。

对此有何建议或意见?

【问题讨论】:

    标签: dataframe perl


    【解决方案1】:

    对我的输入文件进行更改后:

    Main DF:
    ID1          ID2         dN          dS          Omega
    AVP78042     AVP78031    0.0059      0.1188      0.0500 
    ATO98108     AVP78031    0.1373      1.4673      0.0936 
    ATO98108     AVP78042    0.1371      1.4224      0.0964 
    ...
    Complementary DF:
    ID1          ID2        Value
    AVP78042.1  ATO98108.1  0.29731
    AVP78042.1  ATO98120.1  0.29281
    ...
    

    此脚本在 ID 匹配时合并列:

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    my $file01 = $ARGV[0];
    my $file02 = $ARGV[1];
    my @content02;
    
    open (B, $file02) or die;
    while (my $l1 = <B>) {
      $l1 =~ s/\n//g;
      $l1 =~ s/\r//g;
      $l1 =~ s/^ //g;
      push @content02, $l1 ;
    }
    close B;
    
    ### Running with the first file ()
    open (A, $file01) or die;
    
    LINE:
    while (my $l2 = <A>) { # From file 1 (ref)
      $l2 =~ s/\n//g;
      $l2 =~ s/\r//g;
      $l2 =~ s/ //g;
      my @matrix_2 = split ("\t", $l2);
      my $two_id_01 = $matrix_2[0]; ### No tiene punto
      my $two_id_02 = $matrix_2[1]; ### No tiene punto
    
      foreach my $q (@content02) { ### From file 2
        my @matrix_q = split ("\t", $q);
        my $q_id_01 = $matrix_q[0];
        my $q_id_02 = $matrix_q[1];
        my $value = $matrix_q[2];
    
        if (($q_id_01 =~ /^$two_id_01/) and ( $q_id_02 =~ /^$two_id_02/) ) {
          print "$l2\t$value\n";
          next LINE;
        }
      }
    }
    
    
    close A;
    
    exit;
    

    输出:

    Merge DF (6 columns x 42336 rows) 
    ID1          ID2         dN     dS      Omega   Value
    ATO98108    AVP78042    0.1371  1.4224  0.0964  0.29731
    ATO98120    AVP78042    0.1376  1.2989  0.1060  0.29281
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-25
      • 2016-07-31
      • 1970-01-01
      • 2020-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多