Physics and Informatics/bioinformatics

bioinformatics: CCLE expression 데이터 gene symbol, entrez id로 찾기

Novelism 2023. 12. 25. 13:24

 

Cancer Cell Line Encyclopedia (CCLE) 는 천여개의 Cancer Cell line에 대해 copy number, sormatic mutation, expression 등을 수록한 데이터베이스 입니다. 지금은 DepMap (Dependency Map) 과 통합되었고, DepMap portal을 통해서 제공됩니다. DepMap은 Cancer Cell line의 gene knockout/knockdown 에 대한 세포 생장 변화 여부를 수록한 데이터베이스 입니다. 최신 공개 버전은 23Q4 입니다. 

https://depmap.org/portal/download/all/

포털에서 데이터를 그래프로 볼 수도 있고 다운로드를 할 수도 있습니다.

 

 protein coding genes에 대한 expression 값으로 RNAseq , log(TPM+1)  값을 열어보겠습니다. 

파일 이름은 

"OmicsExpressionProteinCodingGenesTPMLogp1.csv"

입니다.

 

import pandas as pd
file_name = "OmicsExpressionProteinCodingGenesTPMLogp1.csv"
df = pd.read_csv(file_name)
df.rename(columns={'Unnamed: 0': 'ModelID'}, inplace=True)
df.set_index('ModelID', inplace=True)

 

            TSPAN6 (7105)	TNMD (64102)	DPM1 (8813)	SCYL3 (57147)	C1orf112 (55732)	FGR (2268)	CFH (3075)	FUCA2 (2519)	GCLC (2729)	NFYA (4800)	...	H3C2 (8358)	H3C3 (8352)	AC098582.1 (8916)	DUS4L-BCAP29 (115253422)	C8orf44-SGK3 (100533105)	ELOA3B (728929)	NPBWR1 (2831)	ELOA3D (100506888)	ELOA3 (162699)	CDR1 (1038)
ModelID																					
ACH-001113	4.331992	0.000000	7.364660	2.792855	4.471187	0.028569	1.226509	3.044394	6.500005	4.739848	...	2.689299	0.189034	0.201634	2.130931	0.555816	0.000000	0.275007	0.0	0.000000	0.000000
ACH-001289	4.567424	0.584963	7.106641	2.543496	3.504620	0.000000	0.189034	3.813525	4.221877	3.481557	...	1.286881	1.049631	0.321928	1.464668	0.632268	0.000000	0.014355	0.0	0.000000	0.000000
ACH-001339	3.150560	0.000000	7.379118	2.333424	4.228049	0.056584	1.310340	6.687201	3.682573	3.273516	...	0.594549	1.097611	0.831877	2.946731	0.475085	0.000000	0.084064	0.0	0.000000	0.042644
ACH-001538	5.085340	0.000000	7.154211	2.545968	3.084064	0.000000	5.868390	6.165309	4.489928	3.956986	...	0.214125	0.632268	0.298658	1.641546	0.443607	0.000000	0.028569	0.0	0.000000	0.000000
ACH-000242	6.729417	0.000000	6.537917	2.456806	3.867896	0.799087	7.208478	5.570159	7.127117	4.568032	...	1.117695	2.358959	0.084064	1.910733	0.000000	0.000000	0.464668	0.0	0.000000	0.000000
...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...
ACH-000285	0.056584	0.000000	6.604368	3.266037	4.973152	0.411426	0.097611	0.704872	4.829850	5.178715	...	2.229588	0.084064	1.310340	3.039138	0.344828	0.000000	0.000000	0.0	0.475085	0.042644
ACH-002669	3.111031	0.000000	7.031329	1.541019	3.664483	0.014355	3.624101	6.805421	4.472488	4.397118	...	0.189034	0.400538	0.356144	1.327687	0.000000	0.000000	0.014355	0.0	0.000000	0.000000
ACH-001858	4.390943	0.000000	7.013239	1.887525	3.252476	0.028569	3.286881	6.902194	5.410748	3.401903	...	1.097611	0.400538	0.613532	1.992768	0.704872	0.000000	1.464668	0.0	0.000000	0.526069
ACH-001997	5.057450	0.000000	7.815191	2.538538	3.893362	0.028569	4.079805	6.971659	4.469886	3.463361	...	0.831877	0.847997	1.292782	2.153805	0.687061	0.000000	0.000000	0.0	0.000000	0.000000
ACH-000052	4.249445	0.000000	6.175724	2.319040	3.825786	0.189034	1.321928	3.538538	3.945795	4.469886	...	1.244887	1.207893	0.000000	1.956057	0.575312	0.042644	0.000000	0.0	0.176323	0.056584
1450 rows × 19193 columns

 

 CCLE 데이터베이스의 열은 "gene symbol (entrez ID)" 형태입니다.

 처음에는 Entrez ID가 표기되어서 번거롭게 생각했는데, gene symbol만으로는 정확한 유전자를 찾을 수 없다는 것을 알게된 후로 gene symbol 만 표기하는 것을 매우 꺼리게 되었습니다. 

 

