Gene ID Mapping
Gene identifiers are the sample-name problem’s harder cousin. The same gene appears as a
symbol (TP53), an Entrez ID (7157), an Ensembl ID (ENSG00000141510), an old alias
(HER2 for ERBB2), a retired symbol (SEPT2, renamed SEPTIN2 in 2020), or an Excel
date (2-Sep, which is what a spreadsheet made of SEPT2). Reconciling these is a
Bioconductor job, so this guide is R only. Python users reach for mygene / MyGene.info,
a network API, which is the closest equivalent.
Every code block runs in a container in the companion repository. HGNChelper and
org.Hs.eg.db run offline; biomaRt queries Ensembl live.
Fix messy symbols with HGNChelper
Section titled “Fix messy symbols with HGNChelper”checkGeneSymbols marks each symbol approved or not and suggests the current one. It
corrects case, resolves aliases, updates retired symbols, and reverses the Excel date
corruption. A /// in the suggestion means the corruption is ambiguous and a human has to
choose.
library(HGNChelper)
ids <- read.csv("../fixtures/gene_ids.csv")checkGeneSymbols(ids$symbol) x Approved Suggested.Symbol1 TP53 TRUE TP532 EGFR TRUE EGFR3 HER2 FALSE ERBB24 1-Mar FALSE MARCHF1 /// MTARC15 2-Sep FALSE SEPTIN2 /// SEPTIN66 SEPT2 FALSE SEPTIN2 /// SEPTIN6The Excel corruption is not a curiosity. Ziemann and colleagues found in 2016 that roughly
a fifth of papers with Excel gene lists in their supplements contained these errors, when a
spreadsheet silently turned SEPT2 and MARCH1 into dates. It is the reason HGNC formally
renamed the SEPT and MARCH gene families to SEPTIN and MARCHF in 2020. HGNChelper
carries a dated internal map, so the fix is reproducible offline.
Map IDs offline with org.Hs.eg.db
Section titled “Map IDs offline with org.Hs.eg.db”Once the symbols are clean, org.Hs.eg.db maps between identifier systems from a local
annotation database. No network, pinned to the image’s Bioconductor release, so the same
input always gives the same IDs.
library(AnnotationDbi)library(org.Hs.eg.db)
clean <- c("TP53", "EGFR", "ERBB2")data.frame( symbol = clean, entrez = mapIds(org.Hs.eg.db, keys = clean, column = "ENTREZID", keytype = "SYMBOL"), ensembl = mapIds(org.Hs.eg.db, keys = clean, column = "ENSEMBL", keytype = "SYMBOL"), row.names = NULL) symbol entrez ensembl1 TP53 7157 ENSG000001415102 EGFR 1956 ENSG000001466483 ERBB2 2064 ENSG00000141736Map IDs online with biomaRt
Section titled “Map IDs online with biomaRt”biomaRt does the same mapping from Ensembl directly, which you want when you need an
attribute the local database does not carry. The catch is reproducibility: the current
Ensembl release moves and the servers go down. Pin the query to a dated archive host, and
it returns the same answer every time.
library(biomaRt)
mart <- useEnsembl(biomart = "genes", dataset = "hsapiens_gene_ensembl", host = "https://oct2024.archive.ensembl.org")getBM(attributes = c("hgnc_symbol", "entrezgene_id", "ensembl_gene_id"), filters = "hgnc_symbol", values = clean, mart = mart) hgnc_symbol entrezgene_id ensembl_gene_id1 EGFR 1956 ENSG000001466482 ERBB2 2064 ENSG000001417363 TP53 7157 ENSG00000141510The offline and online results agree on every ID. Use org.Hs.eg.db for a fast,
reproducible mapping and biomaRt when you need something only Ensembl has, and pin the
archive so a rerun next year still matches the page.