Как преобразовать трехбуквенный код аминокислоты в однобуквенный код с помощью python или R?

У меня есть файл fasta, как показано ниже. Я хочу преобразовать трехбуквенный код в однобуквенный код. Как я могу сделать это с помощью python или R?

>2ppo
ARGHISLEULEULYS
>3oot
METHISARGARGMET

желаемый результат

>2ppo
RHLLK
>3oot
MHRRM

ваши предложения будут оценены!


person user1725152    schedule 06.10.2012    source источник
comment
Как ARGHISLEULEULYS преобразуется в RHLLK? Какова логика?   -  person    schedule 06.10.2012
comment
@Tichodroma: ARG = R, HIS = H, LEU = L и т. д.   -  person Junuxx    schedule 06.10.2012
comment
@Junuxx и т. д.? Было бы полезно добавить к вопросу полный список переводов или хотя бы ссылку на него. Я хотел бы помочь с этим вопросом, но я не могу, пока не получу всю необходимую информацию.   -  person    schedule 06.10.2012
comment
@Tichodroma: en.wikipedia.org/wiki/   -  person Junuxx    schedule 06.10.2012
comment
ах, так что вам нужно разбить строку на массив, чтобы каждый 3-й элемент массива был вашей последней строкой?   -  person caitriona    schedule 06.10.2012
comment
Как насчет: stat.ethz.ch/pipermail/bioconductor/2008-January /020958.html   -  person Ben Bolker    schedule 07.10.2012
comment
Мне любопытно, где вы нашли такой файл — я никогда не видел файла FASTA, в котором использовались бы такие трехбуквенные коды аминокислот.   -  person peterjc    schedule 07.12.2012


Ответы (11)


В BioPython уже есть встроенные словари, помогающие с такими переводами. Следующие команды покажут вам весь список доступных словарей:

import Bio
help(Bio.SeqUtils.IUPACData)

Предопределенный словарь, который вы ищете:

Bio.SeqUtils.IUPACData.protein_letters_3to1['Ala']
person Henk Neefs    schedule 05.01.2014
comment
Это должен быть выбранный ответ. Небольшое примечание: в Python3, по крайней мере, метод фактически находится в модуле Bio.Data, а Bio.SeqUtilis импортирует его оттуда, поэтому, если в текущем пространстве имен нужен только метод profile_letters_3to1, можно было бы сделать: from Bio.Data.IUPACData import protein_letters_3to1 - person Matteo Ferla; 10.06.2019

Используйте словарь для поиска однобуквенных кодов:

d = {'CYS': 'C', 'ASP': 'D', 'SER': 'S', 'GLN': 'Q', 'LYS': 'K',
     'ILE': 'I', 'PRO': 'P', 'THR': 'T', 'PHE': 'F', 'ASN': 'N', 
     'GLY': 'G', 'HIS': 'H', 'LEU': 'L', 'ARG': 'R', 'TRP': 'W', 
     'ALA': 'A', 'VAL':'V', 'GLU': 'E', 'TYR': 'Y', 'MET': 'M'}

И простая функция для сопоставления трехбуквенных кодов с однобуквенными кодами для всей строки:

def shorten(x):
    if len(x) % 3 != 0: 
        raise ValueError('Input length should be a multiple of three')

    y = ''
    for i in range(len(x)/3):
            y += d[x[3*i:3*i+3]]
    return y

Тестирование вашего примера:

>>> shorten('ARGHISLEULEULYS')
'RHLLK'
person Junuxx    schedule 06.10.2012
comment
Большое спасибо за ответ. Я новичок в питоне. Как я могу разобрать входной файл в ваш код? - person user1725152; 06.10.2012
comment
@ user1725152: Это зависит от формата входного файла. Но я думаю, что это может быть что-то вроде for line in inputfile: print(shorten(line)). - person Junuxx; 06.10.2012

Вот как это сделать в R:

# Variables:
foo <- c("ARGHISLEULEULYS","METHISARGARGMET")

# Code maps:
code3 <- c("Ala", "Arg", "Asn", "Asp", "Cys", "Glu", "Gln", "Gly", "His", 
"Ile", "Leu", "Lys", "Met", "Phe", "Pro", "Ser", "Thr", "Trp", 
"Tyr", "Val")
code1 <- c("A", "R", "N", "D", "C", "E", "Q", "G", "H", "I", "L", "K", 
"M", "F", "P", "S", "T", "W", "Y", "V")