그래도 검색할 때는 이 이름을 전부 입력하는것은 불편하죠. 

저는 보통 dict을 만들어서 사용합니다.

 

HGNC symbol이나 entrez ID를 key로 칼럼 이름을 연결합니다.

"OmicsExpressionProteinCodingGenesTPMLogp1.csv" 파일의 경우 entrez가 Unknown 인 경우가 없으니 굳이 if 문 부분이 꼭 필요하진 않지만,

"OmicsSomaticMutationsMatrixDamaging.csv" 파일의 경우

"DUSP27"
"PTPRD (Unknown)"

처럼 entrez 부분에 아무것도 표기되지 않거나,  Unknown 인 경우가 있습니다. 

이들중 일부는 entrez ID 가 있는데 잘못 연결된 경우도 있습니다. 

 

일단 테스트 코드입니다. 

gene_dict_symbol = dict()
gene_dict_entrez = dict()

for col in df.columns:
    lis = col.split(' ')
    gene_symbol = lis[0]
    if gene_symbol in gene_dict_symbol:
        print(col, gene_dict_symbol[gene_symbol])
    else:
        gene_dict_symbol[gene_symbol] = col
    if len(lis)==1:
        continue
    entrez0 = lis[1].strip('(').strip(')')
    if not entrez0.isnumeric():
        continue
    entrez = int(entrez0)
    if entrez in gene_dict_entrez:
        print(col, gene_dict_entrez[entrez])
    else:
        gene_dict_entrez[entrez] = col

그리고 출력은 

RLN1 (6013) RLN2 (6013)
BOLA2 (552900) BOLA2B (552900)
AC140504.1 (255027) MPV17L (255027)
LINC02210-CRHR1 (1394) CRHR1 (1394)
IQCJ-SCHIP1 (29970) SCHIP1 (29970)
AC092329.3 (440519) ZNF724 (440519)
AC131160.1 (55486) PARL (55486)
THSD8 (10535) RNASEH2A (10535)
AC022414.1 (8622) PDE8B (8622)
AP000812.4 (220074) LRTOMT (220074)
AC004593.2 (1124) CHN2 (1124)
AC090517.4 (54816) ZNF280D (54816)
AL160269.1 (11046) SLC35D2 (11046)
AC008770.4 (284391) ZNF844 (284391)
AL353579.1 (221468) TMEM217 (221468)
AL441992.2 (883) KYAT1 (883)
AC098582.1 (8916) HERC3 (8916)

입니다. gene symbol과 entrez ID가 잘못 연결된 것들이 있습니다. 

동인한 entrez ID에 여러 유전자가 매칭되어있는 경우들입니다. 

그래서 저는 딕셔너리를 만들기 전에, 유전자 이름을 먼저 수정합니다.

여기에 사용할 딕셔너리는 이전 포스팅 https://novelism.tistory.com/383 에서 작성하였습니다. 

 

