CNS文章代码学习(一)Immunity 三级淋巴结构

目录

一:样本情况

二:GEO数据处理

三:代码学习

①00_visium_preprocessing.R

②01_MCP_counter.R

第一步 把组织学的注释(用10X的Loup Browser)添加到metadata中

第二步 绘图

第三步 是一个整合 批量绘制所有的图?

③TLS_imprint_signature

原理:Leave-one-out

原理:ROC & AUC

原理:将数据输入ROCit包

 文献代码

对上述代码进行可视化

绘制差异基因火山图

 BOXPLOT AUC的箱装图

④展示TLS_imprint_signature和其它marker关系



一:样本情况

 主要学习对空间转录组的样本处理

二:GEO数据处理

Visium数据的读取若想使用标准读取

格式必须与下面完全一致才可以用标准读取

Seurat::Load10X_Spatial("GSM5924042_frozen_a_1_fuvben/outs")

outs文件夹下应该有以下内容:

spatial文件下(spatial文件夹不可以省略)

注意所有的名字必须一样,不可以带有样本编号等信息,否则难以读取;GEO下载的数据多不标准,需要自己整理成spatial Ranger处理后的标准结果

三:代码学习

①00_visium_preprocessing.R

整理所有样本到指定位置

files <- list.files() #设置路径,然后展示所有文件
[1] "code"                                                  "GSE175540_batch_corrected_bulk_RNA_seq_TPM_25_02_22.csv"
 [3] "GSM5924030_ffpe_c_2"                                     "GSM5924031_ffpe_c_3"                                    
 [5] "GSM5924032_ffpe_c_4"                                     "GSM5924033_ffpe_c_7"                                    
 [7] "GSM5924034_ffpe_c_10"                                    "GSM5924035_ffpe_c_20"                                   
 [9] "GSM5924036_ffpe_c_21"                                    "GSM5924037_ffpe_c_34"                                   
[11] "GSM5924038_ffpe_c_36"                                    "GSM5924039_ffpe_c_39"                                   
[13] "GSM5924040_ffpe_c_45"                                    "GSM5924041_ffpe_c_51"                                   
[15] "GSM5924042_frozen_a_1"                                   "GSM5924043_frozen_a_3"                                  
[17] "GSM5924044_frozen_a_15"                                  "GSM5924045_frozen_a_17"                                 
[19] "GSM5924046_frozen_b_1"                                   "GSM5924047_frozen_b_7"                                  
[21] "GSM5924048_frozen_b_13"                                  "GSM5924049_frozen_b_18"                                 
[23] "GSM5924050_frozen_c_2"                                   "GSM5924051_frozen_c_5"                                  
[25] "GSM5924052_frozen_c_23"                                  "GSM5924053_frozen_c_57"                                 
[27] "RCC_immunity_Tertiary_lymphoid.Rproj" 

slide_list <-files[3:26] #全部空间样本 24个
slide_list_test <- slide_list[1:3] #取随意3个测试代码


正式代码 附带拆解学习

system.time({  #确定运行时间
spatial_list <- sapply(slide_list_test,function(slide){  #一个sapply函数,对slide_list_test中的每一个元素应用自创函数slide
  print(slide)
  raw_data_directory <- paste0("/data/ybk/GEO/STvisium/RCC_immunity_Tertiary_lymphoid/",slide,"/outs/")
  spatial_object <- Seurat::Load10X_Spatial(raw_data_directory) #标准读取
  
  # Collect all genes coded on the mitochondrial genome 找到线粒体基因再计算其比例
  mt.genes <- grep(pattern = "^MT-", x = rownames(spatial_object), value = TRUE) 
  spatial_object$percent.mito <- (Matrix::colSums(spatial_object@assays$Spatial@counts[mt.genes, ])/Matrix::colSums(spatial_object@assays$Spatial@counts))*100
  
  #remove mt genes 移除线粒体基因
  genes_to_keep <- setdiff(names(which(Matrix::rowSums(spatial_object@assays$Spatial@counts )>5)),mt.genes)
  
  #QC去掉些spots和gene
  spatial_object_subset <- subset(spatial_object,features =genes_to_keep, subset = nFeature_Spatial > 300 & percent.mito < 30)
  cat("Spots removed: ", ncol(spatial_object) - ncol(spatial_object_subset), "\n")
  cat("Genes kept: ", length(genes_to_keep),"from",nrow(spatial_object), "\n") 
  
  #使用SCT的标准化(详见Seurat)
  spatial_object_subset <- SCTransform(spatial_object_subset, 
                                       assay = "Spatial", 
                                       verbose = T)
  
  #compute mcp scores计算MCP的score,使用SCT后的数据
  mcp_scores <- MCPcounter.estimate(spatial_object_subset[["SCT"]]@data,featuresType = "HUGO_symbols")
  rownames(mcp_scores) <- make.names(rownames(mcp_scores))#把MCPcounter的type名中间的空格去掉
  cell_types <- rownames(mcp_scores) #就是各种T Bcell
  for(cell_type in cell_types){   #for循环写入meta信息
    spatial_object_subset <- AddMetaData(object= spatial_object_subset,metadata = mcp_scores[cell_type,],col.name = cell_type)
  }
  # Unsupervised analysis 
  spatial_object_subset <- RunICA(spatial_object_subset, assay = "SCT", verbose = FALSE) #这里用ica降维;Seurat官方用的是pca
  spatial_object_subset <- FindNeighbors(spatial_object_subset, reduction = "ica")
  spatial_object_subset <- FindClusters(spatial_object_subset, verbose = FALSE,resolution = 0.4)
  spatial_object_subset <- RunUMAP(spatial_object_subset, reduction = "ica", dims = 1:30)
  return(spatial_object_subset)
  })    #“{”是function的;“)”是sapply的
}) #system.time