# For each code replace 3letter code by 1letter code:
for (i in 1:length(code3))
{
    foo <- gsub(code3[i],code1[i],foo,ignore.case=TRUE)
}

Результаты:

> foo
[1] "RHLLK" "MHRRM"

Обратите внимание, что я изменил имя переменной, поскольку имена переменных не могут начинаться с цифры в R.

person Sacha Epskamp    schedule 06.10.2012
comment
Это нехорошо. Возьмите TRPHISGLU в качестве примера, вы ожидаете, что алгоритм будет преобразован следующим образом {TRP}{HIS}{GLU} -> WHE, но на самом деле с вашим алгоритмом происходит TRP{HIS}{GLU} -> TR{PHE} -> TRF . Вам нужно разбить foo на подстроки из трех символов, чтобы избежать таких возможных взаимодействий. - person flodel; 06.10.2012

>>> src = "ARGHISLEULEULYS"
>>> trans = {'ARG':'R', 'HIS':'H', 'LEU':'L', 'LYS':'K'}
>>> "".join(trans[src[x:x+3]] for x in range(0, len(src), 3))
'RHLLK'

Вам просто нужно добавить остальные записи в trans dict.

Изменить:

Чтобы сделать остальную часть trans, вы можете сделать это. Файл table:

Ala A
Arg R
Asn N
Asp D
Cys C
Glu E
Gln Q
Gly G
His H
Ile I
Leu L
Lys K
Met M
Phe F
Pro P
Ser S
Thr T
Trp W
Tyr Y
Val V

Прочтите это:

trans = dict((l.upper(), s) for l, s in
             [row.strip().split() for row in open("table").readlines()])
person John La Rooy    schedule 06.10.2012

Вы можете попробовать найти и установить Biopython, поскольку вы анализируете файл .fasta, а затем конвертируете его в однобуквенные коды. . К сожалению, в Biopython есть только функция seq3 (в пакете Bio::SeqUtils), которая делает обратное тому, что вы хотите. Пример вывода в IDLE:

>>>seq3("MAIVMGRWKGAR*")
>>>'MetAlaIleValMetGlyArgTrpLysGlyAlaArgTer'

К сожалению, нет функции 'seq1' (пока...), но я подумал, что это может быть полезно для вас в будущем. Что касается вашей проблемы, Junuxx прав. Создайте словарь и используйте цикл for, чтобы прочитать строку блоками по три и перевести. Вот функция, аналогичная той, которую он предоставил, которая является всеобъемлющей и также обрабатывает строчные буквы.

def AAcode_3_to_1(seq):
    '''Turn a three letter protein into a one letter protein.

    The 3 letter code can be upper, lower, or any mix of cases
    The seq input length should be a factor of 3 or else results
    in an error

    >>>AAcode_3_to_1('METHISARGARGMET')
    >>>'MHRRM'

    '''
    d = {'CYS': 'C', 'ASP': 'D', 'SER': 'S', 'GLN': 'Q', 'LYS': 'K',
     'ILE': 'I', 'PRO': 'P', 'THR': 'T', 'PHE': 'F', 'ASN': 'N', 
     'GLY': 'G', 'HIS': 'H', 'LEU': 'L', 'ARG': 'R', 'TRP': 'W', 'TER':'*',
     'ALA': 'A', 'VAL':'V', 'GLU': 'E', 'TYR': 'Y', 'MET': 'M','XAA':'X'}

    if len(seq) %3 == 0:
        upper_seq= seq.upper()
        single_seq=''
        for i in range(len(upper_seq)/3):
            single_seq += d[upper_seq[3*i:3*i+3]]
        return single_seq
    else:
        print("ERROR: Sequence was not a factor of 3 in length!")
person Wes Field    schedule 08.10.2012
comment
Вы сможете использовать Bio.SeqUtils.seq1 в следующем выпуске, Biopython 1.61 (или запускать из репозитория github, если хотите быть в авангарде). - person peterjc; 07.12.2012

У Biopython есть хорошее решение

>>> from Bio.PDB.Polypeptide import *
>>> three_to_one('ALA')
'A'

Для вашего примера я решу это одним вкладышем

