#awk
#awk
Вопрос:
У меня есть два файла — файл один содержит число (1-22) в столбце 1 и диапазон от нижнего числа (столбец 2) и верхнего числа (столбец 3). Вот первая пара строк:
1 | 11362778 | 12362778 |
---|---|---|
1 | 22054176 | 23054176 |
1 | 28191734 | 29191734 |
1 | 42956767 | 43956767 |
1 | 65941329 | 66941329 |
У первого файла нет заголовка.
Во втором файле у меня много столбцов, первый из которых показан здесь:
SNP | CHR | BP |
---|---|---|
rs115828134 | 1 | 11363041 |
rs2788537 | 1 | 11363231 |
rs12141932 | 1 | 11363301 |
Что я хочу сделать, так это удалить все строки в файле 2, если столбец 2 в файле 2 равен столбцу 1 в файле 1, И если столбец 3 в файле 2 попадает в диапазон столбцов 2 и 3 в файле 2.
По сути, что-то вроде этого:, но перебирает все строки файла 1.
awk '{if($2==1 amp;amp; $3 < 11362778 || $3 > 12362778) print $0}' file 2 > results.txt
Ответ №1:
Я согласен на 100% с @jared_mamrot, используйте для этого надлежащие инструменты bioinfo.
Тем не менее, есть способ подойти к этому с помощью awk. Но обязательно протестируйте это на реальном наборе данных, прежде чем полагаться на него для серьезной науки, поскольку я не совсем уверен, охватывает ли он все угловые случаи, особенно в вашем ограниченном примере.
Данные (добавлены совпадающие данные):
$ cat file1
1 11362778 12362778
1 22054176 23054176
1 28191734 29191734
1 42956767 43956767
1 65941329 66941329
2 42956767 43956767
2 65941329 66941329
$ cat file2
SNP CHR BP
rs10875231 1 100000012
rs6678176 1 100000827
rs78286437 1 100000843
rr234233 1 29000000
rr453654 1 29000120
e34534534 1 23444444
rs144406489 1 100001138
rr564564 2 29000120
e34534534 2 23444444
rs144406489 2 42956775
Используйте:
$ awk 'NR==FNR{ chr[NR]=$1; x[NR]=$2; y[NR]=$3; en=NR }
NR!=FNR{ set=0;
for(i=1;i<=en;i ){
if(chr[i]==$2 amp;amp; ( $3 <= y[i] amp;amp; $3 >= x[i] ) ){
set=0; break
}
else{ set=1 }
}
if(set==1){ print }
}' file1 file2
Вывод:
SNP CHR BP
rs10875231 1 100000012
rs6678176 1 100000827
rs78286437 1 100000843
e34534534 1 23444444
rs144406489 1 100001138
rr564564 2 29000120
e34534534 2 23444444
Ответ №2:
Этот тип вопросов, зависящих от домена, лучше подходит для https://bioinformatics.stackexchange.com /
Сказав это, одним из возможных решений является преобразование второго файла в формат bed (такой же, как файл 1), а затем использование bedtools для выявления и исключения совпадений.
Сначала измените первую строку в file_1 так, чтобы координаты соответствовали записи в file_2, иначе вы не сможете увидеть, работает ли метод:
File_1.bed:
1 100000011 100000014
1 22054176 23054176
1 28191734 29191734
1 42956767 43956767
1 65941329 66941329
File_2.bed
# generated using
# awk 'NR>1 {print $2 "t" $3 "t" $3 "t" $1}' file_2 > file_2.bed
1 100000012 100000012 rs10875231
1 100000827 100000827 rs6678176
1 100000843 100000843 rs78286437
1 100001138 100001138 rs144406489
Используйте bedtools intersect для идентификации и удаления пересекающихся записей:
bedtools intersect -v -a file_2.bed -b file_1.bed
Вывод:
1 100000827 100000827 rs6678176
1 100000843 100000843 rs78286437
1 100001138 100001138 rs144406489
Комментарии:
1. Спасибо! Yup- bedtools работает, просто хочу иметь возможность записать его как awk
Ответ №3:
что-то подобное должно работать, но у вас нет проверяемого ввода, поэтому не проверено (нет перекрытия в диапазонах!).
$ awk 'NR==FNR {c[$1] ; b[$1,c[$1]]=$2; e[$1,c[$1]]=$3; next}
$2 in c {for(i=1;i<=c[$2];i )
if(b[$2,i]<$3 amp;amp; $3<e[$2,i]) next}1' file1 file2
также, пожалуйста, отправьте образец ввода, чтобы его можно было скопировать / вставить для удобства тестирования.
Использование примеров входных данных из ответа @AndreWildberg и конвейера column
дает
$ awk ... | column -t
SNP CHR BP
rs10875231 1 100000012
rs6678176 1 100000827
rs78286437 1 100000843
e34534534 1 23444444
rs144406489 1 100001138
rr564564 2 29000120
e34534534 2 23444444
Обратите внимание, что это должно работать немного быстрее, чем альтернатива, поскольку сканирование перекрытия ограничено только совпадающими кодами. В зависимости от вашего размера ввода он может быть незначительным или нет.
Комментарии:
1. Спасибо — Похоже, что он выполняет противоположное тому, что нужно, т.Е. печатает всю строку, которую я хочу удалить. Я обновил файл 2 выше
2. Я хотел бы, чтобы в файле отсутствовали области файла 1
3. Хорошо, я неправильно понял. Обновлено, чтобы пропустить вместо печати.