Perl 如果列相同,则合并R数据帧中的连续行

Perl 如果列相同,则合并R数据帧中的连续行,perl,r,Perl,R,我正在尝试将一个Perl脚本转换为R脚本。我在R中有一个数据框,看起来像(忽略列名)- 起始-结束类型 chr1 945493 945593正常 chr1 945593 947374正常 chr1 947374 947474正常 chr1 947474 947574增益 chr1 947574 947674增益 chr1 947674 960364增益 chr1 960364 960464正常 chr22 17290491 17290591正常 chr22 17290591 17290691正常

我正在尝试将一个Perl脚本转换为R脚本。我在R中有一个数据框,看起来像(忽略列名)-

起始-结束类型 chr1 945493 945593正常 chr1 945593 947374正常 chr1 947374 947474正常 chr1 947474 947574增益 chr1 947574 947674增益 chr1 947674 960364增益 chr1 960364 960464正常 chr22 17290491 17290591正常 chr22 17290591 17290691正常 chr22 17290691 17290791增益 chr22 17290791 17292513增益 chr22 17292513 17292613增益 chr22 17292613 17292713增益 chr22 17292713 17293046增益 chr22 17293346 17298475增益 chr22 17298475 17298575增益 chr22 17298575 17298675正常 chr22 17298675 17303632正常 CHR217303632 17303732损失 CHR217303732 17303832正常 chrX 154162621 154181221正常 chrX 154181221 154181321正常 chrX 154181321 154181421损失 chrX 154181421 154181521损失 chrX 154181521 154181621损失 chrX 154181621 154181721损失 chrX 154181721 154216867损失 chrX 154216867 154216967正常 chrX 154216967 154217067正常 chrX 154217067 154217167正常 如果至少有5个连续行在“CHR”列和“TYPE”列中具有相同的值,则将所有这些行合并到一行中,以便开始列应具有第一行的值,结束列应具有最后一行的值,最后只返回具有“增益”或“损失”类型的行。因此,期望的输出是:

