Compare columnas de diferentes archivos con diferentes tamaños y reemplácelas con NA valores que no coincidan

Compare columnas de diferentes archivos con diferentes tamaños y reemplácelas con NA valores que no coincidan

Tengo tres marcos de datos:

Marco de datos 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

Marco de datos 2

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

Marco de datos 3

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

y me gustaría obtener un marco de datos final donde, de acuerdo con la cuarta columna del primer marco de datos, se informará una coincidencia o no coincidencia en relación con la cuarta columna del segundo y tercer marco de datos. En un nuevo marco de datos, si hay una coincidencia, se informará la misma identificación, pero en caso de que haya una coincidencia, el nombre de la identificación se reemplazará con un NA. Quizás simplemente escribir entradas y salidas sea más fácil de entender. Algo como esto:

Salida deseable:

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

Lo intenté con el comando join en Unix pero no puedo comparar marcos de datos de diferentes tamaños. Cualquier idea será muy apreciada.

Respuesta1

awksolución:

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

La salida:

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, df3y df1son tu 2.º, 3.º y 1.ºmarco de datosarchivos respectivamente

  • FILENAME- variable incorporada que apunta al nombre del archivo actualmente procesado

  • ARGV- variable incorporada que apunta a todos los argumentos pasados ​​al script awk. es decir, ARGV[1]contienedf2

  • FILENAME == ARGV[1] && NR>1- encontrar el primer archivo (es decir df2) a partir de la segunda línea

    • df2[$2,$3,$4]- capturar valores cruciales de "Marco de datos 2"como clave de matrizdf2
  • FILENAME == ARGV[2] && FNR>1- encontrar el segundo archivo (es decir df3) a partir de la segunda línea

    • df3[$2,$3,$4]- capturar valores cruciales de "Marco de datos 3"como clave de matrizdf3
  • FILENAME == ARGV[3]- encontrar el tercer archivo (es decir df1), el principalMarco de datos

Respuesta2

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

Funcionamiento

  • El orden de las entradas es: marco de datos3, marco de datos2 y marco de datos1.
  • Suponiendo que el marco de datos1 tiene las cuartas columnas completas, IOW, no falta ninguna.
  • Invocamos Perlen modo lectura de línea+autosplit:perl -lane
  • Durante el tiempo que se lee el tercer fotograma, @ARGV tiene 2 elementos, durante el segundo fotograma leído hay 1 elemento y 0 durante el tercer fotograma.
  • Completamos un hash, %hcuyas claves son los campos 2.º y 3.º, $F[1],$F[2]y los valores son referencias de matriz anónimas, por lo que se denominan: $h{...}[...].
  • Durante el tiempo del primer marco de datos (@ARGV que tiene 0 elementos), imprimimos cada línea con el contenido del primer marco de datos y determinamos si los elementos de la matriz existen o no para el segundo/tercer marco para el segundo actual correspondiente. /3er campos.

información relacionada