10X單細(xì)胞(10X空間轉(zhuǎn)錄組)分析回顧之harmony的各種運(yùn)用(聯(lián)合NMF和python的harmonypy)

隔離的第八天履澳,孤獨(dú)的情緒漸漸消散了缓屠,音樂(lè)敌完,朋友羊初,親情长赞,還有游戲得哆,果然讓心情會(huì)變好很多,有位圣賢說(shuō)過(guò)栋操,其實(shí)人過(guò)的快不快樂(lè)饱亮,并不是說(shuō)我們擁有了房子近上,車子,還有和喜歡的姑娘在一起葱绒,而是良好的人際關(guān)系地淀,好了拒迅,這一篇我來(lái)詳細(xì)分享一下harmony的各種用法璧微,包括harmony與Seurat 的聯(lián)合使用,harmony與NMF的聯(lián)合使用胞得,以及python版本的harmonypy的運(yùn)用阶剑,我們一一來(lái)分享,希望大家有所收益素邪。

oytdd2r83q.png

1兔朦、R版本沽甥,harmony and Seurat乏奥,這個(gè)應(yīng)該是運(yùn)用的最多的,示例代碼如下:

library(Seurat)
library(harmony)
............前面的處理過(guò)程大家自己看一下就好

numsap=1
for (each in samples){
  pbmc <- readRDS(paste0(path,'/',each,'_QC.rds'))
    colnames(pbmc@assays$RNA@counts) <- str_replace_all(colnames(pbmc@assays$RNA@counts), '-1',paste0('-',numsap))
    ob <- CreateSeuratObject(counts =pbmc@assays$RNA@counts,project =each,min.cells = min_cells)
    ob$stim <-each
    ob <- NormalizeData(ob)
#  ob <- FindVariableFeatures(ob,  selection.method = "vst",nfeatures = Nfeatures)
    numsap=numsap+1
    ob.list[[each]] <- ob
}
outdir = myoutdir

seurat.obj = merge(x=ob.list[[1]], y=ob.list[[2]])

if(length(ob.list) > 2){
  for (j in 3:length(ob.list)){
    seurat.obj = merge(x=seurat.obj, y=ob.list[[j]])
  }
}


#Nfeatures=length(rownames(x =seurat.obj)) 盡量不要用所有基因跑
seurat.obj <- FindVariableFeatures(seurat.obj,  selection.method = "vst",nfeatures = Nfeatures)

seurat.obj<-ScaleData(seurat.obj,verbose = FALSE,split.by = 'orig.idents')

seurat.obj<-RunPCA(seurat.obj,pc.genes = seurat.obj@var.genes, npcs = cca_use, verbose = FALSE)

sample = compare

# run harmany batch correction
seurat.obj <- RunHarmony(seurat.obj,"stim", plot_convergence = TRUE)
harmony_embeddings <- Embeddings(seurat.obj, 'harmony')

harmony.data<-cbind(rownames(harmony_embeddings),harmony_embeddings)
colnames(harmony.data)[1]<-"Barcode"
write.table(harmony.data,file=paste0(outdir,'/Anchors/',prefix,'_harmony.csv'),row.names=F,col.names=T,sep=',',quote=F)

## run TSNE
seurat.obj = RunTSNE(seurat.obj, dims.use=1:cca_use, do.fast=TRUE, reduction.use="harmony")
# run UMAP
seurat.obj <- RunUMAP(seurat.obj, reduction = "harmony", dims = 1:cca_use,umap.method = "umap-learn",metric = "correlation")
seurat.obj <- FindNeighbors(seurat.obj, reduction = "harmony", dims = 1:cca_use)
seurat.obj <- FindClusters(seurat.obj, reduction.type = "harmony",resolution = resolution)

#saveRDS(seurat.obj,file=paste0(outdir,'/',prefix,'_combined.rds'))

