Фильтровать файл по значениям в столбцах другого файла - PullRequest
0 голосов
/ 10 мая 2018

У меня есть файл со списком позиций (столбцы 1 + 2) и значениями, связанными с этими позициями:

FILE1.TXT:

1 20   A   G
4 400  T   C
1 12   A   T
2 500  G   C

И еще один файл с одними и теми же позициями. Может быть несколько строк с такими же позициями, как в File1.txt

file2.txt

#CHR    POS       Count_A Count_C Count_G Count_T
1       20        0       18      2       0
4       400       0       0       0       1
1       12        0       7       0       40
4       400       0       1       0       1
5       50        16      0       0       0
2       500       9       0       4       0

Мне нужно вывести версию File1.txt, исключая все строки, которые когда-либо удовлетворяли обоим этим двум условиям:

1: если позиции (столбцы 1 + 2) совпадают в File1.txt и File2.txt 2: Если в столбце File2.txt указано число> 0, которое соответствует букве (A, G, C, T) в столбце 4 файла File1.txt для этой позиции.

Таким образом, для приведенного выше примера первая строка файла File1.txt не будет выводиться, поскольку в file2.txt для соответствующей строки (на основе первых 2 столбцов: 1 20) в 4-м столбце есть буква G, и для этого строка в File2.txt столбце Count_G> 0.

Единственная строка, которая будет выведена для этого примера, будет:

2 500 G C

Для меня особенно сложная часть заключается в том, что в file2.txt может быть несколько совпадающих строк, и я хочу исключить строки в File1.txt, если соответствующий столбец в File2.txt> 0 хотя бы в одной строке в File2. текст. Это означает, что в приведенном выше примере строка 2 файла File1.txt не будет включена, поскольку значение Count_C> 0 во второй раз, когда эта позиция появляется в файле File2.txt (Count_C = 1).

Я не уверен, возможна ли такая фильтрация за один шаг. Было бы проще вывести список строк в File1.txt, где счет в File2.txt для буквы в 4-м столбце в File1.txt> 0. Затем используйте этот список для сравнения с File1.txt и удалите все строки, которые появляются в обоих файлах?

Ранее я фильтровал один файл на основе значений в другом с помощью приведенного ниже кода, но это было, когда в файле file2.txt был только один столбец значений для фильтрации. Я не уверен, как выполнить условную фильтрацию, чтобы проверить правильный столбец на основании буквы в столбце 4 файла file1.txt

Мой текущий код написан на python, но приветствуется любое решение:

f2 = open('file2.txt', 'r')
d2 = {}
for line in f2.split('\n'):
    line = line.rstrip()
    fields = line.split("\t")
    key = (fields[0], fields[1])
    d2[key] = int(fields[2])

f1 = open('file1.txt', 'r')
for line in file1.split('\n'):
    line = line.rstrip()
    fields = line.split("\t")
    key = (fields[0], fields[1])
    if d2[key] > 1000:
        print line

Я думаю, что мое предыдущее решение уже очень многословно, и я чувствую, что мог бы быть простой инструмент для такого рода проблем, о которых я не знаю.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Ваш код кажется мне довольно хорошим. Вы можете, возможно, редактировать

d2[key] = int(fields[2])

и

if d2[key] > 1000:
        print line

Как они меня немного озадачили.

Я бы сделал это так:

f2 = open('file2.txt', 'r')
d2 = {}
for line in f2.split('\n'):
    fields = line.rstrip().split("\t")
    key = (fields[0], fields[1])
    d2[key] = {'A':int(fields[2]),'C':int(fields[3]),'G':int(fields[4]),
      'T':int(fields[5])}

f1 = open('file1.txt', 'r')
for line in f1.split('\n'):
    line = line.rstrip()
    fields = line.split("\t")
    key = (fields[0], fields[1])
    if (key not in d2) or (d2[key][str(fields[2])] == 0 and d2[key][str(fields[3])] == 0):
        print(line)

Edit: Если у вас есть произвольное количество букв (и столбцов в файле 2), просто обобщите словарь внутри d2, который я жестко закодировал. Легко. Давайте добавим 2 буквы:

col_names = ['A','C','G','T','K','L']

for a,i in zip(fields[2:],range(len(fields[2:]))):
    d2[key][col_names.index(i)] = a
0 голосов
/ 11 мая 2018

Я использовал Perl для решения проблемы.Во-первых, он загружает File2 в хеш-таблицу с ключами char, pos и нуклеотида, значение - это номер нуклеотида.Затем второй файл обрабатывается.Если в хеш-таблице есть ненулевое значение для его символа, pos и нуклеотида, оно не печатается.

#!/usr/bin/perl
use warnings;
use strict;

my %gt0;
open my $in2, '<', 'File2.txt' or die $!;
<$in2>;  # Skip the header.
while (<$in2>) {
    my %count;
    (my ($chr, $pos), @count{qw{ A C G T }}) = split;
    $gt0{$chr}{$pos}{$_} = $count{$_} for qw( A C G T );
}

open my $in1, '<', 'File1.txt' or die $!;
while (<$in1>) {
    my ($chr, $pos, undef, $c4) = split;
    print unless $gt0{$chr}{$pos}{$c4};
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...