生信喵 发表于 2025-11-30 20:03:21

识别转录因子及互作基因的关联

<h1>背景</h1>
<p>Enrichment for Molecular Concept Map, to identify significant association within lists of TF genes。</p>
<p>通过转录因子靶基因的集合,用Fisher's exact test分析转录因子间的coupling(耦合、共调控),在形式上模仿paper里的这种图来展示结果:</p>
<p><img src="https://tcapi.voiceclouds.cn:8444/uploads/2025/11/30/milnmymnvw8a9od6n9l.png" alt="" /></p>
<p>出自PMID: 27288520文章</p>
<h1>应用场景</h1>
<p>分析任意集合之间的关系,例如转录因子之间(示例数据)、差异表达基因跟通路之间、染色质开放跟基因转录之间。</p>
<p>场景一:找转录因子之间的耦合关系(共同调控靶基因),例如示例数据(Interactions.RData)是201个转录因子,以及每个转录因子对应的多个有相互作用的基因。</p>
<p>场景二:差异表达基因在通路里的富集,就把差异表达基因跟通路里的基因都放到Interactions.RData里。例如:</p>
<p>$up_regulated_genes<br />
&quot;ZBTB38&quot; &quot;SRA1&quot;   &quot;IPO13&quot;&quot;ALX4&quot;   &quot;EP300&quot;&quot;CREBBP&quot; &quot;IPO13&quot;</p>
<p>$MAPK_pathway<br />
&quot;ESR2&quot;   &quot;ZNF688&quot;   &quot;BANP&quot;   &quot;ISYNA1&quot;   &quot;TBC1D7&quot;</p>
<p>场景三:分析染色质开放程度跟基因转录调控之间的关系,就把ATAC-seq peak附近的基因跟差异表达基因都放到Interactions.RData里。例如:</p>
<p>$up_regulated_genes<br />
&quot;ZBTB38&quot; &quot;SRA1&quot;   &quot;IPO13&quot;&quot;ALX4&quot;   &quot;EP300&quot;&quot;CREBBP&quot; &quot;IPO13&quot;</p>
<p>$ATAC-seq_peak<br />
&quot;ESR2&quot;   &quot;ZNF688&quot;   &quot;BANP&quot;   &quot;ISYNA1&quot;   &quot;TBC1D7&quot;</p>
<h1>环境设置</h1>
<p>使用国内镜像安装包</p>
<pre><code class="language-r">options(&quot;repos&quot;= c(CRAN=&quot;https://mirrors.tuna.tsinghua.edu.cn/CRAN/&quot;))
options(BioC_mirror=&quot;http://mirrors.ustc.edu.cn/bioc/&quot;)
install.packages(&quot;rentrez&quot;)
</code></pre>
<p>加载包</p>
<pre><code class="language-{r}">library(rentrez)
library(RColorBrewer)
library(corrplot)
library(ggplot2)
library(ggthemes)
source(&quot;my_function.R&quot;)

Sys.setenv(LANGUAGE = &quot;en&quot;) #显示英文报错信息
options(stringsAsFactors = FALSE) #禁止chr转成factor
</code></pre>
<h1>输入文件</h1>
<p>如果你有自己的相互作用的基因list,保存在Interactions.RData里,就可以跳过这步,直接进入“Fisher's Exact Test”。</p>
<p>easy_input_TF.csv,此处用201个转录因子的gene symbol,可以替换成你感兴趣的基因的gene symbol,例如差异表达基因、差异表达lncRNA等。</p>
<p>easy_input_bg.csv,背景gene sybol,可以替换成与你感兴趣的基因相对应的背景基因,例如基因组上的全部基因、全部lncRNA等。</p>
<pre><code class="language-{r}">TFlist &lt;- read.csv(&quot;easy_input_TF.csv&quot;, header = T)
head(TFlist)
dim(TFlist)

bglist &lt;- read.table(&quot;easy_input_bg.csv&quot;, header = T)
head(bglist)
dim(bglist)
</code></pre>
<h2>从NCBI获取基因interaction</h2>
<p>用rentrez包获取NCBI gene数据库里的Interactions,即基因与它有相互作用的基因的list,保存到Interactions.RData。The general interactions in this section are provided, without review by Gene staff, by the external sources listed in https://ftp.ncbi.nlm.nih.gov/gene/GeneRIF/interaction_sources。详情看这里:https://www.ncbi.nlm.nih.gov/books/NBK3841/#EntrezGene.Interactions</p>
<pre><code class="language-r">#Download TF related interactions genes from NCBI Gene
#来源:https://github.com/ropensci/rentrez/wiki/Find-genes-known-to-interact-with-a-given-gene
res &lt;- c()
for (i in 1:nrow(TFlist)) {
output &lt;- print(as.character(TFlist$GeneSym),quote=FALSE)
gene_search &lt;- entrez_search(db=&quot;gene&quot;,term=paste0(&quot;(&quot;,output,&quot;) AND (Homo sapiens)&quot;))
# if you just want the interacting genes you can use this function, it's huge Xpath query
interactions_from_gene &lt;- function(gene_id){
   xmlrec &lt;- entrez_fetch(db=&quot;gene&quot;, id=gene_id, rettype=&quot;xml&quot;, parsed=TRUE)
   XML::xpathSApply(xmlrec,
                  &quot;//Gene-commentary]//Other-source]//Other-source_anchor&quot;,
                  XML::xmlValue)
   }
res1=interactions_from_gene(gene_search$ids)
res1=toupper(res1)
res1=list(res1)
names(res1)=output
res&lt;- c(res,res1)
}

save(res, file = &quot;Interactions.RData&quot;)
</code></pre>
<h1>Fisher's Exact Test</h1>
<p>Produce a geneset (lists) for hypergeometric test p-value</p>
<pre><code class="language-{r}">(load(&quot;Interactions.RData&quot;))
head(res)

# Match and filter geneset by background genelist list size range (number of genes) from 150 - 2000
# 也可以跳过这行,不做筛选
res1 &lt;- GeneSetsFilterByBackground(res,bglist$GeneSym,100,2000)
names(res1)
length(names(res1))

##########################################################
################# hypergeometric test ####################
##########################################################
# hyper and hyperTest function to caculate enrichment score and its pvalue by using hypergeometric test for each given genelist
# usage ## input 1. the list of GeneSet 2. length of background genes
# usage HyperGeoTest &lt;- hyperTest(GeneSet, length(background.genes))

hyper &lt;- function(X,Y,N,alpha=1){
K&lt;-length(X)
M&lt;-length(Y)

if(K==0 || M ==0){
    return(1)
}

both&lt;-length(intersect(X,Y));

XOnly&lt;-length(setdiff(X,Y));
YOnly&lt;-length(setdiff(Y,X));
Fisher.table&lt;-N-both-XOnly-YOnly;
tab&lt;-matrix(c(Fisher.table,YOnly, XOnly, both),2,2);
dimnames(tab)&lt;-list(0:1,0:1);
f&lt;-fisher.test(tab,alternative=&quot;greater&quot;);
pVal&lt;-f$p.value;
estimate&lt;-f$estimate;
return(c(pVal,estimate));
}

## s A list of gene vectors.
## N as a number to provide by using length (total background genes).
hyperTest&lt;-function(s, N, alpha=1){
n&lt;-length(s);
pVal&lt;-matrix(0,n,n);
estimate&lt;-matrix(0,n,n);
for(i in 1:n){
    print(paste(&quot;Processing&quot;, i));
    for(j in 1:n){
      h&lt;-hyper(s[],s[],N,alpha);
      pVal&lt;-h;
      estimate&lt;-h;
    }
}
dimnames(pVal)&lt;-list(names(s),names(s));
dimnames(estimate)&lt;-list(names(s),names(s));
return(list(pVal=pVal,estimate=estimate));
}

# hypergeometric test p-value
HyperGeoTest &lt;- hyperTest(res1, length(bglist$GeneSym))
rm(res1)

# Extract estimate value
est &lt;- HyperGeoTest$estimate
# Remove self comparing results
est = NA
head(est)

# Extract pvalue
p &lt;- HyperGeoTest$pVal
</code></pre>
<p>借用corrplot做clustring,为后面画图做准备</p>
<pre><code class="language-{r}"># set color
cols=rev(colorRampPalette(brewer.pal(9,&quot;RdBu&quot;))(199))
#cols=brewer.pal(n=9, name=&quot;RdBu&quot;)

p1 &lt;- corrplot(as.matrix(log2(est+1)),
         type = &quot;upper&quot;, #只显示上三角
         method=&quot;color&quot;,
         order=&quot;hclust&quot;,
         hclust.method=&quot;ward.D2&quot;,
         col=cols,
         tl.col =&quot;black&quot;, #文字颜色
         tl.cex = 0.5, #文字大小
         tl.srt =45, #Text label color and rotation
         is.corr = FALSE, #非相关系数矩阵。对于一般的矩阵,必须使用is.corr = FALSE
         diag = F,#不展示相关系数
         p.mat = as.matrix(p), #p值的矩阵
         sig.level = c(1e-25,1e-35,1e-50), #显著水平
         insig = c(&quot;label_sig&quot;), #显著水平以***、**、*表示
         pch.cex = 0.5, #标注的星号*的大小
         font = 3) #斜体
</code></pre>
<p><img src="https://tcapi.voiceclouds.cn:8444/uploads/2025/11/30/milny5vdrlght25t7ca.png" alt="" /></p>

生信喵 发表于 2025-11-30 20:03:44

<h1>开始画图</h1>
<p>作者提供了三种画法展示以上结果,这里展示画法一,画法二三见压缩包里的2_3_ggplot2.R文件</p>
<h2>准备工作</h2>
<p>前面用corrplot做了聚类,提取顺序;只需要画一半,也就是三角形,需要把另一半变成NA。</p>
<pre><code class="language-{r}"># Remove self comparing p vaule
# p =NA
p=NA #or p = NA
p &lt;- NA

# cluster ordering info by corrplot function
o &lt;- rownames(p1$corr)

# p value reordered by ward.D2 hclust
p &lt;- reorder(p, o)

# get -log10 fdr value
q &lt;- -log10(p.adjust(p, method=&quot;fdr&quot;))
# get -log10 p value
p &lt;- -log10(p)
head(p)

# estimate value reordered by ward.D2 hclust
o &lt;- rownames(p1$corr)
r &lt;- reorder(est,o)
r &lt;- NA
</code></pre>
<h2>画图</h2>
<pre><code class="language-{r}">pdf(&quot;Enrichment_baseplot.pdf&quot;, 11, 10)
par(bty=&quot;n&quot;,
    mar=c(4,4,4,8)+.1, #四周留空
    las=2,# the style of axis labels
    tcl=-.33) #The length of tick marks as a fraction of the height of a line of text

m &lt;- nrow(est)
n &lt;- ncol(est)

# we should check range(est[!est==Inf]) for col and breaks setting
# we should check data distribution hist(est[!est==Inf]) for col and breaks setting

max_value&lt;- range(r[!is.na(r)])
brks&lt;- c(0,seq(1,20,l=10),seq(21,max_value,l=4))
cols2&lt;- rev(colorRampPalette(brewer.pal(9,&quot;RdBu&quot;))(length(brks)-1))

# baseplot for heatmap
image(x=1:n, y=1:m, r, col=cols2, breaks=brks, xaxt=&quot;n&quot;, yaxt=&quot;n&quot;, xlab=&quot;&quot;,ylab=&quot;&quot;, xlim=c(0, n+4), ylim=c(0, n+1))

# add gene name
mtext(side=2, at=1:n, o, font=3, col=&quot;black&quot;) #left
mtext(side=3, at=1:n, o, font=3, col=&quot;black&quot;) #top

# add white border
abline(h=0:n+.5, col=&quot;white&quot;, lwd=.5)
abline(v=0:n+.5, col=&quot;white&quot;, lwd=.5)

# add title
#text(x=n/2, y=m+1, &quot;Enrichment based on Fisher's Exact Test (greater)&quot;, pos=3)

q_range&lt;- range(q[!is.na(q)])
# significant labels q&gt;50
w = arrayInd(which(q &gt; q_range/2), rep(m,2))
points(w, pch=&quot;*&quot;, col=&quot;black&quot;, cex=1)
# significant labels q&gt;35
w = arrayInd(setdiff(which(q &gt; q_range/3),which(q &gt; q_range/2)),rep(m,2))
points(w, pch=3, col=&quot;black&quot;, cex=1) # &quot;+&quot;&quot;
# significant labels q&gt;25
w = arrayInd(setdiff(which(q &gt; q_range/4),which(q &gt; q_range/3)), rep(m,2))
points(w, pch=&quot;-&quot;, col=&quot;black&quot;, cex=1)

# set up legend color bar
image(y = 1:16 +6, x=rep(n,2)+c(2.5,3)+1, z=matrix(c(1:16), nrow=1), col=cols2, add=TRUE)

# add legend color bar scale value
brks2 &lt;- round(c(0,seq(1,20,l=10), seq(21,max_value,l=4)))

axis(side = 4, at = seq(1,15) + 6.5,tcl=-.15, label=brks2, las=1, lwd=.5)

points(x=rep(n,3)+3.5, y=1:3, pch=c(&quot;-&quot;,&quot;+&quot;,&quot;*&quot;))
text(x=n+2, y=15, &quot;enrichment estimate value&quot;,pos=1,srt=90)
mtext(side=4, at=c(1,2,3,4), c(&quot;-log10(FDR) &gt; 25&quot;,&quot;-log10(FDR) &gt; 35&quot;,&quot;-log10(FDR) &gt; 50&quot;,&quot;ns&quot;), line=0.2)
dev.off()
</code></pre>
<p><img src="https://tcapi.voiceclouds.cn:8444/uploads/2025/11/30/milo6480a5m13tewz1e.png" alt="" /></p>

生信喵 发表于 2025-11-30 20:04:59

<p>文中所用数据可以关注公众号“生信喵实验柴”<br />
<img src="https://tcapi.voiceclouds.cn:8444/uploads/2025/09/07/mf9nu72s90ofyseu9hl.png" alt="" /><br />
发送关键词“20250510”获取</p>
页: [1]
查看完整版本: 识别转录因子及互作基因的关联