需要注意的地方

  • 讀取的時(shí)候我這里寫(xiě)的是QC.rds,大家也可以讀矩陣,10X的結(jié)果文件等等痕鳍,不要拘泥于我寫(xiě)的方法笼呆。
  • RunHarmony的第二個(gè)參數(shù)我寫(xiě)了stim诗赌,其實(shí)就是樣本信息秸弛,這個(gè)分析因人而異递览,你的樣本信息保存在哪一列,你就寫(xiě)哪一列绞铃。
  • 示例代碼有一些參數(shù)用變量替代镜雨,如果大家做過(guò)單細(xì)胞,應(yīng)該都很容易理解儿捧。

好了荚坞,我們的第二部分挑宠,NMF and harmony

前段時(shí)間有位朋友說(shuō)NMF和harmony能不能聯(lián)合使用,答案是可以的颓影,這里展示一下示例代碼各淀,但是大家要知道哪些單細(xì)胞處理的分析軟件用到了NMF,當(dāng)然诡挂,我們分析一般使用基礎(chǔ)的NMF包就可以了,我們先來(lái)看看NMF如何與Seurat無(wú)縫銜接(這部分大家需要掌握):

library(Seurat)
library(tidyverse)
library(NMF)
rm(list = ls())

## 創(chuàng)建seurat對(duì)象
pbmc <- Read10X_h5("pbmc.h5")
pbmc <- CreateSeuratObject(pbmc, project = "pbmc", min.cells = 3, min.features = 500)
pbmc$percent.mt <- PercentageFeatureSet(pbmc, pattern = "^MT-")
pbmc <- subset(pbmc, percent.mt<20)
pbmc <- NormalizeData(pbmc) %>% FindVariableFeatures() %>% ScaleData(do.center = F)
## 高變基因表達(dá)矩陣的分解
# pbmc大體可分成T咆畏,B南捂,NK,CD14+Mono旧找,CD16+Mono溺健,DC,Platelet等類型钮蛛,考慮冗余后設(shè)置rank=10
vm <- pbmc@assays$RNA@scale.data
res <- nmf(vm, 10, method = "snmf/r", seed = 'nndsvd') 
runtime(res)
#    用戶     系統(tǒng)     流逝 
#1063.147   78.019 1139.831 

## 分解結(jié)果返回suerat對(duì)象
pbmc@reductions$nmf <- pbmc@reductions$pca
pbmc@reductions$nmf@cell.embeddings <- t(coef(res))    
pbmc@reductions$nmf@feature.loadings <- basis(res)  

## 使用nmf的分解結(jié)果降維聚類
set.seed(219)
pbmc.nmf <- RunUMAP(pbmc, reduction = 'nmf', dims = 1:10) %>% 
FindNeighbors(reduction = 'nmf', dims = 1:10) %>% FindClusters()
其中有個(gè)問(wèn)題鞭缭,為什么要用NMF?魏颓?
  • 對(duì)比PCA分析的結(jié)果岭辣,NMF雖然毫不遜色,但是它的運(yùn)行時(shí)間更長(zhǎng)甸饱,我們?yōu)槭裁匆肗MF呢沦童?一個(gè)很重要的原因是NMF的因子可解釋性更強(qiáng),每個(gè)因子貢獻(xiàn)度最大的基因基本代表了某種或某個(gè)狀態(tài)細(xì)胞的表達(dá)模式叹话,相比差異分析得到marker基因更有代表性偷遗。

接下來(lái)就是NMF 與 harmony的聯(lián)合使用,相信大家都已經(jīng)會(huì)寫(xiě)了驼壶,示例代碼放在這里:

library(Seurat)
library(tidyverse)
library(NMF)
rm(list = ls())

## 創(chuàng)建seurat對(duì)象
pbmc <- Read10X_h5("pbmc.h5")
pbmc <- CreateSeuratObject(pbmc, project = "pbmc", min.cells = 3, min.features = 500)
pbmc$percent.mt <- PercentageFeatureSet(pbmc, pattern = "^MT-")
pbmc <- subset(pbmc, percent.mt<20)
pbmc <- NormalizeData(pbmc) %>% FindVariableFeatures() %>% ScaleData(do.center = F)
## 高變基因表達(dá)矩陣的分解
# pbmc大體可分成T氏豌,B,NK热凹,CD14+Mono泵喘,CD16+Mono,DC般妙,Platelet等類型纪铺,考慮冗余后設(shè)置rank=10
vm <- pbmc@assays$RNA@scale.data
res <- nmf(vm, 10, method = "snmf/r", seed = 'nndsvd') 
runtime(res)
#    用戶     系統(tǒng)     流逝 
#1063.147   78.019 1139.831 

