单细胞Day7-多样本数据-1

1.下载并整理数据

演示数据:GSE231920,3个treat+3个control

untar("GSE231920_RAW.tar",exdir = "GSE231920_RAW")#解包
library(stringr)
fs = paste0("GSE231920_RAW/",dir("GSE231920_RAW/"))
samples = dir("GSE231920_RAW/") %>% str_split_i(pattern = "_",i = 2) %>% unique();samples
## 从文件名中提取到样本名,用str_split_i把文件名称按照"_"作为分隔符(pattern = "_")分成多个部分(比如GSM7306054_sample1_barcodes.tsv.gz被分成GSM7306054、sample1、barcodes.tsv.gz三个部分),我们需要的是第2个部分(i=2),即sample1。
1.1字符串处理的函数

stringr包里的函数:
str_sub():用于从字符串中提取子字符串。可以根据起始位置和结束位置来选择部分字符串。

text <- "Hello, world!"
# 提取从第7个字符到最后的子字符串
result <- str_sub(text, start = 7)
print(result)  
# 输出结果为 "world!"

str_remove():用于从字符串中移除指定的子字符串。可以根据正则表达式或者普通字符串来指定需要移除的内容。

text <- "Data analysis is fun."
# 移除包含 "is" 的子字符串
result <- str_remove(text, "is")
print(result)
# 输出结果为 "Data analysis  fun."

str_detect():用于检测字符串中是否包含指定的模式或者子字符串。返回逻辑值(TRUE或FALSE),表示是否检测到匹配

texts <- c("apple", "banana", "orange", "grape")
# 检测包含 "an" 的字符串
result <- str_detect(texts, "an")
print(result)  
# 输出结果为 TRUE FALSE TRUE FALSE

str_replace():用于替换字符串中的匹配内容。可以根据正则表达式或者普通字符串来替换匹配到的内容。

text <- "R programming is great!"
# 替换 "great" 为 "awesome"
result <- str_replace(text, "great", "awesome")
print(result)  
# 输出结果为 "R programming is awesome!"
1.2 文件处理函数
dir() # 列出工作目录下的文件
# [1] "2024-06-18-151153.jpg"     "2024-06-18-151153.png"     "anno.txt"                 
# [4] "featureplot.png"           "GSE231920_RAW"             "GSE231920_RAW.tar"        
# [7] "heatmap.png"               "input"                     "markers.Rdata"            
#[10] "my_markers.txt"            "obj.Rdata"                 "plot_zoom.png"            
#[13] "plot_zoom2.png"            "plot_zoom3.png"            "plot_zoom4.png"           
#[16] "ref_BlueprintEncode.RData" "ref_Human_all.RData"       "sce.all.Rdata"            
#[19] "sce.Rdata"                 "single_ref"                "violin.png"               
#[22] "单细胞.Rproj"              "单细胞学小组geo数据"       "山脊图.png"               
#[25] "未命名.R"                  "气泡图.png"                "注释.png"                 
#[28] "注释umap.png"              "注释气泡.png"                            "sce.all.Rdata"

dir(pattern = ".R$") #列出工作目录下以.R结尾的文件 $表示以……结尾
# [1] "未命名.R"

dir(pattern = ".R")   #列出工作目录下包含.R的文件

##[1] "GSE231920_RAW"             "GSE231920_RAW.tar"         "markers.Rdata"            
##[4] "obj.Rdata"                 "ref_BlueprintEncode.RData" "ref_Human_all.RData"      
## [7] "sce.all.Rdata"             "sce.Rdata"                 "单细胞.Rproj"             
##[10] "未命名.R"

file.create("douhua.txt") #用代码创建文件
## [1] TRUE

file.exists("douhua.txt") #某文件在工作目录下是否存在
## [1] TRUE

file.remove("douhua.txt") #用代码删除文件
## [1] TRUE

file.exists("douhua.txt") #删掉了就不存在
## [1] FALSE

## 可以批量的新建和删除
f = paste0("douhua",1:10,".txt")
file.create(f)
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

file.remove(f)
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
1.3 lapply
lapply(1:4, print)   #就是把1、2、3、4依次代入print这个函数里

## [1] 1
## [1] 2
## [1] 3
## [1] 4

## [[1]]
## [1] 1
## 
## [[2]]
## [1] 2
## 
## [[3]]
## [1] 3
## 
## [[4]]
## [1] 4
1.4 自定义函数

比如分情况讨论装包可以写成一个函数:

my_install = function(pkg){
  if (!require(pkg,character.only = T))install.packages(pkg,update = F,ask = F)
}
my_install("tidyr")   
#就会把”tidyr”代入到大括号里的pkg位置
#安装多个包
ps = c("tidyr","dplyr","stringr")
lapply(ps, my_install)
1.5 整理成Read10X要求的格式

每个样本单独一个文件夹,文件夹名是样本名,每个文件夹里3个固定名称的文件,不可以有前缀。

# 为每个样本创建单独的文件夹,都放在01_data下面
ctr = function(s){
  ns = paste0("01_data/",s)
  if(!file.exists(ns))dir.create(ns,recursive = T)
}
lapply(samples, ctr)
list.files(path = "01_data")
##  [1] "sample1" "sample2" "sample3" "sample4" "sample5" "sample6"
#每个样本的三个文件复制到单独的文件夹
#自定义函数可不起名字,直接放在lapply第二个参数的位置上
lapply(fs, function(s){
  #s = fs[1]
  for(i in 1:length(samples)){
    #i = 1
    if(str_detect(s,samples[[i]])){
      file.copy(s,paste0("01_data/",samples[[i]]))
    }
  }
})
image.png
#所有文件改名,去掉前缀。
on = paste0("01_data/",dir("01_data/",recursive = T));on
#输出只留了前三个做示范
#[1] "01_data/sample1/GSM7306054_sample1_barcodes.tsv.gz"
# [2] "01_data/sample1/GSM7306054_sample1_features.tsv.gz"
# [3] "01_data/sample1/GSM7306054_sample1_matrix.mtx.gz"  
nn = str_remove(on,"GSM\\d+_sample\\d_");nn
#输出只留了前三个做示范
#[1] "01_data/sample1/barcodes.tsv.gz" "01_data/sample1/features.tsv.gz"
#[3] "01_data/sample1/matrix.mtx.gz"
file.rename(on,nn)
image.png

修改文件名时,路径时要从工作目录之下开始写

2.批量读取

rm(list = ls())
library(Seurat)
rdaf = "sce.all.Rdata"
if(!file.exists(rdaf)){
  f = dir("01_data/")
  scelist = list() #创建空的列表,下面的for循环每执行一次,scelist里面就会多一个元素。
  for(i in 1:length(f)){
    pda <- Read10X(paste0("01_data/",f[[i]]))
    scelist[[i]] <- CreateSeuratObject(counts = pda, 
                                       project = f[[i]],
                                       min.cells = 3,
                                       min.features = 200)
    print(dim(scelist[[i]]))#输出每个文件的基因数和细胞数
  }
  sce.all = merge(scelist[[1]],scelist[-1]) #合并多个对象
  sce.all = JoinLayers(sce.all) 
  #merge后,每个样本的表达矩阵是一个独立的的layer,JoinLayers是合并为一个表达矩阵
  set.seed(335)
  sce.all = subset(sce.all,downsample=700)#每个样本抽700个细胞
  save(sce.all,file = rdaf)
}
load(rdaf)
head(sce.all@meta.data)

##                      orig.ident nCount_RNA nFeature_RNA
## AAAGAACAGTCTGTAC-1_1    sample1       3884         1377
## AAAGGGCTCTCGCGTT-1_1    sample1       1615          721
## AAAGGTACAATTGGTC-1_1    sample1       3806         1215
## AAAGTGAGTATCGAAA-1_1    sample1       5554         1456
## AAAGTGATCTCAACCC-1_1    sample1       3111         1328
## AACAAAGGTAAGGTCG-1_1    sample1       3658         1243