# user  system elapsed 可以看到3个样本也运行了十分钟
# 341.571  15.858 625.920 

查看一下结果

spatial_list
# $GSM5924030_ffpe_c_2
# An object of class Seurat 
# 32170 features across 4482 samples within 2 assays 
# Active assay: SCT (16085 features, 3000 variable features)
# 1 other assay present: Spatial
# 2 dimensional reductions calculated: ica, umap
# 1 image present: slice1
# 
# $GSM5924031_ffpe_c_3
# An object of class Seurat 
# 31116 features across 4754 samples within 2 assays 
# Active assay: SCT (15558 features, 3000 variable features)
# 1 other assay present: Spatial
# 2 dimensional reductions calculated: ica, umap
# 1 image present: slice1
# 
# $GSM5924032_ffpe_c_4
# An object of class Seurat 
# 31516 features across 3829 samples within 2 assays 
# Active assay: SCT (15758 features, 3000 variable features)
# 1 other assay present: Spatial
# 2 dimensional reductions calculated: ica, umap
# 1 image present: slice1

 meta信息

 Idents信息

 原code中给的保存代码,蛮有意思的,第一次见到save.image()

save.image(paste0(res_folder,Sys.Date(),"_","seurat_processed.RData"))

这里其实就是保存一下这些spatial对象啦

②01_MCP_counter.R

上文已经计算出来了MCPcounter的得分,这里把它们出图

CNS级别的出图

第一步 把组织学的注释(用10X的Loup Browser)添加到metadata中

我的每一个样本的文件夹下储存相应的名为TLS_annotation.csv的注释文件

#ADD annotation 
#再次使用slide_list_test替代slide_list
slide_list_test
# [1] "GSM5924030_ffpe_c_2" "GSM5924031_ffpe_c_3"
# [3] "GSM5924032_ffpe_c_4"

for(slide in slide_list_test){
  #correct ident
  spatial_list[[slide]]$orig.ident <- slide #把orig.ident改过来
  #adding all annotation available
  annot <- paste0(paste0("/data/ybk/GEO/STvisium/RCC_immunity_Tertiary_lymphoid/",slide),"/TLS_annotation.csv")
  for(x in annot){
    annot_table <- read.csv(x)
    rownames(annot_table) <- annot_table[,1]
    annot_table$Barcode <- NULL
    spatial_list[[slide]] <- AddMetaData(object= spatial_list[[slide]],
                                         metadata = annot_table,
                                         col.name = paste0(colnames(annot_table),"_annot"))
  }
}
# 经过与对应文件中的csv验证,这些样本的ano已经被准确添加到对应样本的metadata中
spatial_list$GSM5924030_ffpe_c_2@meta.data["AAACGCTGGGCACGAC-1",]
spatial_list$GSM5924031_ffpe_c_3@meta.data["AAAGTGTGATTTATCT-1",]

                            orig.ident nCount_Spatial
AAAGTGTGATTTATCT-1 GSM5924031_ffpe_c_3           7535
                   nFeature_Spatial percent.mito
AAAGTGTGATTTATCT-1             3589            0
                   nCount_SCT nFeature_SCT    T.cells
AAAGTGTGATTTATCT-1      15618         4105 0.04951051
                   CD8.T.cells Cytotoxic.lymphocytes
AAAGTGTGATTTATCT-1           0             0.3549867
                   B.lineage NK.cells Monocytic.lineage
AAAGTGTGATTTATCT-1 0.6940119        0         0.6839274
                   Myeloid.dendritic.cells Neutrophils
AAAGTGTGATTTATCT-1                       0   0.2408643
                   Endothelial.cells Fibroblasts
AAAGTGTGATTTATCT-1         0.1194506    2.314476
                   SCT_snn_res.0.4 seurat_clusters
AAAGTGTGATTTATCT-1               0               0
                   TLS_2_cat_annot
AAAGTGTGATTTATCT-1             TLS

第二步 绘图

取消坐标轴

#hide spatial axes for seurat plots 
hide_axis <- theme(axis.title.x=element_blank(),
                   axis.text.x=element_blank(),
                   axis.ticks.x=element_blank(),
                   axis.title.y=element_blank(),
                   axis.text.y=element_blank(),
                   axis.ticks.y=element_blank())

绘制,这里挑选了一个样本来做

#figure 1 main 
GSM5924030_ffpe_c_2 <- spatial_list$GSM5924030_ffpe_c_2
Idents(GSM5924030_ffpe_c_2)  <-as.numeric(Idents(GSM5924030_ffpe_c_2)) #如果不用as.numeric,结果是一个因子
#H&E
he_GSM5924030_ffpe_c_2 <- SpatialPlot(GSM5924030_ffpe_c_2,repel = F,label = F,image.alpha=1,alpha = c(0,0), pt.size.factor =0.000001) + geom_point(alpha=0)+
  NoLegend() +
  ggtitle("TLS positive")+  
  theme(text=element_text(size=14))+ 
  theme(text=element_text(face = "bold"));he_GSM5924030_ffpe_c_2  
# MCP scores
cell_types <- make.names(rownames(MCPcounter.estimate(MCPcounterExampleData)))
plot_list_mcp <- lapply(cell_types[c(5,1,2,4,6,8,9,10)],function(x){
  plot_list_mcp <- SpatialPlot(GSM5924030_ffpe_c_2,
                               features = x,
                               image.alpha=0,
                               pt.size.factor = 1.5) +
    scale_fill_viridis_c(option="C") + 
    DarkTheme() +
    hide_axis +    
    theme(text=element_text(size=14))+ 
    theme(text=element_text(face = "bold"))+
    theme(legend.text=element_text(size=7))
  
})
plot_list_mcp

#CA9
ca9 <- SpatialPlot(GSM5924030_ffpe_c_2,
                   features = "CA9",
                   image.alpha=0,
                   pt.size.factor = 1.5) +
  scale_fill_viridis_c(option="C") + 
  DarkTheme() +
  hide_axis +    
  theme(text=element_text(size=14))+ 
  theme(text=element_text(face = "bold"))+
  theme(legend.text=element_text(size=7))

plot_list_mcp[[9]] <- ca9
plot_list_mcp[[10]] <- he_GSM5924030_ffpe_c_2
lay <- rbind(c(10,9,1,2,3,4),
             c(10,9,5,6,7,8))
png(paste0("results_ybk/",Sys.Date(),"_","FIGURE1_.png"),width = 450,height=250,res = 300,units = "mm",bg="transparent")
grid.arrange(grobs = plot_list_mcp, layout_matrix = lay)
dev.off()

出图的效果是所有的图集中在一个list也就是plot_list_mcp当中,grid.arrange函数排图

好看的

第三步 是一个整合 批量绘制所有的图?

我的代码应该还是要把spatial_list换为spatial_list_test

下面为作者源代码 我就没有再测试啦 先用到自己的数据上看看

