簡體   English   中英

如果列相同,則合並R數據框中的連續行

[英]Merging consecutive rows in R dataframe if columns are same

我正在嘗試將我的Perl腳本之一轉換為R腳本。 我在R中有一個數據框,看起來像(忽略列名)-

CHR     START          END      TYPE
chr1    945493         945593   normal
chr1    945593        947374    normal
chr1    947374        947474    normal
chr1    947474        947574    gain
chr1    947574        947674    gain
chr1    947674        960364    gain
chr1    960364        960464    normal
chr22   17290491    17290591    normal
chr22   17290591    17290691    normal
chr22   17290691    17290791    gain
chr22   17290791    17292513    gain
chr22   17292513    17292613    gain
chr22   17292613    17292713    gain
chr22   17292713    17293046    gain
chr22   17293346    17298475    gain
chr22   17298475    17298575    gain
chr22   17298575    17298675    normal
chr22   17298675    17303632    normal
chr22   17303632    17303732    loss
chr22   17303732    17303832    normal
chrX    154162621   154181221   normal
chrX    154181221   154181321   normal
chrX    154181321   154181421   loss
chrX    154181421   154181521   loss
chrX    154181521   154181621   loss
chrX    154181621   154181721   loss
chrX    154181721   154216867   loss
chrX    154216867   154216967   normal
chrX    154216967   154217067   normal
chrX    154217067   154217167   normal

如果“ CHR”列和“ TYPE”列中至少有5個連續行具有相同的值,則將所有這些行合並為一行,以便START列應具有第一行的值,END列應具有最后一行的值並在末尾只需返回具有“收益”或“虧損” TYPE的行即可。 因此,所需的輸出為:

chr22   17290691        17298575        gain
chrX    154181321       154216867       loss

我現在正在做的是:

  1. 用“ write.table”保存數據框。
  2. 使用此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; } } 

我認為這是一個額外的步驟,先保存數據框,然后再使用Perl腳本。 任何人都可以建議使用R中更簡單的方法-任何軟件包或任何其他技巧嗎?

遵循這些原則?

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

我擔心如果一個染色體中存在TYPE的替代值,您應該要中斷這些序列(即,將它們視為不同的)。 您沒有具體說明,但我認為生物學將保證有此附加要求。 因此,需要創建另一個變量。 在沒有相反建議的情況下,我們將假定數據幀名為cdat 這將在TYPE的連續運行中查找,應用測試,並將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

conseq向量是通過將下一個TYPE值與其先前的值進行比較,並通過cumsum()-沿其整個長度出現一個新值來構建的。 由於這些變量要短一個元素。 1在開頭添加為占位符,以使其與數據框對齊。

如果您熟悉SQL並想對數據幀進行很多操作,則另一個選擇是sqldf庫,該庫允許您在R數據幀上執行SQL查詢。 它使這樣的操作變得非常容易。

還有R-Perl接口 ,它可以讓您保留現有的Perl代碼,然后對結果進行R處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM