轨迹分析:Palantir评估细胞分化潜能 类似于monocle2

轨迹分析是单细胞测序分析中重要的组成部分,它基于细胞谱系之间“具有中间态细胞”的理论基础,通过结合先验知识(细胞注释、markers)、细胞基因表达改变等,为在单细胞测序数据赋予了“假时间”(pseudotime)这一重要概念。基于pseudotime提供的时间维度,研究者得以进一步揭示细胞表型(phenotype)改变的连续过程,推断其中的基因调控机制。此前我们曾经写过几篇关于轨迹分析的推文,微信公众号:生信小博士

在pseudotime的概念之上,进一步通过算法衍生了“细胞分化潜能”或者“细胞干性”(Cell fate probabilities)等符合生物学常识的概念。例如,2020年发表在Science的CytoTRACE是一个简单但强有力的算法,它是基于每个细胞表达的基因数量,并利用这一转录多样性的度量来开发的计算框架。但是CytoTRACE也有一定的局限性,首先它是基于无监督的算法,非人为指定起点或终点,这就会导致算法出现错误的可能性,比如时序倒置,或一些显著背离生物学发展轨迹的方向。

说个题外话。有同学可能会提到,无监督的算法是否更能反映真实的改变情况,如果人为指定会不会出现过度干预或操纵的可能性。诚然,每一种算法或实验都有其局限性,但是目前关于有监督或无监督算法在单细胞各个研究领域中的应用都存在争议。就以最常见的降维分群注释为例,我们会看到越来越多基于有监督或半监督的聚类算法大放异彩,比如scANVI,以及各种单细胞图谱,他们的目的都是为了提供预先注释的信息以获得更加准确的注释。当然我个人并不懂算法开发,但先验知识与算法的有机结合呈现的优势无疑是巨大的,它能够避免一些无谓的、甚至离谱的错误出现。

Image

今天我们分享另一个基于Python的工具Palantir。该方法于近年发表在Nature Biotechnology上。与CytoTRACE不同,Palantir基于随机漫步的算法,将细胞命运视为概率事件来模拟不同分化轨迹,并利用熵来衡量轨迹上细胞的可塑性,从而生成高分辨率的假时间排序,并为每个细胞状态分配了分化到不同终端状态的概率(Cell fate probabilities)。

Image

环境配置

创建一个新的虚拟环境

conda create -n palantir python=3.8 -y
conda activate palantir

安装所依赖的python包,这里需要注意,palantir的最新版(1.3.1)可能会出现环境或配置错误,建议安装1.0.1版本。

pip install PhenoGraph
pip install rpy2
pip install palantir==1.0.1

配置kernel。

pip install ipykernel
# 配置jupyterlab内核
python -m ipykernel install --user --name=palantir --display-name palantir

加载Python包和全局设置

import palantir
import scanpy as sc
import numpy as np
import pandas as pd
import os

# Plotting 
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
import warnings

# Inline plotting
%matplotlib inline

sns.set_style('ticks')
matplotlib.rcParams['figure.figsize'] = [4, 4]
matplotlib.rcParams['figure.dpi'] = 100
matplotlib.rcParams['image.cmap'] = 'Spectral_r'
warnings.filterwarnings(action="ignore", module="matplotlib", message="findfont")

# Reset random seed
np.random.seed(5)

# 更换到相应的项目路径
os.chdir('path/to/project')

数据准备

官方提供的数据下载方式:

# Load sample data
data_dir = os.path.expanduser("./")
download_url = "https://dp-lab-data-public.s3.amazonaws.com/palantir/marrow_sample_scseq_counts.h5ad"
file_path = os.path.join(data_dir, "marrow_sample_scseq_counts.h5ad")
ad = sc.read(file_path, backup_url=download_url)
ad
# AnnData object with n_obs × n_vars = 4142 × 16106

如果你加载的是本地数据,或是整合的数据,需要明确的是:数据必须无批次信息或经过批次矫正。本次官方提供的数据只有一个样品,不存在批次效应。如果你用的是自己的数据,一定要系统评估批次效应。你也可以将上面的链接复制到浏览器窗口中下载。然后加载数据:

adata = sc.read_h5ad('marrow_sample_scseq_counts.h5ad')
adata
# AnnData object with n_obs × n_vars = 4142 × 16106

数据预处理:

# 计算线粒体基因比例
adata.var['mt'] = adata.var_names.str.startswith('MT-')
sc.pp.calculate_qc_metrics(adata, qc_vars=['mt'], percent_top=None, log1p=False, inplace=True)