###这一步应该是对上面函数的整合
sapply(names(spatial_list),function(id){
  print(id)
  #figure 1 main 
  spatial_obj <- spatial_list[[id]]
  Idents(spatial_obj)  <-as.numeric(Idents(spatial_obj)) 
  #H&E
  he <- SpatialPlot(spatial_obj,repel = F,label = F,image.alpha=1,alpha = c(0,0), pt.size.factor =0.00000) +
    NoLegend() +
    ggtitle(id)+  
    theme(text=element_text(size=10))+ 
    theme(text=element_text(face = "bold"))
  #MCP scores
  mcp_keep <- intersect(cell_types[c(5,1,2,4,6,8,9,10)],colnames(spatial_obj@meta.data))
  plot_list_mcp <- lapply(mcp_keep,function(x){
    plot_list_mcp <- SpatialPlot(spatial_obj,
                                 features = x,
                                 image.alpha=0,
                                 pt.size.factor = 1.8) +
      scale_fill_viridis_c(option="C") + 
      DarkTheme() +
      hide_axis +    
      theme(text=element_text(size=10))+ 
      theme(text=element_text(face = "bold"))+ 
      theme(legend.text=element_text(size=8))
  })
  #CA9
  if("CA9" %in% rownames(spatial_obj)){
    ca9 <- SpatialPlot(spatial_obj,
                       features = "CA9",
                       image.alpha=0,
                       pt.size.factor = 1.8) +
      scale_fill_viridis_c(option="C") + 
      DarkTheme() +
      hide_axis +    
      theme(text=element_text(size=10))+ 
      theme(text=element_text(face = "bold"))+
      theme(legend.text=element_text(size=8))
  }else{
    ca9 <- SpatialPlot(spatial_obj,repel = F,label = F,image.alpha=0,alpha = c(0,0), pt.size.factor =0.00000) + NoLegend() + ggtitle("CA9 not expressed")
  }
  plot_list_mcp[[9]] <- ca9
  plot_list_mcp[[10]] <- he
  
  test_null <- sapply(plot_list_mcp,is.null)
  if(any(test_null)){
    check_null <- which(test_null)
    plot_list_mcp[[check_null]] <- SpatialPlot(spatial_obj,repel = F,label = F,image.alpha=0,alpha = c(0,0), pt.size.factor =0.00000) + NoLegend() 
  }
  lay <- rbind(c(10,9,1,2,3,4),
               c(10,9,5,6,7,8))
  grid.arrange(grobs = plot_list_mcp, layout_matrix = lay)
})
dev.off()

③TLS_imprint_signature

原理:Leave-one-out

文中探索这个signature的方法叫做 Leave-one-out,应该说是交叉验证(a method that performs sequential permutations by identifying genes from 3 tumors and validating them on the fourth
one.)。挑选了4个有TLS的冰冻数据样本,计算他们TLS区(手动注释)和非TLS区spot的DEG(使用Seurat的findmarkers函数)。

随后拿三个样本的DEG,和第四个样本的信息做ROC曲线,并计算AUC(使用ROCit包),这样总共可计算四个样本的箱状图。只有那些至少在三个样本中,AUC都大于0.7的DEG才能被保留作为signature,最后剩下29个。随后还把这29个gene放在剩余有TLS的样本中进行验证,发现除了个别样本(质量差),所有的gene AUC都保持在0.7以上。

原理:ROC & AUC

1.ROC曲线的横坐标是伪阳性率FPR(也叫假正类率,False Positive Rate),纵坐标是真阳性率TPR(真正类率,True Positive Rate)。还有伪阴性率(FNR)和伪阴性率(FNR),暂不讨论它俩。

(1)伪阳性率(FPR):判定为正例却不是真正例的概率,即真负例中判为正例的概率(比如一个人本来没有乙肝,结果试剂盒错把这个人判断为乙肝)

(2)真阳性率(TPR):判定为正例也是真正例的概率,即真正例中判为正例的概率(也即正例召回率)(比如一个人本来有乙肝,也被试剂盒检测出来了乙肝)

2.列表大概就是这么个情况,想把TP变成TPR要经过计算. roc曲线就是根据TPR和FPR的坐标点绘制出来的。

 

3.ROC曲线用来评价一种分类器的好坏。如果它的AUC超过0.5(一半),就证明分类器比随机猜要好。曲线上的点代表一个个阈值,随着阈值的不同,假阳性和真阳性的概率也会改变。比如乙肝试剂盒的检测阈值越小,很多低携带量的患者就可以被成功检出,真阳性率升高,但也会有正常人被误伤为乙肝阳性,那么假阳性率也会变高。

 

原理:将数据输入ROCit包

文中的ROC包是ROCit,了解一下这个包的输入

 可以看到重要的就是scoreclass两个参数

文章code中可以看到score是一个(差异)基因*(所有)细胞的表达矩阵;class是在提取样本TLS手动注释的metadata信息,其中中组织学注释为 “TLS” 的细胞会返回True

rocit(
score = spatial_list[[x]][["SCT"]]@data[gene,],    
#取出来一个:行为一个基因,列为barcode的SCT表达矩阵(该函数结合了sapply函数,gene为一个单独的基因
class =  spatial_list[[x]]$TLS_2_cat_annot=="TLS", 
#组织学注释为TLS
negref = F
)

 这里对class举个例子,大概就是这样一个东西。是不是就是所谓的class of the obervations?

结果是一个逻辑值构成的向量,向量的名字是细胞名


