Compare as colunas de arquivos diferentes com tamanhos diferentes e substitua por valores NA não correspondentes

1

Eu tenho três quadros de dados:

Dataframe 1

chr start end Id chr1 1 400 SN_1 chr1 401 800 SN_2 chr1 801 1200 SN_3 chr1 1201 1600 SN_4 chr1 1601 2000 SN_5 chr1 2001 2400 SN_6 chr1 2401 2800 SN_7

Dataframe 2

chr start end Id chr1 401 800 SN_2 chr1 801 1200 SN_3 chr1 1201 1600 SN_4

Dataframe 3

chr start end Id chr1 1201 1600 SN_4 chr1 1601 2000 SN_5 chr1 2001 2400 SN_6

e gostaria de obter um quadro de dados final onde, de acordo com a 4ª coluna do 1º quadro de dados, será reportado um resultado ou um não correspondência em relação à 4ª coluna do 2º e 3º quadro de dados. Em um novo quadro de dados Se houver uma correspondência, o mesmo ID será informado, mas caso haja uma correspondência, o nome da identificação será substituído por um NA. Talvez apenas escrever entrada e saída seja mais fácil de entender. Algo como este:

Desirable output:

chr start end Id Id Id chr1 1 400 SN_1 NA NA chr1 401 800 SN_2 SN_2 NA chr1 801 1200 SN_3 SN_3 NA chr1 1201 1600 SN_4 SN_4 SN_4 chr1 1601 2000 SN_5 NA SN_5 chr1 2001 2400 SN_6 NA SN_6 chr1 2401 2800 SN_7 NA NA

Eu tentei unir-se ao comando unix, mas não posso comparar o quadro de dados de tamanho diferente. Qualquer ideia será muito apreciada.

    
por fusion.slope 31.05.2017 / 20:14

2 respostas

2
Solução

awk :

awk 'FILENAME == ARGV[1] && NR>1{ df2[$2,$3,$4] }
     FILENAME == ARGV[2] && FNR>1{ df3[$2,$3,$4] }
     FILENAME == ARGV[3]{ if(FNR == 1) { printf("%s\t%s\t%s\n",$0,$NF,$NF) } 
     else { printf("%s\t%s\t%s\n",$0, (($2,$3,$4) in df2)? $NF :"NA",(($2,$3,$4) in df3)? $NF :"NA")} 
}' df2 df3 df1 | column -t

A saída:

chr   start  end   Id    Id    Id
chr1  1      400   SN_1  NA    NA
chr1  401    800   SN_2  SN_2  NA
chr1  801    1200  SN_3  SN_3  NA
chr1  1201   1600  SN_4  SN_4  SN_4
chr1  1601   2000  SN_5  NA    SN_5
chr1  2001   2400  SN_6  NA    SN_6
chr1  2401   2800  SN_7  NA    NA
  • df2 , df3 e df1 são seus arquivos de segundo, terceiro e primeiro dataframe

  • FILENAME - variável interna apontando para o nome do arquivo atualmente processado

  • ARGV - variável interna apontando para todos os argumentos passados para o script awk. Por exemplo, ARGV[1] contém df2

  • FILENAME == ARGV[1] && NR>1 - encontrando o primeiro arquivo (ou seja, df2 ) a partir da segunda linha

    • df2[$2,$3,$4] - capturando valores cruciais de " Dataframe 2 " como chave da matriz df2
  • FILENAME == ARGV[2] && FNR>1 - encontrando o segundo arquivo (por exemplo, df3 ) a partir da segunda linha

    • df3[$2,$3,$4] - capturando valores cruciais de " Dataframe 3 " como chave da matriz df3
  • FILENAME == ARGV[3] - encontrando o terceiro arquivo (ou seja, df1 ), o principal Dataframe

por 31.05.2017 / 20:47
0
perl -lane '$,="\t";
   !@ARGV and $. == 1 and print($_, qw/Id/x2),next;
   $h{$F[1],$F[2]}->[@ARGV] = $F[3];
   !@ARGV and print $_, map { $h{$F[1],$F[2]}->[$_] // q/NA/ } 1..2;
   $. = 0 if eof;
' file3 file2 file1

Resultados

chr    start   end     Id       Id      Id
 chr1   1       400     SN_1    NA      NA
 chr1   401     800     SN_2    SN_2    NA
 chr1   801     1200    SN_3    SN_3    NA
 chr1   1201    1600    SN_4    SN_4    SN_4
 chr1   1601    2000    SN_5    NA      SN_5
 chr1   2001    2400    SN_6    NA      SN_6
 chr1   2401    2800    SN_7    NA      NA

Funcionamentos

  • A ordem das entradas é: dataframe3, dataframe2 e dataframe1.
  • Supondo que o dataframe1 tenha todas as 4 colunas preenchidas, o IOW, nenhuma falta.
  • Invocamos Perl no modo de leitura de linha + autosplit: perl -lane
  • Durante o tempo em que o 3º quadro está sendo lido, @ARGV tem 2 elementos, durante o segundo quadro lido, são 1 elementos e 0 durante o 3º quadro.
  • Nós preenchemos um hash, %h , cujas chaves são o segundo + terceiro campos, $F[1],$F[2] e os valores são referências de matriz anônima, portanto, referidos como: $h{...}[...] .
  • Durante o tempo do primeiro quadro de dados (@ARGV com 0 elementos), estamos imprimindo cada linha com o conteúdo do primeiro quadro de dados e determinando se os elementos de matriz existem ou não para o segundo / terceiro quadros do correspondentes campos atuais de 2º / 3º.
por 31.05.2017 / 21:35