table(sce.all$orig.ident) #每个样本多少细胞

## 
## sample1 sample2 sample3 sample4 sample5 sample6 
##     700     700     700     700     700     700

sum(table(Idents(sce.all)))#细胞总数

## [1] 4200

3.质控指标

除了线粒体基因(MT-),核糖体(RP[SL])和红细胞基因(HB[^(P)])也是常见的过滤指标,也可以画画看,如果有离群值,也可以过滤掉。

#过滤掉线粒体基因,核糖体和红细胞基因
sce.all[["percent.mt"]] <- PercentageFeatureSet(sce.all, pattern = "^MT-")
sce.all[["percent.rp"]] <- PercentageFeatureSet(sce.all, pattern = "^RP[SL]")
sce.all[["percent.hb"]] <- PercentageFeatureSet(sce.all, pattern = "^HB[^(P)]")
head(sce.all@meta.data, 3)
##                     orig.ident nCount_RNA nFeature_RNA percent.mt percent.rp percent.hb
## AAAGAACAGTCTGTAC-1_1    sample1       3884         1377   4.763131   23.09475          0
## AAAGGGCTCTCGCGTT-1_1    sample1       1615          721   0.619195   35.85139          0
## AAAGGTACAATTGGTC-1_1    sample1       3806         1215   7.777194   37.12559          0
#过滤掉离群值,画小提琴
VlnPlot(sce.all, 
        features = c("nFeature_RNA",
                     "nCount_RNA", 
                     "percent.mt",
                     "percent.rp",
                     "percent.hb"),
        ncol = 3,pt.size = 0.5, group.by = "orig.ident")
image.png
#根据小提琴图指定指标去掉离群值
sce.all = subset(sce.all,percent.mt < 20&
                   nCount_RNA < 40000 &
                   nFeature_RNA < 6000)
table(sce.all@meta.data$orig.ident)

## 
## sample1 sample2 sample3 sample4 sample5 sample6 
##     687     622     683     686     678     675

4.整合降维聚类分群

多样本的整合,使用harmony,它需要的计算资源少,且准确程度高,是最受欢迎的方法。
**需要删掉原来的obj.Rdata!!!!!

f = "obj.Rdata"
library(harmony)
if(!file.exists(f)){
  sce.all = sce.all %>% 
    NormalizeData() %>%  
    FindVariableFeatures() %>%  
    ScaleData(features = rownames(.)) %>%  
    RunPCA(pc.genes = VariableFeatures(.))  %>%
    RunHarmony("orig.ident") %>%
    FindNeighbors(dims = 1:15, reduction = "harmony") %>% 
    FindClusters(resolution = 0.5) %>% 
    RunUMAP(dims = 1:15,reduction = "harmony") %>% 
    RunTSNE(dims = 1:15,reduction = "harmony")
  save(sce.all,file = f)
}
load(f)
ElbowPlot(sce.all)
image.png
p1 =  DimPlot(sce.all, reduction = "umap",label = T,pt.size = 0.5)+ NoLegend();p1
image.png
DimPlot(sce.all, reduction = "umap",pt.size = 0.5,group.by = "orig.ident")

image.png

group.by = "orig.ident"就会按照样本来分配颜色。检查一下去除样本间批次效应的效果如何,在umap图上面看,糊在一起,没有每个样本自成一簇,就说明效果还可以。如果效果不太好,可以比较一下其他的去除批次效应的方法(一般没啥必要)。

https://satijalab.org/seurat/articles/seurat5_integration

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,198评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,334评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,643评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,495评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,502评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,156评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,743评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,659评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,200评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,282评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,424评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,107评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,789评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,264评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,798评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,435评论 2 359

推荐阅读更多精彩内容