chr22 17290691 17298575 gain chrX 154181321 154216867 loss chr22 17290691 17298575增益 chrX 154181321 154216867损失 我现在正在做的是:

  • 使用“write.table”保存数据帧
  • 使用以下perl脚本:

      open $first, "<",$ARGV[0] or die "Unable to open input file: $!";
      my $count=1;
      $_ = <$first>;
      chomp;
      my ($p_key, $p_col1, $p_col2,$p_cnv) = split;
    
      while(<$first>) {
          chomp;
          my ($key, $col1, $col2,$cnv) = split;
          if ($key eq $p_key and $cnv eq  $p_cnv) {
            $p_col2 = $col2;
            $count++;
    
          } elsif ($count > 4){
    
    
             print $p_key,"\t", $p_col1,"\t", $p_col2,"\t", $p_cnv,"\n" if($p_cnv eq "gain" or $p_cnv eq "loss");
             ($p_key, $p_col1, $p_col2, $p_cnv) = ($key, $col1, $col2, $cnv);
             $count=1;
            }
    
           else { 
    
        ($p_key, $p_col1, $p_col2, $p_cnv) = ($key, $col1, $col2, $cnv);
            $count=1;
           }
    }
    

    先打开$first,“类似这样的东西

    library(plyr)
    ddply(x[x$TYPE %in% c("gain", "loss"), ], 
          .(CHR, TYPE), 
          function(z){if(nrow(z) < 5) NULL else z[range(seq_len(nrow(z))), ]}
          )
    
        CHR     START       END TYPE
    1 chr22  17290691  17290791 gain
    2 chr22  17298475  17298575 gain
    3  chrX 154181321 154181421 loss
    4  chrX 154181721 154216867 loss
    
    库(plyr)
    ddply(x[x$类型%c(“收益”、“损失”),],
    (CHR,类型),
    函数(z){if(nrow(z)<5)NULL else z[范围(seq_len(nrow(z))),]}
    )
    起始-结束类型
    1 chr22 17290691 17290791增益
    2 chr22 17298475 17298575增益
    3 chrX 154181321 154181421损失
    4 chrX 154181721 154216867损失
    
    这是什么意思

    library(plyr)
    ddply(x[x$TYPE %in% c("gain", "loss"), ], 
          .(CHR, TYPE), 
          function(z){if(nrow(z) < 5) NULL else z[range(seq_len(nrow(z))), ]}
          )
    
        CHR     START       END TYPE
    1 chr22  17290691  17290791 gain
    2 chr22  17298475  17298575 gain
    3  chrX 154181321 154181421 loss
    4  chrX 154181721 154216867 loss
    
    库(plyr)
    ddply(x[x$类型%c(“收益”、“损失”),],
    (CHR,类型),
    函数(z){if(nrow(z)<5)NULL else z[范围(seq_len(nrow(z))),]}
    )
    起始-结束类型
    1 chr22 17290691 17290791增益
    2 chr22 17298475 17298575增益
    3 chrX 154181321 154181421损失
    4 chrX 154181721 154216867损失
    
    如果您熟悉SQL并希望对数据帧进行大量操作,另一个选项是库,它允许您在R数据帧上执行SQL查询。这样的操作非常简单


    还有一个选项,它允许您保留现有的Perl代码,然后对结果进行处理。

    如果您熟悉SQL并希望对数据帧进行大量操作,另一个选项是库,它允许您对R数据帧执行SQL查询。这样的操作非常简单


    还有一个,允许你保留你现有的Perl代码,然后用结果做R。

    < P>我关心的是你应该中断序列(即把它们看成是不同的)。如果在一条染色体中存在类型的中间替代值。您没有明确说明,但我认为生物学会保证这一额外要求。因此需要创建另一个变量。在没有相反建议的情况下,我们将假设数据框名为
    cdat
    。这看起来与在类型的连续运行中,应用测试,并将CHR和START绑定到开头,将END和TYPE绑定到最后一个元素

    cdat$conseq <-cumsum(c(1, cdat$TYPE[-1] != cdat$TYPE[-length(cdat$TYPE)] ) )
    do.call( rbind, 
        by(cdat, list(cdat$CHR, cdat$conseq), 
             function(df)
                if( NROW(df) >=5 & df$TYPE[1] %in% c("gain", "loss") ) {
                    cbind(df[1, c("CHR", "START")] , df[NROW(df), c("END", "TYPE")] ) 
                    } else{NULL} ) )
         CHR     START       END TYPE
    10 chr22  17290691  17298575 gain
    23  chrX 154181321 154216867 loss
    
    cdat$conseq=5&df$TYPE[1]%,单位为%c(“收益”、“损失”)){
    cbind(df[1,c(“CHR”,“START”)]),df[NROW(df),c(“END”,“TYPE”)]))
    }else{NULL})
    起始-结束类型
    10 chr22 17290691 17298575增益
    23 chrX 154181321 154216867损失
    

    conseq向量是通过比较下一个类型值与其前一个值和cumsum()建立的-一个新的值沿其全长出现。因为这些变量是一个元素较短的。1在开始时被添加为占位符,以使其与数据文件对齐。

    < P>我关心的是,你应该中断序列(即认为它们是不同的)。如果在一条染色体中存在类型的中间替代值。您没有明确说明,但我认为生物学会保证这一额外要求。因此需要创建另一个变量。在没有相反建议的情况下,我们将假设数据框名为
    cdat
    。这看起来与在类型的连续运行中,应用测试,并将CHR和START绑定到开头,将END和TYPE绑定到最后一个元素

    cdat$conseq <-cumsum(c(1, cdat$TYPE[-1] != cdat$TYPE[-length(cdat$TYPE)] ) )
    do.call( rbind, 
        by(cdat, list(cdat$CHR, cdat$conseq), 
             function(df)
                if( NROW(df) >=5 & df$TYPE[1] %in% c("gain", "loss") ) {
                    cbind(df[1, c("CHR", "START")] , df[NROW(df), c("END", "TYPE")] ) 
                    } else{NULL} ) )
         CHR     START       END TYPE
    10 chr22  17290691  17298575 gain
    23  chrX 154181321 154216867 loss
    
    cdat$conseq=5&df$TYPE[1]%,单位为%c(“收益”、“损失”)){
    cbind(df[1,c(“CHR”,“START”)]),df[NROW(df),c(“END”,“TYPE”)]))
    }else{NULL})
    起始-结束类型
    10 chr22 17290691 17298575增益
    23 chrX 154181321 154216867损失
    

    conseq向量是通过比较下一个类型值与其前一个值和cumsum()建立的-将一个新值的外观沿其整个长度进行调整。因为这些变量短了一个元素。在开始时添加1作为占位符,以使其与数据帧对齐。

    作为第一步,为什么不简单地将Perl脚本转换为R(看起来相当直截了当的代码),并查看是否遇到任何问题?这就是我想做的。在Perl中似乎很容易,但我不知道如何在R中完成。在Perl脚本中,您使用
    &
    (按位和)而不是
    &
    (C-s)