>>> from Bio.PDB.Polypeptide import *
>>> str3aa = 'ARGHISLEULEULYS'
>>> "".join([three_to_one(aa3) for aa3 in [ "".join(g) for g in zip(*(iter(str3aa),) * 3)]])
>>> 'RHLLK'

Меня могут критиковать за такой лайнер :), но в глубине души я все еще люблю PERL.

person ghosh'.    schedule 18.06.2014

Использование R:

convert <- function(l) {

  map <- c("A", "R", "N", "D", "C", "E", "Q", "G", "H", "I",
           "L", "K", "M", "F", "P", "S", "T", "W", "Y", "V")

  names(map) <- c("ALA", "ARG", "ASN", "ASP", "CYS", "GLU", "GLN",
                  "GLY", "HIS", "ILE", "LEU", "LYS", "MET", "PHE",
                  "PRO", "SER", "THR", "TRP", "TYR", "VAL")

  sapply(strsplit(l, "(?<=[A-Z]{3})", perl = TRUE),
         function(x) paste(map[x], collapse = ""))
}

convert(c("ARGHISLEULEULYS", "METHISARGARGMET"))
# [1] "RHLLK" "MHRRM"
person flodel    schedule 06.10.2012
comment
+1 за умный метод разбиения строки на 3-символьные подстроки. Он демонстрирует кое-что интересное о том, как работает сопоставление регулярных выражений. - person Josh O'Brien; 07.10.2012
comment
@fodel Большое спасибо за ваш ответ. У меня более 1000 последовательностей. это в текстовом файле. Сначала я должен импортировать этот файл в r и изменить трехбуквенный код на одну букву. Я показал желаемый результат. Если вы можете, пожалуйста, помогите мне. - person user1725152; 07.10.2012
comment
Показанная мной функция принимает на вход вектор последовательностей. Как прочитать файл FASTA в вектор последовательностей в R — это другой вопрос. Быстрый поиск в Google, и я могу указать вам как минимум на три разных пакета: Biostrings (readFASTA), seqinr (read.fasta), bio3d (read.fasta). - person flodel; 07.10.2012

Другой способ сделать это — использовать seqinr и iPAC в пакете R.

# install.packages("seqinr")
# source("https://bioconductor.org/biocLite.R")
# biocLite("iPAC")

library(seqinr)
library(iPAC)

#read in file
fasta = read.fasta(file = "test_fasta.fasta", seqtype = "AA", as.string = T, set.attributes = F)
#split string
n = 3
fasta1 = lapply(fasta,  substring(x,seq(1,nchar(x),n),seq(n,nchar(x),n)))
#convert the three letter code for each element in the list 
fasta2 = lapply(fasta1, function(x) paste(sapply(x, get.SingleLetterCode), collapse = ""))

# > fasta2
# $`2ppo`
# [1] "RHLLK"
#
# $`3oot`
# [1] "MHRRM"
person paul_dg    schedule 28.08.2015

my %aa_hash=(
  Ala=>'A',
  Arg=>'R',
  Asn=>'N',
  Asp=>'D',
  Cys=>'C',
  Glu=>'E',
  Gln=>'Q',
  Gly=>'G',
  His=>'H',
  Ile=>'I',
  Leu=>'L',
  Lys=>'K',
  Met=>'M',
  Phe=>'F',
  Pro=>'P',
  Ser=>'S',
  Thr=>'T',
  Trp=>'W',
  Tyr=>'Y',
  Val=>'V',
  Sec=>'U',                       #http://www.uniprot.org/manual/non_std;Selenocysteine (Sec) and pyrrolysine (Pyl)
  Pyl=>'O',
);


    while(<>){
            chomp;
            my $aa=$_;
            warn "ERROR!! $aa invalid or not found in hash\n" if !$aa_hash{$aa};
            print "$aa\t$aa_hash{$aa}\n";
    }

Используйте этот perl-скрипт для преобразования триплетных кодов a.a в однобуквенный код.

person Kanhu charan Moharana    schedule 05.07.2013

Для тех, кто приземлится здесь в 2017 году и позже:

Вот однострочная команда Linux bash для преобразования трехбуквенного кода белковой аминокислоты в однобуквенный код в текстовом файле. Я знаю, что это не очень элегантно, но я надеюсь, что это поможет кому-то найти то же самое и захотеть использовать однострочную команду.

