Ich habe eine Datei mit dem Namen, snp_data
dieSNP (Einzelnukleotid-Polymorphismus)Chromosomendaten. Dies ist eine 3-spaltige, durch Leerzeichen getrennte CSV-Datei im folgenden Format:
user@host:~$ cat snp_data
snp_id chromosome position
Chr01__912 1 912 1
Chr01__944 1 944 1
Chr01__1107 1 1107 1
Chr01__1118 1 1118 1
Chr01__1146 1 1146 1
Chr01__1160 1 1160 1
...
...
...
Chr17__214708367 17 214708367
Chr17__214708424 17 214708424
Chr17__214708451 17 214708451
Chr17__214708484 17 214708484
Chr17__214708508 17 214708508
Beachten Sie, dass das Feld für jede Zeile snp_id
die Form Chr{chromosome}__{position}
für die entsprechenden Werte von chromosome
und hat position
.
Ich habe eine weitere Datei mit dem Namen, window
die Zusatzdaten enthält. Dies ist eine 5-spaltige, durch Leerzeichen getrennte CSV-Datei, die das folgende Format hat:
user@host:~$ cat window
seqname chromosome start end width
1 Chr1 1 15000 15000
2 Chr1 15001 30000 15000
3 Chr1 30001 45000 15000
4 Chr1 45001 60000 15000
5 Chr1 60001 75000 15000
6 Chr1 75001 90000 15000
...
...
...
199954 Chr17 214620001 214635000 15000
199955 Chr17 214635001 214650000 15000
199956 Chr17 214650001 214665000 15000
199957 Chr17 214665001 214680000 15000
199958 Chr17 214680001 214695000 15000
199959 Chr17 214695001 214708580 13580
Beachten Sie die Entsprechung zwischen den window
und snp_data
Dateien, die durch den Wert des chromosome
Felds in der window
Datei und die Werte der chromosome
und snp_id
Felder in der snp_data
Datei bestimmt wird. Beispielsweise entsprechen Zeilen mit einem Wert von "Chr1"
in Zeilen in mit einem Wert von für und deren Zeilen mit dem Präfix beginnen .window
snp_data
1
chromosome
snp_id
Chr01__
Wenn für jede Zeile in der snp_data
Datei (jeder SNP innerhalb jedes Chromosoms) der Wert dieser Zeile position
innerhalb des durch die start
und end
Werte einer der Zeilen in window
für dieses bestimmte Chromosom vorgegebenen Bereichs liegt, hängen Sie die seqname
aus der window
Datei an die Zeile aus der snp_data
Datei an.
Für die oben angegebenen Eingaben wäre dies meine gewünschte Ausgabe:
user@host:~$ cat desired_output
snp_id chromosome position window
Chr01__912 1 912 1
Chr01__944 1 944 1
Chr01__1107 1 1107 1
...
...
...
Chr17__214708367 17 214708367 199959
Chr17__214708424 17 214708424 199959
Chr17__214708451 17 214708451 199959
Chr17__214708484 17 214708484 199959
Chr17__214708508 17 214708508 199959
Der Hauptpunkt ist, dass die Positionen nur innerhalb jedes Chromosoms eindeutig sind. Daher muss ich diese beiden Dateien Chromosom für Chromosom vergleichen (d. h. für jedes Chromosom separat). Wie kann ich das tun?
Antwort1
Hier ist ein Python-Skript, das das Gewünschte tun sollte:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""intersect_snp.py"""
import sys
# Read data from the SNP file into a list
snp_list = []
with open(sys.argv[1], 'r') as snp_file:
for line in snp_file:
snp_row = line.split()
snp_list.append(snp_row)
# Read data from the "window" file into a dictionary of lists
win_dict = {}
with open(sys.argv[2], 'r') as win_file:
for line in win_file:
seqnames, chromosome, start, end, width = win_row = line.split()
if chromosome not in win_dict:
win_dict[chromosome] = []
win_dict[chromosome].append(win_row)
# Compare data and compute results
results = []
# Iterate over snp data rows
for snp_row in snp_list:
# Extract the field values for each snp row
snp_id, chromosome, position = snp_row
# Convert the chromosome to match the format in the "window" file
# i.e. `1` -> `Chr1`
chromosome_name = "Chr{}".format(chromosome)
# Iterate over the "window" rows corresponding to that chromosome
for win_row in win_dict.get(chromosome_name, []):
# Extract the field values for each "window" row
seqnames, chromosome, start, end, width = win_row
# Perform the desired comparison
if int(start) <= int(position) <= int(end):
# If the comparison returns true, construct the result row
result = [snp_id, chromosome, position, seqnames]
results.append(result)
break
# Print the output column headers
columns = ["snp_id", "chromosome", "position", "window"]
print(" ".join(columns))
# Print the results
for row in results:
print(' '.join(row))
Beachten Sie, dass dieses Skript davon ausgeht, dass alle Ihre Zeilen Datenzeilen sind. Wenn Ihre Eingabedateien benannt sind snp_data
, window
können Sie es folgendermaßen ausführen:
python intersect_snp.py snp_data window
Wenn Ihre Dateien Kopfzeilen haben, können Sie tail
die Kopfzeilen überspringen/entfernen und es stattdessen folgendermaßen ausführen:
python intersect_snp.py <(tail -n+2 snp_data) <(tail -n+2 window)
Angenommen, dies ist Ihre snp_data
Datei:
snp_id chromosome position
Chr01__912 1 912
Chr01__944 1 944
Chr01__1107 1 1107
...
...
...
Chr17__214708367 17 214708367
Chr17__214708424 17 214708424
Chr17__214708451 17 214708451
Chr17__214708484 17 214708484
Chr17__214708508 17 214708508
Und dass dies Ihre window
Datei ist:
seqnames chromosome start end width
1 Chr1 1 15000 15000
2 Chr1 15001 30000 15000
3 Chr1 30001 45000 15000
4 Chr1 45001 60000 15000
5 Chr1 60001 75000 15000
...
...
...
199954 Chr17 214620001 214635000 15000
199955 Chr17 214635001 214650000 15000
199956 Chr17 214650001 214665000 15000
199957 Chr17 214665001 214680000 15000
199958 Chr17 214680001 214695000 15000
199959 Chr17 214695001 214708580 13580
Wenn wir dann diesen Befehl ausführen:
python intersect_snp.py <(tail -n+2 snp_data) <(tail -n+2 window)
Wir erhalten die folgende Ausgabe:
snp_id chromosome position window
Chr01__912 Chr1 912 1
Chr01__944 Chr1 944 1
Chr01__1107 Chr1 1107 1
...
...
...
Chr17__214708367 Chr17 214708367 199959
Chr17__214708424 Chr17 214708424 199959
Chr17__214708451 Chr17 214708451 199959
Chr17__214708484 Chr17 214708484 199959
Chr17__214708508 Chr17 214708508 199959
Antwort2
Um große Wartezeiten zu vermeiden, bietet sich hierfür die minimalistische SQL-Engine SQLite an, die unter Linux häufig vorinstalliert ist. Sie betreibt keinen Server und arbeitet mit SQL-Datenbanken, die in Dateien gespeichert sind.
Führen Sie in Ihrem snp_data- und Fensterverzeichnis Folgendes aus:
cat snp_data | tr -s " " > snp_data.csv
sed 's#Chr##g' window | tr -s " " > window.csv
Dadurch werden die Leerzeichen zwischen den Feldern normalisiert und für den Import vorbereitet.
Importieren Sie diese Daten dann in SQL und führen Sie die Abfrage aus, um die Ausgabe zu erhalten:
cat > task.sql
CREATE TABLE snp_data (snp_id text,chromosome int, position int);
CREATE TABLE window (seqname int,chromosome int, c_start int , c_end int, c_width int);
.mode csv
.separator " "
.import snp_data.csv snp_data
.import window.csv window
.mode column
.header on
SELECT D.snp_id, D.chromosome, D.position, W.seqname FROM snp_data D, window W WHERE W.chromosome=D.chromosome AND D.position BETWEN W.c_start AND W.c_end;
[STRG+D hier, um die Eingabe zu beenden]
Und schlussendlich:
cat task.sql | sqlite3 my_database.db
Im Allgemeinen sollte dies bei großen Dateien schneller sein.