## 分解結(jié)果返回suerat對(duì)象
pbmc@reductions$nmf <- pbmc@reductions$pca
pbmc@reductions$nmf@cell.embeddings <- t(coef(res))    
pbmc@reductions$nmf@feature.loadings <- basis(res)  

seurat.obj <- RunHarmony(seurat.obj,"stim", plot_convergence = TRUE)
harmony_embeddings <- Embeddings(seurat.obj, 'harmony')

harmony.data<-cbind(rownames(harmony_embeddings),harmony_embeddings)

## 使用nmf的分解結(jié)果降維聚類
set.seed(219)
pbmc.nmf <- RunUMAP(pbmc, reduction = 'harmony', dims = 1:10) %>% 
FindNeighbors(reduction = 'nmf', dims = 1:10) %>% FindClusters()
####下游的處理都一樣了

但是這里注意一個(gè)問(wèn)題,harmony默認(rèn)是識(shí)別pca的股冗,如果出來(lái)slot報(bào)錯(cuò)霹陡,就用NMF的分析結(jié)果覆蓋掉PCA。

python版本的harmonypy

安裝的話很簡(jiǎn)單

pip install harmonypy

示例代碼
import pandas as pd
import numpy as np
from scipy.cluster.vq import kmeans
from scipy.stats.stats import pearsonr
import harmonypy as hm

meta_data = pd.read_csv("data/meta.tsv.gz", sep = "\t")
data_mat = pd.read_csv("data/pcs.tsv.gz", sep = "\t")
data_mat = np.array(data_mat)
vars_use = ['dataset']

# meta_data
#
#                  cell_id dataset  nGene  percent_mito cell_type
# 0    half_TGAAATTGGTCTAG    half   3664      0.017722    jurkat
# 1    half_GCGATATGCTGATG    half   3858      0.029228      t293
# 2    half_ATTTCTCTCACTAG    half   4049      0.015966    jurkat
# 3    half_CGTAACGACGAGAG    half   3443      0.020379    jurkat
# 4    half_ACGCCTTGTTTACC    half   2813      0.024774      t293
# ..                   ...     ...    ...           ...       ...
# 295  t293_TTACGTACGACACT    t293   4152      0.033997      t293
# 296  t293_TAGAATTGTTGGTG    t293   3097      0.021769      t293
# 297  t293_CGGATAACACCACA    t293   3157      0.020411      t293
# 298  t293_GGTACTGAGTCGAT    t293   2685      0.027846      t293
# 299  t293_ACGCTGCTTCTTAC    t293   3513      0.021240      t293

# [300 rows x 5 columns]

# data_mat[:5,:5]
#
# array([[ 0.0071695 , -0.00552724, -0.0036281 , -0.00798025,  0.00028931],
#        [-0.011333  ,  0.00022233, -0.00073589, -0.00192452,  0.0032624 ],
#        [ 0.0091214 , -0.00940727, -0.00106816, -0.0042749 , -0.00029096],
#        [ 0.00866286, -0.00514987, -0.0008989 , -0.00821785, -0.00126997],
#        [-0.00953977,  0.00222714, -0.00374373, -0.00028554,  0.00063737]])

ho = hm.run_harmony(data_mat, meta_data, vars_use)

# Write the adjusted PCs to a new file.
res = pd.DataFrame(ho.Z_corr)
res.columns = ['X{}'.format(i + 1) for i in range(res.shape[1])]
res.to_csv("data/adj.tsv.gz", sep = "\t", index = False)

# Test 2
########################################################################

import pandas as pd
import numpy as np
from scipy.cluster.vq import kmeans
from scipy.stats.stats import pearsonr
import harmonypy as hm