sed 's/ALA/A/g;s/CYS/C/g;s/ASP/D/g;s/GLU/E/g;s/PHE/F/g;s/GLY/G/g;s/HIS/H/g;s/HID/H/g;s/HIE/H/g;s/ILE/I/g;s/LYS/K/g;s/LEU/L/g;s/MET/M/g;s/ASN/N/g;s/PRO/P/g;s/GLN/Q/g;s/ARG/R/g;s/SER/S/g;s/THR/T/g;s/VAL/V/g;s/TRP/W/g;s/TYR/Y/g;s/MSE/X/g' < input_file_three_letter_code.txt > output_file_single_letter_code.txt

Решение исходного вопроса выше в виде одной командной строки:

sed 's/.\{3\}/& /g' | sed 's/ALA/A/g;s/CYS/C/g;s/ASP/D/g;s/GLU/E/g;s/PHE/F/g;s/GLY/G/g;s/HIS/H/g;s/HID/H/g;s/HIE/H/g;s/ILE/I/g;s/LYS/K/g;s/LEU/L/g;s/MET/M/g;s/ASN/N/g;s/PRO/P/g;s/GLN/Q/g;s/ARG/R/g;s/SER/S/g;s/THR/T/g;s/VAL/V/g;s/TRP/W/g;s/TYR/Y/g;s/MSE/X/g' | sed 's/ //g' < input_file_three_letter_code.txt > output_file_single_letter_code.txt

Объяснение:

[1] sed 's/.\{3\}/& /g' разделит последовательность. Это добавит пробел после каждой 3-й буквы.

[2] Вторая команда 'sed' в конвейере возьмет вывод выше и преобразует его в однобуквенный код. Добавьте любой нестандартный остаток как s/XYZ/X/g; к этой команде.

[3] Третья команда 'sed', sed 's/ //g', удалит пробелы.

person Insilico    schedule 07.11.2017

Решения Python 3.

В моей работе раздражает то, что коды аминокислот могут относиться к модифицированным кодам, которые часто появляются в файлах PDB/mmCIF, например

«Тих» -> «А».

Таким образом, отображение может быть более 22 пар. Сторонние инструменты в Python, такие как

Bio.SeqUtils.IUPACData.protein_letters_3to1

не могу справиться с этим. Мое самое простое решение — использовать http://www.ebi.ac.uk/pdbe-srv/pdbechem, чтобы найти сопоставление и добавить необычное сопоставление в dict в моих собственных функциях всякий раз, когда я с ними сталкиваюсь.

def three_to_one(three_letter_code):
    mapping = {'Aba':'A','Ace':'X','Acr':'X','Ala':'A','Aly':'K','Arg':'R','Asn':'N','Asp':'D','Cas':'C',
           'Ccs':'C','Cme':'C','Csd':'C','Cso':'C','Csx':'C','Cys':'C','Dal':'A','Dbb':'T','Dbu':'T',
           'Dha':'S','Gln':'Q','Glu':'E','Gly':'G','Glz':'G','His':'H','Hse':'S','Ile':'I','Leu':'L',
           'Llp':'K','Lys':'K','Men':'N','Met':'M','Mly':'K','Mse':'M','Nh2':'X','Nle':'L','Ocs':'C',
           'Pca':'E','Phe':'F','Pro':'P','Ptr':'Y','Sep':'S','Ser':'S','Thr':'T','Tih':'A','Tpo':'T',
           'Trp':'W','Tyr':'Y','Unk':'X','Val':'V','Ycm':'C','Sec':'U','Pyl':'O'} # you can add more
    return mapping[three_letter_code[0].upper() + three_letter_code[1:].lower()]

Другое решение - получить сопоставление онлайн (но URL-адрес и шаблон html могут меняться со временем):

import re
import urllib.request

def three_to_one_online(three_letter_code):
    url = "http://www.ebi.ac.uk/pdbe-srv/pdbechem/chemicalCompound/show/" + three_letter_code
    with urllib.request.urlopen(url) as response:
        single_letter_code = re.search('\s*<td\s*>\s*<h3>One-letter code.*</h3>\s*</td>\s*<td>\s*([A-Z])\s*</td>', response.read().decode('utf-8')).group(1)
    return single_letter_code

Здесь я напрямую использую re вместо парсеров html для простоты.

Надеюсь, это может помочь.

person Young    schedule 07.05.2018