inferCNV:scRNA-seq数据推断染色体拷贝数变化

news2024/11/28 19:41:39

inferCNV分析简介

inferCNV用于探索肿瘤单细胞RNA-Seq 数据,以确定体细胞大规模染色体拷贝数改变的证据,例如整个染色体或大片段染色体的增益或缺失。这是通过与一组参考“正常”细胞(这里的正常细胞可自行定义)进行比较,探索肿瘤基因组各部位基因的表达强度来完成的。热图展示每个染色体的相对表达强度,并且与“正常”细胞相比,肿瘤基因组的哪些区域过表达或降低(异常)。

同时我们需要了解两个概念:拷贝数变异(Copy number variation, CNV)拷贝数改变(copy number alterations, CNA)

拷贝数改变(copy number alterations, CNA) :指的是基因组中的 DNA 片段在不同个体间的拷贝数存在变异。这些变异可以是片段的缺失(deletion)或扩增(duplication),并且这些片段通常较大,范围从 1 kb 到数 Mb 不等。

拷贝数改变(copy number alterations, CNA) :是指基因组中某些 DNA 片段的拷贝数发生变化,包括拷贝数的增加(扩增,amplification)和减少(缺失,deletion)。这些改变可以影响单个基因、多个基因甚至整个染色体区域, CNA 与CNV概念相似。

inferCNV分析的意义

我们对单细胞分析的时候会根据关键基因/标记进行细胞分群,基本上可以把大部分的细胞亚群给区分开来,但如果某些基因/标记广泛地存在于多种细胞亚群时,此时应进一步寻找其他的关键基因/标记进行区分,这种分析策略是“常规流程”。对于肿瘤细胞和正常细胞而言,我们常会遇到某些关键基因/标记在两者中均表达的情况(转录组水平),此时通过“常规流程”仍难以区分细胞的良恶性,因此换个角度来辅助区分良恶性细胞就显得尤为重要。

肿瘤细胞通常具有更多的CNV,而正常细胞则较为稳定,因此如果有一种工具能够可视化拷贝数变异的情况那么是不是就可以辅助鉴别良恶性细胞呢?基于这种情况inferCNV就应运而生了。

inferCNV分析结果详解

1、官方示例展示

图中的红色部分是References(Cells),也就是我们自行定义的对照(正常)细胞。这些对照细胞可以是相对于肿瘤细胞的正常细胞(癌与非癌),也可选用免疫细胞进行对照。

蓝色部分是Observations(Cells),也就是我们想要重点分析的细胞。

灰色部分是细胞的图注,上边的色块代表了对照细胞的情况,该图研究者纳入了Microglia/Macrophage和Oligodendrocytes(non-malignant)作为对照细胞,恶性细胞作为观察细胞。

红色方框部分代表的是分层聚类树,其中第一列色柱代表的是所有观察组细胞的分层聚类,第二列色柱则是与所提供输入的观察组细胞分类相对应。

第一列色柱根据分析时group_by_cluster参数设置的不同(True/False)会对结果产生差异:

如果group_by_cluster = FALSE ,意味着不按照研究者命名的cluster去分,换句话说就是第一列色柱是按照聚类树所切割成k_obs_groups分组的情况来表示树状图的细分。

如果group_by_cluster = TRUE ,左边的树状图是所有观察细胞的“线性连接”(树状图的根与每种类型的树状图的根相连,这导致它们都处于同一水平)。第一列色柱列是单一颜色,因为注释聚类时不使用k_obs_groups分组。

但实际函数中参数名称改成了cluster_by_groups,并且True/False的最终结果也对调过来了,这个可能跟R包更新了有关系,因此我个人意见是,只要看到第一条色柱是同一的颜色时,我们应当理解为不采用k_obs_groups分组,而当显示不同颜色时是采用了k_obs_groups分组。两种参数设置均可。

蓝色方框部分代表的是染色体的分组分别是从chr1-chr22,性染色体和线粒体染色体已经被过滤了。

红色蓝色箭头分别代表染色体区域扩增和染色体区域缺失(两者均为异常)。

按照箭头看向对照和观察组细胞,在红色箭头处代表了malignant_MGH36细胞群,这群细胞相比于观察组(蓝色箭头) 在chr1, 4, 19中存在更显著的染色体缺失,在chr11, 21中存在更显著的染色体扩增。同样的我们可以看其他的三群恶性细胞,也均存在不同区域的染色体拷贝数异常。

2、其他数据展示—正常/肿瘤样本

该结果显示1个正常样本作为对照组,10个肿瘤样本作为观察组。整体情况观察下来可以发现肿瘤组样本相比于对照组来说还是存在了很明显的染色体拷贝数异常。

红色方框中的第二列色柱是代表了P10肿瘤样本的信息,中间还混了一小部分的P05患者的信息,从聚类树分层后的色柱来看,P10肿瘤样本还可以进一步的细分为三群。

蓝色方框中的第二列色柱带了很多肿瘤样本的信息,但从聚类树分层后的色柱来看,这些肿瘤样本信息应当分成同一群。

同样的数据,修改了cluster_by_groups的值之后聚类树的图形出现了变化。在不按照k_obs_groups分组之后,主要根据每个样本内部的情况进行分组,我们可以明显发现不同样本内部也存在着很大的异质性(红色方框)。

3、其他数据展示—细胞亚群

该结果显示前期分析得到了17个细胞亚群,其中第15个亚群根据关键基因/标记推测认为可能是正常细胞群,因此通过inferCNV进行辅助分析判断第15个亚群是否是正常细胞群,从结果来看确实也符合正常细胞亚群的猜测。

而根据聚类树结果来看,k_obs_groups分组和细胞亚群分组一致。

在不按照k_obs_groups分组之后,我们可以明显发现很多细胞亚群之间没有十分明显的界限,也就是说这个结果提示我们在后续聚类的时候可以把很多细胞亚群合并成同一群。

inferCNV分析流程
1.加载对象和R包
rm(list = ls())
library(infercnv)
library(Seurat)
library(gplots)
library(ggplot2)
#这里加载的是seurat对象,替换自己的数据即可
load("sce_CNV_N_T.Rdata") 

#检查一下自己导入进来的数据
DimPlot(sce,reduction = 'umap',
        label = TRUE,pt.size = 0.5) +NoLegend()
2.读取数据
#根据需求去检查一下数据集的信息
table(Idents(sce))
table(sce@meta.data$seurat_clusters)
table(sce@meta.data$orig.ident)
#table(sce@meta.data$patient)
#table(sce@meta.data$ID)

# 文件制作1:表达量矩阵
# 除了用GetAssayData函数其实也可以直接sce@assays$RNA@count即可
dat <- GetAssayData(sce,
                    layer = 'counts',assay = 'RNA')
dat[1:4,1:4]

# 文件制作2:样本的描述
groupinfo <- data.frame(v1 = colnames(dat),
                        v2 = sce@meta.data$patient)

# 文件制作3:基因在染色体中的坐标
library(AnnoProbe)
#annoGene 函数返回一个数据框,包含输入基因的详细注释信息。
#注释信息可能包括基因名称、染色体位置、基因描述等。
geneInfor <- annoGene(rownames(dat),"SYMBOL","human") #物种需要小心哦
# 使用逻辑条件来移除包含 chrM, chrX, 和 chrY 的行
geneInfor <- geneInfor[!geneInfor$chr %in% c("chrM", "chrX", "chrY"), ]
#提取chr后后面的数字并转化为num,从而按这个num排序
#sub函数用于把chr替换为空
geneInfor$chr_num <- as.numeric(sub("chr", "", geneInfor$chr))
colnames(geneInfor)

#with函数的作用是简化写法,可问gpt
geneInfor <- geneInfor[with(geneInfor,order(chr_num,start)),c(1,4:6)]
geneInfor <- geneInfor[!duplicated(geneInfor[,1]),]

length(unique(geneInfor[,1]))
head(geneInfor)
3.排序一下
#保留行名在geneInfor第一列中存在的行。
dat <- dat[rownames(dat) %in% geneInfor[,1],]
#match(x, table):match函数返回x中每个元素在table中的位置索引。
#获得位置后对dat进行重新排序使其跟geneInfor中的顺序一致
dat <- dat[match(geneInfor[,1],rownames(dat)),]
#检查信息
dim(dat)
head(groupinfo)
dat[1:4,1:4]
table(groupinfo$v2)
dim(groupinfo)
4.保存/输出文件
#统一把”-“改成”_“,因为后续运行inferCNV的时候需要读取保存文档,若不修改则会出现错误。
#expFile:是一个变量,存储写入的文件的文件名或路径。在这里文件名是expFile.txt。
expFile <- 'expFile.txt' #定义输出文件名
colnames(dat) <- gsub("-", "_", colnames(dat))
write.table(dat, file = expFile, sep = '\t', quote = F)

#groupFiles:是一个变量,存储写入的文件的文件名或路径。在这里文件名是groupFiles.txt。
groupFiles <- 'groupFiles.txt'
groupinfo$v1 <- gsub("-", "_", groupinfo$v1)
write.table(groupinfo,file = groupFiles, sep = '\t',
            quote = F, col.names = F, row.names = F)

#geneFile:是一个变量,存储写入的文件的文件名或路径。在这里文件名是geneFile.txt。
head(geneInfor)
geneFile <- 'geneFile.txt'
write.table(geneInfor, file = geneFile, sep = '\t',
            quote = F, col.names = F, row.names = F)
5. inferCNV分析
#创建对象,请注意文件需要一一对应哦!
#ref_group_names 这里的细胞是正常对照,然后跟其他的细胞比较
infercnv_obj <- CreateInfercnvObject(raw_counts_matrix = expFile,
                                     annotations_file = groupFiles,
                                     delim = "\t",
                                     gene_order_file = geneFile,
                                     ref_group_names = c("N01")
)

infercnv_obj2 <- infercnv::run(infercnv_obj,
                               cutoff =  0.1, #smart-seq选择1,10X选择0.1
                               out_dir = "infercnv_output", # dir is auto
                               # 是否根据细胞注释文件的分组
                               # 对肿瘤细胞进行分组
                               # 影响read.dendrogram, 如果有多个细胞类型,且设置为TRUE,
                               # 后续的read.dendrogram无法执行
                               cluster_by_groups =  F, #是否根据患者类型(由细胞注释文件中定义)
                               hclust_method = "ward.D2",# ward.D2 方法进行层次聚类
                               analysis_mode = "samples", # 默认是samples,推荐是subclusters
                               denoise = TRUE, # 去噪音
                               HMM = F,  ##特别耗时间,是否要去背景噪音
                               plot_steps = F, #不在每个步骤后生成图形。
                               leiden_resolution = "auto", #可以手动调参数
                               num_threads = 4 #4线程工作,加快速度
                               )

接下来使用曾老师的方法去检查拷贝数变异的情况
6、读取数据加载R包
rm(list = ls())
options(stringsAsFactiors = F)
library(phylogram)
library(gridExtra)
library(grid)
require(dendextend)
require(ggthemes)
library(tidyverse)
library(Seurat)
library(infercnv)
library(miscTools)

load("sce_CNV_N_T.Rdata")
7、把inferCNV中的run.final.infercnv_obje文件读取进来
infer_CNV_obj<-readRDS('../3.inferCNV_N_T/infercnv_output/run.final.infercnv_obj')
expr <- infer_CNV_obj@expr.data
expr[1:4,1:4]
data_cnv <- as.data.frame(expr)
dim(expr)
colnames(data_cnv)
rownames(data_cnv)

#记得要改一下sce中的列名
colnames(sce) <- gsub("-","_",colnames(sce))
meta <- sce@meta.data
8、计算CNV并绘图
#要根据参数修改哦,我这里的对照组只有N01
if(T){
  tmp1 = expr[,infer_CNV_obj@reference_grouped_cell_indices$N01]
  tmp = tmp1
  #tmp2 = expr[,infer_CNV_obj@reference_grouped_cell_indices$`ref-2`]
  #tmp= cbind(tmp1,tmp2)
  down=mean(rowMeans(tmp)) - 2 * mean( apply(tmp, 1, sd))
  up=mean(rowMeans(tmp)) + 2 * mean( apply(tmp, 1, sd))
  oneCopy=up-down
  oneCopy
  a1= down- 2*oneCopy
  a2= down- 1*oneCopy
  down;up
  a3= up +  1*oneCopy
  a4= up + 2*oneCopy 
  
  cnv_score_table<-infer_CNV_obj@expr.data
  cnv_score_table[1:4,1:4]
  cnv_score_mat <- as.matrix(cnv_score_table)
  
  # Scoring
  cnv_score_table[cnv_score_mat > 0 & cnv_score_mat < a2] <- "A" #complete loss. 2pts
  cnv_score_table[cnv_score_mat >= a2 & cnv_score_mat < down] <- "B" #loss of one copy. 1pts
  cnv_score_table[cnv_score_mat >= down & cnv_score_mat <  up ] <- "C" #Neutral. 0pts
  cnv_score_table[cnv_score_mat >= up  & cnv_score_mat <= a3] <- "D" #addition of one copy. 1pts
  cnv_score_table[cnv_score_mat > a3  & cnv_score_mat <= a4 ] <- "E" #addition of two copies. 2pts
  cnv_score_table[cnv_score_mat > a4] <- "F" #addition of more than two copies. 2pts
  
  # Check
  table(cnv_score_table[,1])
  # Replace with score 
  cnv_score_table_pts <- cnv_score_mat
  rm(cnv_score_mat)
  # 
  cnv_score_table_pts[cnv_score_table == "A"] <- 2
  cnv_score_table_pts[cnv_score_table == "B"] <- 1
  cnv_score_table_pts[cnv_score_table == "C"] <- 0
  cnv_score_table_pts[cnv_score_table == "D"] <- 1
  cnv_score_table_pts[cnv_score_table == "E"] <- 2
  cnv_score_table_pts[cnv_score_table == "F"] <- 2
   
  cnv_score_table_pts[1:4,1:4]
  str(as.data.frame(cnv_score_table_pts[1:4,1:4])) 
  cell_scores_CNV <- as.data.frame(colSums(cnv_score_table_pts))
  
  colnames(cell_scores_CNV) <- "cnv_score" 
}

#可视化
head(cell_scores_CNV) 
score=cell_scores_CNV
head(score)
meta$totalCNV = score[match(colnames(sce),
                            rownames(score)),1] 
p <- ggplot(meta, aes(x= patient, 
                 y=totalCNV, 
                 fill=patient)) +
            geom_boxplot();print(p) 
ggsave("totalCNV.png",plot = p, width = 8,height = 6,dpi = 300)

补充资料:

官方说明

https://github.com/broadinstitute/inferCNV/wiki

技能树推文及B站视频

推文名称:肿瘤单细胞转录组拷贝数分析结果解读和应用

https://www.bilibili.com/video/BV19Q4y1R7cu/?spm_id_from=333.999.0.0&vd_source=3a13860df939bc922ad1fd6099e42c1d

致谢:感谢曾老师,小洁老师以及生信技能树团队全体成员(部分代码来源:生信技能树马拉松和数据挖掘课程)。

:若对内容有疑惑或者有发现明确错误的朋友,请联系后台(希望多多交流)。更多内容可关注公众号:生信方舟

- END -

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【STM32】输入捕获应用-测量脉宽或者频率(方法2)

链接&#xff1a;https://blog.csdn.net/gy3509/article/details/139629893?spm1001.2014.3001.5502&#xff0c;讲述了只使用一个捕获寄存器测量脉宽和频率的方法&#xff0c;其实测量脉宽和频率还有一个更简单的方法就是使用PWM输入模式&#xff0c;PWM输入模式需要占用两个…

Imagic: Text-Based Real Image Editing with Diffusion Models

Imagic: Text-Based Real Image Editing with Diffusion Models Bahjat Kawar, Google Research, CVPR23, Paper, Code 1. 前言 在本文中&#xff0c;我们首次展示了将复杂&#xff08;例如&#xff0c;非刚性&#xff09;基于文本的语义编辑应用于单个真实图像的能力。例如…

Java NIO ByteBuffer 使用方法

前言 最近在使用spring boot websocket xterm.js 给 k8s pod做了个在线的 web 终端&#xff0c;发现websocket的类核心方法&#xff0c;用的都是ByteBuffer传递数据&#xff0c;如下&#xff1a; OnMessagepublic void onMessage(Session session, ByteBuffer byteBuffer) {…

MySQL-分组函数

041-分组函数 重点&#xff1a;所有的分组函数都是自动忽略NULL的 分组函数的执行原则&#xff1a;先分组&#xff0c;然后对每一组数据执行分组函数。如果没有分组语句group by的话&#xff0c;整张表的数据自成一组。 分组函数包括五个&#xff1a; max&#xff1a;最大值mi…

智造新篇章:MicroAlign融资助推高精度FA技术革新

随着智能化浪潮的汹涌澎湃&#xff0c;全球制造业正经历着前所未有的技术革新。MicroAlign&#xff0c;一家专注于高精度功能组装&#xff08;FA&#xff09;技术的创新企业&#xff0c;近日宣布完成了高达100万欧元的种子轮融资。这一轮融资不仅为MicroAlign注入了加速商业化的…

java基于Vue+Spring boot前后端分离架构开发的一套UWB技术高精度定位系统源码

java基于VueSpring boot前后端分离架构开发的一套UWB技术高精度定位系统源码 系统采用UWB高精度定位技术&#xff0c;可实现厘米级别定位。UWB作为一种高速率、低功耗、高容量的新兴无线局域定位技术&#xff0c;目前应用主要聚焦在室内外精确定位。在工业自动化、物流仓储、电…

【产品经理】发票系统简述

一、发票类型 增值税电子普通发票&#xff1a;简称电票 增值税普通发票和增值税专用发票&#xff0c;简称&#xff1a;纸票 蓝票&#xff1a;开票金额为正值的发票。红票&#xff1a;发票金额为负值的发票。 注&#xff1a;专票电子化系统国家目前在推&#xff0c;后续有更新…

digit 手写数据库笔记 (机械学习)

参考书籍 第三章内容 digit 手写数据库 # 最初的分类器 # digits 手写数字库import numpy as np import matplotlib.pyplot as plt from sklearn import datasets from sklearn import tree # 性能评价相关的库 from sklearn import metrics# digits 数据加载 digits datase…

人工智能-机器学习算法是什么?

人工智能和机器学习是紧密相关的概念&#xff0c;可以说机器学习是人工智能的一个重要分支。机器学习是一门多学科交叉专业&#xff0c;涵盖概率论知识&#xff0c;统计学知识&#xff0c;近似理论知识和复杂算法知识&#xff0c;使用计算机作为工具并致力于真实实时的模拟人类…

一个小的画布Canvas页面,记录点的轨迹

Hello大家好&#xff0c;好久没有更新了&#xff0c;最近在忙一些其他的事&#xff0c;今天说一下画布canvas&#xff0c;下面是我的代码&#xff0c;实现了一个点从画布的&#xff08;0,0&#xff09;到&#xff08;canvas.width&#xff0c;canvas.height&#xff09;的一个实…

MYSQL数据库下载和安装(详细)

1.点击MySQL官网(后续照着图走) 2.软件下载完点击进入安装 设置要安装的路径然后点击OK,后面点击下一步 再点击下一步 MySQL推荐使用最新的数据库和相关客户端&#xff0c;mysql8换了加密插件&#xff0c;所以如果选第一种方式&#xff0c;很可能导致你的navicat等客户端连不上…

手把手教你,怎么用手机开发一个H5整蛊小游戏

前言&#xff1a; 相信在大家的认知里&#xff0c;做软件&#xff0c;做应用肯定都是通过电脑来进行开发的吧。但是你听说过用手机也可以开发软件吗&#xff1f;今天就教大家如何用手机轻松的开发出一款整蛊的H5小游戏。 首先我们需要借助一个工具CodeFlying&#xff0c;它能够…

为什么要分析电商用户数据?详解两大用户数据分析维度

零售电商行业的蓬勃发展带来了海量的客户数据&#xff0c;这些数据不仅记录了消费者的每一次点击、浏览、购买行为&#xff0c;还蕴含着巨大的商业价值。如何从这些数据中提炼出有价值的信息&#xff0c;成为电商企业提升竞争力、优化客户体验、实现可持续发展的关键。本文将深…

跟着AI学AI_08 NumPy 介绍

NumPy&#xff08;Numerical Python&#xff09;是一个用于科学计算的基础库&#xff0c;它为 Python 提供了支持大规模多维数组和矩阵 NumPy 介绍 NumPy&#xff08;Numerical Python&#xff09;是一个用于科学计算的基础库&#xff0c;它为 Python 提供了支持大规模多维数…

异常体系及自定义路径

异常( Exception) 定义&#xff1a; 异常代表程序出现的问题 图来自黑马程序员 分类&#xff1a; 运行时异常&#xff1a;RuntimeException以及其子类&#xff0c;编译阶段不会出现异常提醒&#xff0c;运行时出现的异常&#xff08;如数组越界异常&#xff09;编译时异常&am…

C++ 11 之 参数传递

c11参数传递.cpp #include <iostream> using namespace std;void swap1(int a, int b) {int temp a;a b;b temp;cout << "函数的a: " << a << endl;cout << "函数的b: " << b << endl; }void swap2(int *a,…

JUC并发编程第十一章——Synchronized与锁升级机制

1 入门知识介绍 synchronized锁&#xff0c;是不是默认实现了锁升级。代码中只需要直接使用synchronized&#xff0c;至于怎么从偏向锁升级为轻量锁再升级为重量级锁&#xff0c;这些底层jvm已经实现了。不需要程序员担心。 是的&#xff0c;Java 8中的synchronized关键字确实默…

为什么代理IP很难做到100%可用性?

在当今高度互联的网络环境中&#xff0c;代理IP已成为许多网络活动的重要支撑工具&#xff0c;从数据收集到业务推广&#xff0c;无所不包。然而&#xff0c;代理IP在很多场景中发挥着重要作用&#xff0c;却很难实现100%的可用性。 这种情况并非偶然&#xff0c;而是受到多重复…

如何给自己的项目实现在线测试的接口文档knife4j

配置实现Knife4j在线接口测试文档 为什么要是实现这个东西呢&#xff1f;肯定是对我们有用的&#xff0c;后端主要编写的就是接口&#xff0c;然后我们将接口编写好了之后肯定还是需要进行调试看是否能够正常使用且按照规范返回对应的数据。相信大家测试都是基本上使用的是一些…

JavaScript的数组(一维数组、二维数组、数组常用的方法调用)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…