meta_data = pd.read_csv("data/pbmc_3500_meta.tsv.gz", sep = "\t")
data_mat = pd.read_csv("data/pbmc_3500_pcs.tsv.gz", sep = "\t")

from time import time

start = time()
ho = hm.run_harmony(data_mat, meta_data, ['donor'])
end = time()
print("elapsed {:.2f} seconds".format(end - start)) # 24 seconds for python, 5 seconds for Rcpp

res = pd.DataFrame(ho.Z_corr).T
res.columns = ['PC{}'.format(i + 1) for i in range(res.shape[1])]
res.to_csv("data/pbmc_3500_pcs_harmonized_python.tsv.gz", sep = "\t", index = False)

harm = pd.read_csv("data/pbmc_3500_pcs_harmonized.tsv.gz", sep = "\t")

cors = []
for i in range(res.shape[1]):
    cors.append(pearsonr(res.iloc[:,i].values, harm.iloc[:,i].values))
print([np.round(x[0], 3) for x in cors])

python版本的harmony是為了scanpy而準(zhǔn)備的,所以也是和scanpy無(wú)縫銜接烹棉,寫(xiě)法跟上面的R版本很一致攒霹,把scanpy對(duì)應(yīng)的信息給到harmony就可以了

import harmonypy as hm
import pandas as pd
import scanpy as sc

adata = adata = sc.read_10x_mtx(
    'data/filtered_gene_bc_matrices/hg19/',  # the directory with the `.mtx` file
    var_names='gene_symbols',                # use gene symbols for the variable names (variables-axis index)
    cache=True)    

###或者讀取其他格式的文件,包括h5ad浆洗,loom催束,csv,h5等伏社,看大家的需求抠刺,前面的質(zhì)控處理就不多說(shuō)了,直接做完pca摘昌,然后下一步:

ho = hm.run_harmony(adata.X, adata.obs, ['Sample'])

res = pd.DataFrame(ho.Z_corr)
res.columns = ['X{}'.format(i + 1) for i in range(res.shape[1])]
res.to_csv("data/adj.tsv.gz", sep = "\t", index = False)

###然后一樣速妖,把得到的信息添加到scanpy的分析對(duì)象就可以了

最后是python版本的NMF與harmony的聯(lián)合使用,就不多介紹了聪黎,大家應(yīng)該都會(huì)寫(xiě)了罕容。

生活很好,有你更好

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載稿饰,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者锦秒。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市喉镰,隨后出現(xiàn)的幾起案子旅择,更是在濱河造成了極大的恐慌,老刑警劉巖侣姆,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件生真,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡捺宗,警方通過(guò)查閱死者的電腦和手機(jī)汇歹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)偿凭,“玉大人,你說(shuō)我怎么就攤上這事派歌⊥淠遥” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵胶果,是天一觀的道長(zhǎng)匾嘱。 經(jīng)常有香客問(wèn)我,道長(zhǎng)早抠,這世上最難降的妖魔是什么霎烙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上悬垃,老公的妹妹穿的比我還像新娘游昼。我一直安慰自己,他們只是感情好尝蠕,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布烘豌。 她就那樣靜靜地躺著,像睡著了一般看彼。 火紅的嫁衣襯著肌膚如雪廊佩。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天靖榕,我揣著相機(jī)與錄音标锄,去河邊找鬼。 笑死茁计,一個(gè)胖子當(dāng)著我的面吹牛料皇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播簸淀,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼瓶蝴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了租幕?” 一聲冷哼從身側(cè)響起舷手,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎劲绪,沒(méi)想到半個(gè)月后男窟,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贾富,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年歉眷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颤枪。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡汗捡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出畏纲,到底是詐尸還是另有隱情扇住,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布盗胀,位于F島的核電站艘蹋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏票灰。R本人自食惡果不足惜女阀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一宅荤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浸策,春花似錦冯键、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至夫晌,卻和暖如春雕薪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晓淀。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工所袁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凶掰。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓燥爷,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親懦窘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子前翎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容