# 简单过滤
sc.pp.filter_cells(adata, min_genes=200)
sc.pp.filter_genes(adata, min_cells=3)

adata = adata[adata.obs.n_genes_by_counts < 4000, :]
adata = adata[adata.obs.pct_counts_mt < 5, :]

# 高变基因
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
adata.raw = adata
adata = adata[:, adata.var.highly_variable]

# 归一化
sc.pp.regress_out(adata, ['total_counts', 'pct_counts_mt'])
sc.pp.scale(adata, max_value=10)

# PCA
# 如果你的是整合数据,应该使用 corrected PCA embedding
sc.tl.pca(adata, svd_solver='arpack')
sc.pl.pca(adata, color='CD34')

Image

根据Palantir官方的细胞注释信息,我们对细胞进行注释

sc.pp.neighbors(adata, n_neighbors=10, n_pcs=40)
sc.tl.umap(adata)
sc.pl.umap(adata, color=["CD34", "MPO", "GATA1", "IRF8"])

Image

细胞重命名

sc.tl.leiden(adata, resolution=0.5)
sc.pl.umap(adata, color='leiden') # 图就不展示了

# 这里我们使用字典进行重命名,以防止错乱,尤其是你的分类特别多的时候
# scanpy提供的解决方案是 adata.rename_categories()
celltype_dict = {
    '0':'HSC',
    '1':'Ery',
    '2':'Mono',
    '3':'Mono',
    '4':'Mono',
    '5':'DC',
    '6':'DC'
}
adata_rename = adata.copy()
adata_rename.obs['CellType'] = adata_rename.obs['leiden']

# 重命名
new_celltype = []
for subtype in adata_rename.obs['CellType']:
    new_subtype = celltype_dict.get(subtype, subtype)
    new_celltype.append(new_subtype)  
adata_rename.obs['CellType'] = pd.Categorical(new_celltype)

sc.pl.umap(adata_rename, color='CellType', frameon=False)

 

Diffusion Map和Force Directed Graph

可能很多做单细胞的小伙伴都没有接触过Diffusion Map(DM)和Force Directed Graph(FDG)这两个概念。这其中重要原因是Seurat和Scanpy提供在标准分析流程没有提及(实际上Scanpy有内置相应的函数)。这其实是非常重要的两个概念,很多高分文章的拟时序分析都应用了这两种降维方式。

Diffusion Map(扩散映射)和force directed graph(力导向图)是在单细胞研究中常用的数据可视化和降维方法。Diffusion Map是一种基于扩散过程的降维方法。它通过计算数据点之间的相似性和距离,构建一个扩散矩阵,然后对该矩阵进行特征值分解,得到数据的低维表示。Diffusion Map可以帮助发现数据中的潜在结构和关系,尤其适用于非线性数据。Force directed graph是一种可视化方法,用于展示数据点之间的关系和相互作用。在force directed graph中,数据点被表示为节点,而数据点之间的关系则通过边来表示。边的长度和弹簧力的大小根据数据点之间的相似性和距离进行调整,从而使得相似的数据点更加靠近,不相似的数据点则远离。通过调整边的长度和力的大小,可以得到一个具有良好可视化效果的图形。

在单细胞研究中,DM和FDG可以用于数据的可视化和降维。它们可以帮助研究人员理解和解释单细胞数据的结构和关系。通过应用DM,可以将高维的单细胞数据降低到较低的维度,从而更好地展示数据的特征和变化。而FDG可以将单细胞数据的相似性和关系以图形的形式展示出来,从而帮助研究人员发现细胞之间的相互作用和群落结构。

我们通过这个实例来看看他们有什么不同,以及为什么这两种降维方式适合做轨迹推断:

adata = adata_rename.copy()

# diffmap
sc.pp.neighbors(adata, n_neighbors=20, n_pcs=50, use_rep='X_pca', method='gauss')
sc.tl.diffmap(adata)

sc.pl.embedding(adata,'diffmap',color=['CellType','leiden'])

Image

在这里我们可以清晰地看到,以HSC为中间点,向不同轨迹分化的方向。但我们也发现,DC1实际上没有编码分化的轨迹信息,因此我们可以尝试删除掉DC1:

adata.obsm['X_diffmap_'] = adata.obsm['X_diffmap'][:,1:]
sc.pl.embedding(adata,'diffmap_',color=['CellType','leiden'])

Image

是不是有点Monocle内味了?但其实他们俩没啥关系。

我们再来看看FDG:

adata.obsm['X_diffmap'].shape
# (3821, 15)
sc.pp.neighbors(adata, n_neighbors=15, n_pcs=15, use_rep='X_diffmap')
sc.tl.draw_graph(adata)
sc.pl.draw_graph(adata, color=['CellType'])

Image

总体来说,需要根据实际情况选择用哪一种,DM的图形通常比较尖锐,而FDG更柔和。当细胞轨迹比较复杂多样时,DM通常会显得比较“紊乱”,这时候我们还可以这样来处理:

sc.pp.neighbors(adata, n_neighbors=10, n_pcs=10, use_rep='X_diffmap_')
sc.tl.umap(adata)
sc.pl.umap(adata,color='CellType')

Image

利用X_diffmap提供的embedding来替换PCA embedding,以获得更符合生物学轨迹的UMAP图。我们发现这个UMAP图更能把Mono和DC轨迹分开。此外,在上图中我们发现DC和Ery内部还有不同的分化方向。实际上基于先验知识的判断,它有一定的正确性,我们从下图的分化谱系中可以看到,DC细胞实际上有两个来源,其中一个是淋巴系分化出来,在UMAP表现为HSC直接分化得到,而另一个是由髓系分化,在UMAP图中表现为Monoctye分化而来。

Image

Palantir

Palantir可以认为提供root cell 和 terminal cells,我们回到Seurat中,利用CellSelector这个函数来精准选择细胞。

# anndata对象转换为h5这个通用格式
import diopy
diopy.output.write_h5(adata, 'diffmap.h5')

# Run in R
library(dior)
scobj = dior::read_h5('diffmap.h5')
scobj

Idents(scobj) = 'CellType'
p = DimPlot(scobj, reduction = 'diffmap_')
p

CellSelector(plot = p)
# 选择其中一个细胞
root.cell = 'Run4_130184147004718'
# 确认
DimPlot(scobj, cells.highlight = root.cell, reduction = 'diffmap_')

Image

接下来回到Python中

## Palantir需要基于PCA
pca_projections = pd.DataFrame(adata.obsm['X_pca'], index=adata.obs_names)
## Palantir内置了diffusion map函数
dm_res = palantir.utils.run_diffusion_maps(pca_projections, n_components=10)
# Determing nearest neighbor graph...
# computing neighbors
#     finished: added to `.uns['neighbors']`
#     `.obsp['distances']`, distances for each pair of neighbors
#     `.obsp['connectivities']`, weighted adjacency matrix (0:00:01)

dm_res['EigenVectors'].shape # embedding
# (3821, 10)

# Palantir内置函数帮助选择多少维DCs纳入分析
ms_data = palantir.utils.determine_multiscale_space(dm_res)
# 如果不选择:run me
# ms_data = dm_res['EigenVectors']

ms_data.shape
# (3821, 3)

运行:

# root cell
root_cell = 'Run4_130184147004718'
pr_res = palantir.core.run_palantir(ms_data, 
                                    early_cell=root_cell, 
                                    use_early_cell_as_start=True, 
                                    num_waypoints=500, knn=30)

获取信息和画图:

adata.obs['pseudotime'] = pr_res.pseudotime
adata.obs["DP"] = pr_res.entropy
sc.pl.embedding(adata, basis="umap", color=['pseudotime', 'DP'])

Image

DP即differential potential,通常与pseudotime呈反比。概念上与开头提到的“每个细胞状态分配了分化到不同终端状态的概率(Cell fate probabilities)”类似。结合先验知识,我们发现DP的结果与其生物学意义还是非常符合的。

此外,Palantir会提供自动计算的终点细胞名称。

pr_res.branch_probs.columns
# Index(['Run4_122436474493213', 'Run4_226265800857309', 'Run5_160996525231478'], dtype='object')

我们来看看这三个终点位置在哪里:

DimPlot(scobj,
        reduction = 'umap', 
        cells.highlight = c('Run4_122436474493213', 'Run4_226265800857309', 'Run5_160996525231478'))

Image

还是非常精确的!有时候如果觉得不满意,或者你还有其他希望人为指定终点的话,可以使用下面的例子。

我们再次从Seurat中选取终点细胞。假设我们希望针对DC潜在的另一个谱系分化进行研究。

DC_2 = 'Run4_236768101062563'

Image

terminal_cells = {
  "Run4_122436474493213": "Mono",
  "Run4_226265800857309": "Ery",
  "Run5_160996525231478": "DC1",
  "Run4_236768101062563": "DC2",
}
pr_res = palantir.core.run_palantir(ms_data, 
                                    early_cell=root_cell, 
                                    use_early_cell_as_start=True, 
                                    num_waypoints=500, 
                                    terminal_states=terminal_cells)
pr_res.branch_probs.columns = ['Mono','Ery','DC1','DC2']
pr_res.branch_probs.head()

Image

adata.obs['pseudotime'] = pr_res.pseudotime
adata.obs["DP"] = pr_res.entropy
sc.pl.embedding(adata, basis="umap", color=['pseudotime', 'DP'])

Image

可以看到,结果还是与之前类似,尽管我们指定了DC2终点,但Palantir没有按照我们指定的细胞强行拟合。我们看看branch probability结果:

Palantir计算出来的几个谱系的界限和路径都非常清晰。

我们保存一下Palantir其他重要结果:

with open("tmp/palantir_waypoint.txt", "w") as fo:
    [fo.write(cellID+"\n") for cellID in pr_res.waypoints.tolist()]

adata.obs.to_csv("tmp/palantir_results.csv")

导出为h5通用格式

diopy.output.write_h5(adata, 'palantir.h5')

小结

Palantir给我们提供了准确有效的拟时序信息和细胞干性评估,这对于后续分析至关重要,尤其是涉及细胞亚群表型转换的研究分析。如果你希望画出类似Slingshot的基因变化图,也可以参照之前我们分享过的笔记,利用Seurat和ggplot2画图体系来解决。事实上轨迹分析给我们添加了“时间”的维度,就会让很多事情变得有趣起来,就像3G网络变4G网络一样,以后我们再找时间继续分享轨迹分析的妙用吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/225042.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vscode eide arm-gcc 编译环境搭建调试

安装cube&#xff0c;vscode 1.安装vscode插件 C/C Extension Pack Chinese (Simplified) (简体中文) Language Pack Cortex-Debug Embedded IDE 工具链设置 2.软件工程生成 调试 3.生成工程&#xff0c;导入工程 4. 配置工程 编译完毕

【EI会议征稿】第五届大数据与信息化教育国际学术会议(ICBDIE 2024)

【往届检索】第五届大数据与信息化教育国际学术会议&#xff08;ICBDIE 2024&#xff09; 2023 5th International Conference on Big Data and Informatization Education 第五届大数据与信息化教育国际学术会议&#xff08;ICBDIE 2024&#xff09;定于2024年01月19-21日在…

小型洗衣机哪个牌子质量好?内衣洗衣机便宜好用的牌子

近些年来&#xff0c;由于人们对生活和健康的追求越来越高&#xff0c;所以内衣洗衣机也逐渐走进了人们的视线&#xff0c;许多研究显示&#xff0c;单纯地用手洗内衣是并不能彻底消除内衣物上所残留的细菌&#xff0c;而内衣洗衣机拥有着高温蒸煮的除菌功能&#xff0c;因此可…

【C语言】用户空间使用非缓存内存

在用户空间使用非缓存内存通常不是标准做法&#xff0c;因为非缓存内存的操作与硬件平台紧密相关&#xff0c;并且通常被保留给内核模块或设备驱动程序使用。 一、方法 用户空间程序一般不直接处理非缓存内存问题&#xff0c;因为它们依赖于操作系统来管理内存缓存一致性。尽…

智慧景区(园区)数字孪生可视化GIS解决方案

随着技术的日新月异&#xff0c;景区日常管理及运营中使用到的智慧化工具越来越丰富&#xff0c;智慧化硬件设备也越来越多&#xff0c;而其中各个管理系统往往又是相互独立&#xff0c;形成一个个数据孤岛。智慧景区管理平台就是将各个孤岛中的数据及功能汇集起来&#xff0c;…

叮!速来get宏基因组元素循环耦合分析!

微生物通过一系列氧化还原反应驱动生物地球化学循环&#xff0c;有的微生物可以耦合不同元素的生物地球化学循环&#xff0c;例如碳、氮、磷、硫等&#xff0c;存在复杂的耦合关系。 图 升高(A)和气候变暖(B)对氮库和转化过程影响的概念图 红树林生态系统被认为是生物地球化学…

Elasticsearch:什么是大语言模型(LLM)?

大语言模型定义 大语言模型 (LLM) 是一种深度学习算法&#xff0c;可以执行各种自然语言处理 (natural language processing - NLP) 任务。 大型语言模型使用 Transformer 模型&#xff0c;并使用大量数据集进行训练 —— 因此规模很大。 这使他们能够识别、翻译、预测或生成文…

HASH 哈希算法之MD5 算法

1. 哈希算法&#xff0c;用C 写的 #include <iostream> #include <iomanip> #include <cstring> #include <openssl/md5.h> #include <stdio.h>using namespace std;int main() {string str "hello world";unsigned char digest[MD5…