这里参考一下SPSS在计算AUC时的数据输入:需要一个class列,一个value列。这样在设定不同的阈值时,就会根据value来分配到合适的class。比如,当以Value=0.6作为阈值,那么被试1,2,3,4被分类成阳性样本,其他被试被分类成阴性样本,据此,我们可以计算得到TPR=3/4,FPR=1/4。这样,我们就可以得到一组(TPR,FPR)值,制定多个阈值,我们就可以得到多组(TPR,FPR)值,把这些值(TPR,FPR)绘制出来得到的曲线就是ROC曲线。

SPSS需要这样整理数据:


回到ROCit的输入

假如score是这样一个矩阵(每次只取一个基因出来)

cell1cell2cell3
DEG11264

那么class就是:(注意这是个向量,上面的cell是向量的name)

cell1cell2cell3
TrueFalseFalse

对于DEG1:

阈值取12,cell1判断为TLS,cell2 cell3非TLS,和class结果一致,那么TPR就是1,FPR是0;

阈值取6,cell1 cell2判断为TLS,cell3非TLS,有一个假阳性,那么TPR就是1/(1+0),FPR是1/(1+1);

阈值取4,cell1 cell2 cell3判断为TLS,有两个假阳性,那么TPR就是1/(1+0),FPR是2/2;

例子有点极端,把AUC搞成1了,但也就说明通过DEG1的值来判断是否为TLS是非常好的;因为高表达的cell1是True,而低表达的cell2 cell3都是False。

以此类推,可以做出每一个差异基因的AUC。

如下图每个肿瘤有多个DEG,每个DEG都有自己的AUC,就形成一个小黑点。

那么leave one out的验证是如何实现的呢?

三个样本的DEG取交集,得到一个基因list。然后用这些gene在第四个样本中的基因取交集,获得最后用来做ROC的DEG。对每一个DEG取出score,和第四个样本的TLS注释情况class一起做AUC分析。这样就可以绘出第四个样本的gene-TLS AUC得分箱状图(如下)。一个点代表一个基因,拥有一个AUC值

 文献代码

接下来来看看作者的代码究竟是怎么搞的

作者的源代码是"b_1","a_15","a_4","b_17"四个样本,我这里就接上文的三个样本

最后的效果就是两个样本的DEG与第三个样本的表达矩阵gene取交集获得score,并用第三个样本的TLS注释(class)来做ROC曲线。

Differential expression in each samples

# Differential expression in each samples 用举例的三个样本
TLS_pos_ids <- c("GSM5924030_ffpe_c_2",
                 "GSM5924031_ffpe_c_3",
                 "GSM5924032_ffpe_c_4")
# 差异基因分析
TLS_list_all_samples <- lapply(TLS_pos_ids,function(y){
  x <- spatial_list[[y]]
  to_use <- "TLS"
  if(length(to_use)!=0){
    tls_MAST <- FindMarkers(x,group.by = "TLS_2_cat_annot",ident.1 = to_use,test.use = "MAST")
  }else{
    return(NA)
  }
})
TLS_list_all_samples #三个差异基因的List,对应上方的三个样本

Perform discovery on 2 tumors and validate on 1(原作为3 tumors and validate on 1)

hide_ig <- F #这是给一个逻辑值
x <- TLS_pos_ids[c(1)] #给下文X的值举例 正文不需要此代码 跑循环的时候不运行
cross_validation <- sapply(TLS_pos_ids[c(3,2,1)],function(x){
  print(x) #x就是对应的3个样本之一
  sub <- TLS_pos_ids[TLS_pos_ids!=x] #sub是除了x的另外两个样本
  gene_list <- lapply(TLS_list_all_samples[TLS_pos_ids!=x],function(y){ #y是除了x的另外两个样本的差异基因list,也就是sub对应的样本差异基因
    rownames(y)[which(y$avg_log2FC > 1 & y$p_val_adj < 0.05)] #按照阈值筛选差异基因
  }) ##lapply end 返回的结果是一个list,list中是两个样本的差异基因
  tls_sign <- unique(unlist(gene_list)) #把上面筛选的两个样本的所有的差异基因去重,得到筛选后的DEG
  intersect_tls_sign <- intersect(tls_sign,rownames(spatial_list[[x]])) #将DEG与x的所有基因取交集(保证上文推导的差异基因都在X中出现)
  if(hide_ig){ #默认不运行本段
    intersect_tls_sign <- grep(x =intersect_tls_sign, pattern = "IG",value = T,invert = T) #invert=T以后返回的是未匹配到的值
    intersect_tls_sign <- grep(x =intersect_tls_sign, pattern = "JCHAIN",value = T,invert = T) #value=T后返回的是匹配到的值,F则返回位置
  }
  #ROC
  #intersect_tls_sign是通过除X的另外几个样本得到的DEG与样本X的所有基因取交集后得到的一串基因名(signature)
  rocs <- sapply(intersect_tls_sign,function(gene){ #d对signature中的所有基因挨个应用函数function(gene)
    roc_empirical <- rocit(score = spatial_list[[x]][["SCT"]]@data[gene,],    #取出来一个:行为一个基因,列为barcode的SCT表达矩阵
                           class =  spatial_list[[x]]$TLS_2_cat_annot=="TLS", #组织学注释为TLS
                           negref = F)
    roc_empirical$AUC
  }) #输出的结果rocs是一串ROC值的向量,向量的name是基因
  return(list(
    "tls_sign"=intersect_tls_sign,
    "auc"=sort(rocs)))
}) ###supply end

