Ich habe drei Datenrahmen:
Datenrahmen 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
Datenrahmen 2
chr start end Id chr1 401 800 SN_2 chr1 801 1200 SN_3 chr1 1201 1600 SN_4
Datenrahmen 3
chr start end Id chr1 1201 1600 SN_4 chr1 1601 2000 SN_5 chr1 2001 2400 SN_6
und ich möchte einen endgültigen Datenrahmen erhalten, in dem gemäß der 4. Spalte des 1. Datenrahmens eine Übereinstimmung oder eine Nichtübereinstimmung in Bezug auf die 4. Spalte des 2. und 3. Datenrahmens gemeldet wird. In einem neuen Datenrahmen wird bei einer Übereinstimmung dieselbe ID gemeldet, aber falls eine Übereinstimmung vorliegt, wird der ID-Name durch ein NA ersetzt. Vielleicht ist es einfacher zu verstehen, einfach Eingabe und Ausgabe aufzuschreiben. Etwa so:
Erwünschtes Ergebnis:
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
Ich habe es mit dem Join-Befehl im Unix versucht, kann aber Datenrahmen unterschiedlicher Größe nicht vergleichen. Für jede Idee bin ich sehr dankbar.
Antwort1
awkLösung:
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
Die Ausgabe:
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
und sind Ihr 2., 3. und 1df3
.df1
DatenrahmenDateien bzw.FILENAME
- integrierte Variable, die auf den Namen der aktuell verarbeiteten Datei zeigtARGV
- integrierte Variable, die auf alle an das awk-Skript übergebenen Argumente verweist. Das heißt, sieARGV[1]
enthältdf2
FILENAME == ARGV[1] && NR>1
- Auffinden der 1. Datei (dhdf2
) ab der 2. Zeiledf2[$2,$3,$4]
- Erfassung entscheidender Werte aus "Datenrahmen 2" als Schlüssel des Arraysdf2
FILENAME == ARGV[2] && FNR>1
- Auffinden der 2. Datei (dhdf3
) ab der 2. Zeiledf3[$2,$3,$4]
- Erfassung entscheidender Werte aus "Datenrahmen 3" als Schlüssel des Arraysdf3
FILENAME == ARGV[3]
- Begegnung mit der 3. Datei (dhdf1
), der HauptDatenrahmen
Antwort2
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
Ergebnisse
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
Funktionsweise
- Die Reihenfolge der Eingaben ist: dataframe3, dataframe2 und dataframe1.
- Angenommen, dass in dataframe1 alle 4. Spalten ausgefüllt sind, mit anderen Worten, es fehlt keine.
- Wir rufen
Perl
im Line-Read-In+Autosplit-Modus auf:perl -lane
- Während der 3. Frame gelesen wird, hat @ARGV 2 Elemente, während des 2. Frames 1 Element und während des 3. Frames 0 Elemente.
- Wir füllen einen Hash aus,
%h
dessen Schlüssel das 2. und 3. Feld sind$F[1],$F[2]
und dessen Werte anonyme Array-Referenzen sind, daher als: bezeichnet$h{...}[...]
. - Während der Zeit des 1. Datenrahmens (@ARGV hat 0 Elemente) drucken wir jede Zeile mit dem Inhalt des 1. Datenrahmens und bestimmen, ob die Array-Elemente für den 2./3. Rahmen für die entsprechenden aktuellen 2./3. Felder vorhanden sind oder nicht.