网络安全(一)--网络环境构成,系统的安全

2. 网络攻防环境 目标 了解攻防环境构成了解入侵检测系统&#xff08;平台&#xff09;的部署位置 2.1. 环境构成 2.1.1. 环境框图 一个基本的网络攻防实验环境包括&#xff1a;靶机、攻击机、入侵检测分析系统、网络连接四部分组成。 一个基础的网络攻防实验环境需要如下…

【c语言指针详解】指针的高级应用

目录 一、指针和字符串 1.1 字符串和字符数组的关系 1.2 字符串常量和字符指针的使用 1.3 字符串函数库的指针参数 1.3.1 strlen 函数 1.3.2 strcpy 函数 1.3.3 strcat 函数 1.3.4 strcmp 函数 二、指针的高级应用 2.1 函数指针的定义和使用 2.2 回调函数和函数指针数组的应用 …

2022年第十一届数学建模国际赛小美赛D题野生动物贸易是否应长期禁止解题全过程文档及程序

2022年第十一届数学建模国际赛小美赛 D题 野生动物贸易是否应长期禁止 原题再现&#xff1a; 野生动物市场被怀疑是此次疫情和2002年SARS疫情的源头&#xff0c;食用野生肉类被认为是非洲埃博拉病毒的一个来源。在冠状病毒爆发后&#xff0c;中国最高立法机构永久性地加强了野…

基于SpringBoot的大学活动平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着互联网技术的不断…

如何统计12.5米高程覆盖率?

无论是卫星影像还是高程DEM数据&#xff0c;覆盖率都是大家非常关心的一个重要参数。 我们曾基于WGS84坐标进行过简单的覆盖率计算&#xff0c;而且面积还包括了海洋区域。 因此&#xff0c;最后得出了一个非常不靠谱&#xff0c;看起来也很不漂亮的数据&#xff1a;12%。 为…

【算法】对二分搜索的理解

二分搜索大家都很熟悉&#xff0c;首先我们先来看看基本框架 func binarySearch(nums []int, target int) int {left, right : 0, ...for ... {mid : left (right-left)/2if nums[mid] target {...} else if nums[mid] < target {left ...} else if nums[mid] > targ…

快速安装Axure RP Extension for Chrome插件

打开原型文件的html&#xff0c;会跳转到这个页面&#xff0c;怎么破&#xff1f; 我们点开产品设计的原型图如果没有下载Axure插件是打不开&#xff0c;而我们国内网通常又不能再google商店搜索对应插件&#xff0c;下面教大家如何快速安装 1、打开原型文件->resources-&g…

星钻图形输出

答案&#xff1a; #include <stdio.h> int a 0, b 0; void printLine(int a , int b) //输出一行包含&#xff1a;若干个空格 若干个*&#xff0c;第一&#xff0c;二个参数为空格数和*数&#xff1b; (定义一个星钻输出函数) {while (a--) //打印a个空格{printf(…

内衣洗衣机和手洗哪个干净?高性价比内衣洗衣机推荐

通常来说&#xff0c;我们的内衣裤对卫生要求比较高&#xff0c;毕竟是贴身穿的&#xff0c;所以如果和一般的衣物一起洗&#xff0c;就怕会有细菌互相感染。所以很多用户为了内衣裤的卫生都会选择自己手动洗&#xff0c;但手洗一方面很费时间和人力&#xff0c;另一方面又很伤…

el-menu标题过长显示不全问题处理

项目基于vue-element-admin 问题 期望 处理方式 \src\layout\components\Sidebar\index.vue 文件后添加CSS <style scped> /* 侧栏导航菜单经典 文字超长溢出问题 CSS折行 */ .el-submenu__title {display: flex;align-items: center; } .el-submenu__title span {white-…

刚毕业做前端开发难度会很大吗

这里是up主的三段经历&#xff0c;小伙伴们可以自己看一看 首先可以确定的是&#xff0c;不是很大&#xff0c;因为如果你能走到做开发这一步去&#xff0c;说明你的基础能力是够硬的 我的第一段经历&#xff0c;也就是我的第一份实习&#xff0c;是一家小企业&#xff0c;一共…

单片机第三季-第六课:STM32标准库

1&#xff0c;为什么会有标准外设库 传统单片机软件开发方式&#xff1a; (1)芯片厂商提供数据手册、示例代码、开发环境&#xff1b; (2)单片机软件工程师面向产品功能&#xff0c;查阅数据手册&#xff0c;参考官方示例代码进行开发&#xff1b; (3)硬件操作的方式是用C语言…