def refine_ccle_data(df, gene_symbol_entrez_dict,gene_entrez_symbol_dict):
    gene_list= list(df.columns)
    duplication_list = list()
    mod_dict = dict()
    remove_list = list()
    g_col_dict = dict()
    for gene_col in gene_list:
        lis = gene_col.split(' ')
        symbol = lis[0]
        check_ee = False
        if len(lis)<2:
            check_ee = True
        else:
            tmp = lis[1].strip('(').strip(')')
            if tmp == 'Unknown':
                check_ee = True
            else:
                entrez_id = int(lis[1].strip('(').strip(')'))
        if check_ee:
            entrez_id = 'Unknown'
            if symbol in gene_symbol_entrez_dict:
                entrez_id0 = gene_symbol_entrez_dict[symbol]
                gene_col_new = '%s (%d)' %(symbol, entrez_id0)
                mod_dict[gene_col] = gene_col_new
            else:
                remove_list.append(gene_col)

        if entrez_id not in g_col_dict:
            g_col_dict[entrez_id] = gene_col
        else:
            if type(g_col_dict[entrez_id]) is list:
                g_col_dict[entrez_id].append(gene_col)
            else:
                gene_col0 = g_col_dict[entrez_id]
                g_col_dict[entrez_id] = [gene_col0, gene_col]
            if not check_ee:
                duplication_list.append(entrez_id)
            
    duplication_set = set(duplication_list)
    for entrez_id in sorted(duplication_set):
        zz = g_col_dict[entrez_id]
        for gene_col in zz:
            lis = gene_col.split(' ')
            symbol = lis[0]
            entrez_id0 = int(lis[1].strip('(').strip(')'))
            if symbol in gene_symbol_entrez_dict:
                entrez_id = gene_symbol_entrez_dict[symbol]
            else:
                remove_list.append(gene_col)
                continue
            if entrez_id in gene_entrez_symbol_dict:
                symbol_new = gene_entrez_symbol_dict[entrez_id]
            else:
                remove_list.append(gene_col)
                continue

            if entrez_id != entrez_id0:
                gene_col_new = '%s (%d)' % (symbol_new, entrez_id)
                mod_dict[gene_col] = gene_col_new
                
    df_refine = df.rename(columns=mod_dict,inplace=False)
    df_refine.drop(columns=remove_list,inplace=True)

    return df_refine, mod_dict, remove_list, g_col_dict
    
    
gene_id_file = '/gene_dict_symbol.tsv'
gene_id_list = [x.strip().split('\t') for x in open(gene_id_file)]
gene_symbol_entrez_dict = { x[0] : int(x[1].split('|')[0]) for x in gene_id_list}

gene_name_file = 'gene_dict_entrez.tsv'
df_gene_name = pd.read_csv(gene_name_file, sep='\t')
df_gene_name.set_index('Entrez_id', inplace=True)
gene_entrez_symbol_dict = df_gene_name.to_dict()['symbol']


results = refine_ccle_data(df, gene_symbol_entrez_dict,gene_entrez_symbol_dict)
df_refine, mod_dict, remove_list, g_col_dict = results

 

열이름이 변경된 데이터 프레임을 df_refine에 저장합니다. 

이전에 만든 gene symbol-entrez id 딕셔너리로부터 
잘못 매칭된 부분을 수정하고, entrez id를 채워넣습니다. 

최종적으로 entrez ID 가 매칭되지 않는 것들은 df에서 제외됩니다. 

gene_dict_symbol = dict()
gene_dict_entrez = dict()

for col in df_refine.columns:
    lis = col.split(' ')
    gene_symbol = lis[0]

    gene_dict_symbol[gene_symbol] = col
    gene_dict_entrez[entrez] = col

 

 

사용할 때는 

gene_symbol = 'EGFR'
col = gene_dict_symbol[gene_symbol]
df_refine[col]

이나, 

entrez_id = 1956
col = gene_dict_entrez[entrez_id]
df_refine[col]

같은 방식을 사용합니다.