运行结果解读:

直接来看是个List,class的结果却不是

class(cross_validation)
# [1] "matrix" "array" 

 tls_sign是利用该样本进行验证时的TLS signature,auc展示对应基因的值


如果把上文的cross_validation <- sapply(TLS_pos_ids[c(3,2,1)],function(x){改为lapply,则返回结果是list。展示为标准的List结构

class(cross_validation)
# [1] "list"

 


如果注释掉一些代码

则尽管使用的是sapply,返回的结果仍然是list

class(cross_validation)
# [1] "list"

 


既注释掉return,又使用lapply

class(cross_validation)
# [1] "list"


上述的例子涉及Return和sapply和lapply的区分

return中,如果你自己编了一个函数,试图使这个函数返回多个值,例如返回均值,方差,如果在自定义的函数里,分两行写了均值,方差,将只返回方差。如果要实现这个目的,请使用list。

返回值return:
返回值就是函数给出的结果。打个比方,编写一个函数,就像自己攒一个机器,例如现在攒好 一台豆浆机,该豆浆机要求输入大豆,输入的大豆就是参数, 返回的结果,就是豆浆。如果该豆浆机需要不停地输入大豆, 而不能产出豆浆,这样的机器就一定会被扔掉。函数也是一样的, 需要给出返回值。 R中默认的情况是将最后一句作为返回值。但是为了函数的可读性起见,应该尽量指名返回值。返回值用return()函数给出。 函数在内部处理过程中,一旦遇到return(),就会终止运行, 将return()内的数据作为函数处理的结果给出。

结合上述四种情况可以看出,在没有设置返回值时,只能默认返回最后一个运行值(rocs)。

想要同时返回两个值,请用list连接

不想返回一个列表,请使用sapply


Get list with threshold 按照0.7的阈值筛选

tls_sign <- sort(table(unlist(sapply(cross_validation["auc",],function(auc) names(which(auc > 0.7))))))
tls_sign <- names(which(tls_sign >=3))
tls_sign
# [1] "IGHA1"   "IGHG1"   "IGHG2"   "IGHG3"   "IGHM"    "IGKC"    "IGKV4-1" "IGLC1"   "JCHAIN"  "POU2AF1"

Venn diagramm 图有点丑,不过可以出图

tls_sign_over_07 <- sapply(cross_validation["auc",],function(auc) auc[which(auc > 0.7)])
library(VennDiagram)
toto <- sapply(tls_sign_over_07,function(x) names(x)) #结果是所有经过0.7筛选的基因名
pl <- venn.diagram(
  x = toto,
  category.names = names(toto),
  filename = NULL,cex=4,
  fill=c(viridis(3)),
  output=T
)
pl
png(paste0(res_folder,Sys.Date(),"_FIGURE_TLS_signature_supp_venn.png"),width = 7,height=5,units = "in",res = 500,bg = 'transparent')
grid.draw(pl)
dev.off()

 注意这里

y1=sapply(tls_sign_over_07,function(x) names(x))
y2=sapply(tls_sign_over_07,function(x){
  names(x)}) #两种写法等价

对上述代码进行可视化

#visualise on all tumours 在所有的肿瘤上对TLS——signature可视化
opt<-"C" #提供调色板选项
#hide spatial axes for seurat plots 
hide_axis <- theme(axis.title.x=element_blank(),
                   axis.text.x=element_blank(),
                   axis.ticks.x=element_blank(),
                   axis.title.y=element_blank(),
                   axis.text.y=element_blank(),
                   axis.ticks.y=element_blank())
val <-lapply(names(spatial_list)[1:3],function(x){ #我的list中只有三个样本,源代码1:12
  print(x)
  intersect_tls_sign <- intersect(tls_sign,rownames(spatial_list[[x]])) 
  spatial_list[[x]] <- AddMetaData(spatial_list[[x]],apply(as.matrix(spatial_list[[x]][["SCT"]]@data[intersect_tls_sign,]),2,mean),col.name = "TLS_signature") 
  #ROC 
  if(any(spatial_list[[x]]$TLS_2_cat_annot=="TLS")){
    roc_empirical <- rocit(score = spatial_list[[x]]$TLS_signature,
                           class =  spatial_list[[x]]$TLS_2_cat_annot=="TLS",
                           negref = F)
    auc <- roc_empirical$AUC
  }else{
    auc <- NA
  }
  SpatialPlot(spatial_list[[x]],image.alpha = 0, features = "TLS_signature") +
    scale_fill_viridis_c(option=opt,limits = c(0,4.1)) + 
    DarkTheme() +
    hide_axis +
    ggtitle(label =paste0("AUC = ", round(auc,2)))
})
grid.arrange(grobs=val,ncol=3)

png(paste0(res_folder,Sys.Date(),"_FIGURE_TLS_signature_supp_heatmap.png"),width = 24,height=10,units = "in",res = 500,bg = 'transparent')
grid.arrange(grobs=val,ncol=6)
dev.off()

绘制差异基因火山图

(还是只有三个样本

#figure supp TLS signature 差异基因的火山图
#plot volcano
names(TLS_list_all_samples) <- TLS_pos_ids 
all_volcanoes <- lapply(TLS_pos_ids[c(3,2,1)], function(ids){
  diff_exp <- TLS_list_all_samples[[ids]]
  diff_exp <- diff_exp[,c("avg_log2FC","p_val_adj")]
  colnames(diff_exp) <- c("log2FC","pval")
  plot_volcano(dataset = diff_exp,
               pval_FC=c(0.05,2),
               #label_to_id = tls_sign,
               hide_label = F,
               ylabel = "-log10 (Adjusted P value)") + xlim(lims=c(-5,5)) +
    ggtitle(label=ids) +
    theme(text=element_text(size=15))+ 
    theme(text=element_text(face = "bold"))
})
png(paste0(res_folder,Sys.Date(),"_FIGURE_TLS_signature_supp.png"),width = 10,height=10,units = "in",res = 500)
grid.arrange(grobs=all_volcanoes,n=2)
dev.off()

上门的代码有一段plot_volcano可能是作者source的自建函数。我这里替换一个火山图函数
#figure supp TLS signature 差异基因的火山图
#plot volcano
names(TLS_list_all_samples) <- TLS_pos_ids #给差异基因的list命名
all_volcanoes <- lapply(TLS_pos_ids[c(3,2,1)], function(ids){
  diff_exp <- TLS_list_all_samples[[ids]]
  diff_exp <- diff_exp[,c("avg_log2FC","p_val_adj")]
  colnames(diff_exp) <- c("log2FC","pval")
  EnhancedVolcano(diff_exp,
                  lab = rownames(diff_exp),
                  x="log2FC",
                  y="pval",
                  pCutoff=0.05,
                  FCcutoff=2)+
  # plot_volcano(dataset = diff_exp,
  #              pval_FC=c(0.05,2),
  #              #label_to_id = tls_sign,
  #              hide_label = F,
  #              ylabel = "-log10 (Adjusted P value)") + 
    xlim(lims=c(-5,5)) +
    ggtitle(label=ids) +
    theme(text=element_text(size=15))+ 
    theme(text=element_text(face = "bold"))
})

all_vocanno

grid.arrange(grobs=all_volcanoes,n=1)

 

 BOXPLOT AUC的箱装图

构建数据

library(stringr)
toto <- data.frame(unlist(cross_validation["auc",]))
toto$id <- str_split(rownames(toto),"\\.",simplify = T)[,1]
colnames(toto)[1] <- "values"

 绘图

 对比原文看一下

④展示TLS_imprint_signature和其它marker关系

使用scale.data

 

#figure supp 绘制共表达图的代码????好像是的 下面画了Sup 4 figure
opt <- "C"
plot_list <- list()
for(spat in names(spatial_list)[c(1:3)]){  #原文是c(1:2,4:12),这里进行替换1:3
  spat <- names(spatial_list[1])  ###举例,不运行循环
  print(spat)
  library("patchwork")
  pat <- list.files(path = "~/projects/visium/data/ihc",pattern =spat,full.names =T)
  ihc <- readPNG(pat,native=T)
  # 把IGKC和JCHAIN 和 intersect_tls_sign的gene计算平均值(SCT data)计入两个新的metadata
  spatial_list[[spat]] <- AddMetaData(spatial_list[[spat]],apply(as.matrix(spatial_list[[spat]][["SCT"]]@data[c("IGKC","JCHAIN"),]),2,mean),col.name = "Pan_IG") 
  intersect_tls_sign <- intersect(tls_sign,rownames(spatial_list[[spat]])) 
  spatial_list[[spat]] <- AddMetaData(spatial_list[[spat]],apply(as.matrix(spatial_list[[spat]][["SCT"]]@data[intersect_tls_sign,]),2,mean),col.name = "TLS_Imprint") 
  #ROC 
  if(any(spatial_list[[spat]]$TLS_2_cat_annot=="TLS")){
    print("compute_roc")
    roc_empirical <- rocit(score = spatial_list[[spat]]$TLS_Imprint,
                           class =  spatial_list[[spat]]$TLS_2_cat_annot=="TLS",
                           negref = F)
    auc <- roc_empirical$AUC
  }else{
    auc <- NA
  }
  
  #compute spatial cor ????
  TLS_Imprint <- as.vector(scale(spatial_list[[spat]]$TLS_Imprint)) #提取metadata,
  Pan_IG <- as.vector(scale(spatial_list[[spat]]$Pan_IG))
  
  spatial_list[[spat]]@assays$SCT@scale.data <- rbind(spatial_list[[spat]]@assays$SCT@scale.data,TLS_Imprint)#把结果合并到scale.data中(3000个基因+1)
  spatial_list[[spat]]@assays$SCT@scale.data <- rbind(spatial_list[[spat]]@assays$SCT@scale.data,Pan_IG)#为什么是scale.data呢
  sign_list <- c("TLS_Imprint",
                 "MZB1",
                 "Pan_IG",
                 "IGHM",
                 "IGHG1",
                 "IGHA1",
                 "COL1A1",
                 "CXCL12")
  spat_cor_int <- intersect(sign_list,rownames(spatial_list[[spat]]@assays$SCT@scale.data)) #取交集
  spat_cor_ext <- setdiff(sign_list,rownames(spatial_list[[spat]]@assays$SCT@scale.data)) #取差集
  
  # spatial_cor <- RunMoransI(data = spatial_list[[spat]]@assays$SCT@scale.data[spat_cor_int,],
  #                               pos =  GetTissueCoordinates(object = spatial_list[[spat]]))
  # spatial_cor[spat_cor_ext,] <-c(NA,NA)
  he <- SpatialPlot(spatial_list[[spat]],repel = F,label = F,image.alpha=1,alpha = c(0,0), pt.size.factor =0) + NoLegend()
  blank <- SpatialPlot(spatial_list[[spat]],repel = F,label = F,image.alpha=0,alpha = c(0,0), pt.size.factor =0) + NoLegend()+
    inset_element(p = ihc,
                  left = 0,
                  bottom = 0,
                  right = 1,
                  top = 1)
  
  all_plots <-lapply(sign_list,function(sign){
    p <- SpatialPlot(spatial_list[[spat]],image.alpha = 0, features = sign)
    p <- p+ scale_fill_viridis_c(option="C")
    p <- p+ DarkTheme()
    # p <- p+ annotate("text", 
    #                  x=max(GetTissueCoordinates(object = spatial_list[[spat]])[,2]) - 10, 
    #                  y = max(GetTissueCoordinates(object = spatial_list[[spat]])[,1]) +30,
    #                  size=4,
    #                  vjust=1,
    #                  hjust=1,
    #                  col="white"),
    #                  label = paste0("Spatial cor: ", round(spatial_cor[sign,"observed"],digits = 2)))
    if(sign=="TLS_Imprint" & spat %in% names(spatial_list)[c(1,2,4,6:9)]){
      p <- p+ annotate("text", 
                       x=min(GetTissueCoordinates(object = spatial_list[[spat]])[,2]) + 100, 
                       y=min(GetTissueCoordinates(object = spatial_list[[spat]])[,1]) +30,
                       size=4,
                       vjust=1,
                       hjust=1,
                       col="white",
                       label = paste0("AUC = ", round(auc,2)))
    }
    p <- p + hide_axis +theme(legend.title=element_text(size=15))
  })
  plot_list[[spat]]  <- (he | blank | all_plots[[1]] | all_plots[[2]] |all_plots[[3]] ) / ( all_plots[[4]] | all_plots[[5]] | all_plots[[6]] |all_plots[[7]]| all_plots[[8]])
}
pdf(paste0(res_folder,Sys.Date(),"_FIGURE_4_supp.pdf"),width = 15,height=15)
plot_list
dev.off()

绘图用scale.data

 

 

最后出的一些图没有太明白和上文的有什么区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

18kkk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值