看到了2025年10月的单细胞转录组文献是公开了表达量矩阵的:《A cellular and spatial atlas of TP53-associated tissue remodeling defines a multicellular tumor ecosystem in lung adenocarcinoma》,但是不是我们常见的GEO数据库啦。文章里面的 WES, scRNA-seq and ST data 都可以在Zenodo (https://doi.org/10.5281/zenodo.16546233

我首先使用人工智能大模型帮我汇总了这个研究的组学方面,就是系统刻画了 TP53 突变型 vs 野生型肺腺癌(LUAD)的 单细胞转录组 + 空间转录组 + 多重免疫荧光 + 全外显子组多组学图谱:
项目 | 详情 |
|---|---|
样本来源 | 23 例初治 NSCLC 患者(21 例吸烟),切除原发肿瘤 |
技术平台 | 10x Chromium 3′ scRNA-seq(v2/v3) |
细胞总数 | 166,821 个高质量细胞(质控后) |
TP53 分组 | TP53mut(n=8) vs TP53WT(n=10) |
配对数据 | WES(肿瘤+PBMC)、空间转录组(Visium,20 张切片)、mIF(42 张) |
细胞类型 | 11 大类 → 恶性、T/NK、B、髓系、内皮、周细胞、成纤维等 |


细胞类型 | TP53mut 特征 |
|---|---|
内皮细胞 | ↓ 气胞(aerocyte)与动脉内皮;血管生成受抑制 |
周细胞 | 显著减少 |
CAF | ↑ COL1A2⁺ 炎症性 CAF(CAF.COLs);↑ TGFB2-TGFBR2 信号 |
巨噬细胞 | ↓ FABP4⁺ 肺泡样 TAM;↑ SPP1⁺ TAM(与缺氧/EMT 共表达) |
T 细胞 | ↑ 耗竭型 CD8(PDCD1⁺CTLA4⁺TIGIT⁺);↑ CXCL13⁺ TFH;↑ GZMK⁺ CD8 |
本文通过 166k 单细胞 + 空间转录组揭示:TP53 突变型 LUAD 恶性细胞丧失 AT2 身份、获得高熵/可塑性,并构建以 SPP1⁺巨噬-COL1A2⁺成纤维为核心的 缺氧-EMT 生态位,伴随 PVR-TIGIT/PDL1-PD1免疫检查点富集,为 TP53mut 肿瘤提供更优免疫治疗响应的生物学基础。
可以 读取作者给出来的单细胞转录组文件,然后自己进行第一层次降维聚类分群后,跟作者的单细胞亚群注释信息对比一下。不过我们这里为了简化处理,直接对比作者自己的第一层次降维聚类分群和第二层次的命名:
load('Data_for_Github/all.merge.Rda')
phe = all@meta.data
pdf('celltype-vs-subtype.pdf',width = 12,height = 15)
gplots::balloonplot(table(phe$celltype,phe$subtype))
dev.off()
很容易看到第一层次的每个亚群是如何细分成为第二层次的多个亚群的:

第一层次的每个亚群是如何细分成为第二层次的多个亚群
如果想让上面的图好看一点,就需要简单的排序。以前我是让人工智能大模型帮我想解决方案,但是这次我动了一下我的小脑袋瓜,发现也可以自己写出来。
x = phe$subtype
y = phe$celltype
tbl = table(x,y)
df = dcast(as.data.frame(tbl),x~y)
#View(df)
rownames(df)=df[,1]
df=df[,-1]
n=10^(10*(ncol(df):1))
#View(t(t(df)*n))
pos=order(rowSums( t(t(df)*n) ));pos
rownames(df)[pos]
phe$subtype = factor(phe$subtype,levels = rownames(df)[pos] )
可以看到,效果还是很不错的, 排序的清清楚楚啦!

虽然我的脑袋瓜子想出来了这么好的代码,但是我嘴笨不知道如何解释,这个时候仍然是可以求助于人工智能大模型。 下面这段 R 代码的核心任务是:
把 phe$subtype的 levels 重新排个序,使得在“加权后的总 abundance”越大的 group 越靠前(即后面画图时排在热图上方)。
权重由 n = 10^(10*(ncol(df):1))给出——列号越靠后(即原表最右边的 celltype),权重越大。
逐句拆解:
x = phe$subtype # 行:肿瘤亚型/分组
y = phe$celltype # 列:细胞类型
tbl = table(x, y) # 数每种组合的细胞数
df = dcast(as.data.frame(tbl), x ~ y)
# 结果:行名 = subtype,列名 = celltype,值 = 计数
rownames(df) = df[, 1]
df = df[, -1] # 现在 df 是纯数值矩阵
n = 10^(10*(ncol(df):1))
# 举例:若有 5 个 celltype,则
# n = c(10^50, 10^40, 10^30, 10^20, 10^10)
# 越靠右的 celltype 权重越高
tmp = t(t(df) * n) # 每列乘对应权重
score = rowSums(tmp) # 每行加总,得一个分数
pos = order(score) # 分数小的在前
rownames(df)[pos] # 查看排序后的名字
phe$subtype = factor(phe$subtype,
levels = rownames(df)[pos])
order默认是 升序,而我们要分数大的在前,所以直接把 pos当作新 levels 即可(pos里先放的是原表中得分最小的行号,依次往后)。这段代码按“越靠右的 celltype 对排序贡献越大”的规则,把
subtype的 levels 重新排了一遍,以便后续可视化时把“重要”的 group 放在上方。
当然了,这个时候其实桑基图会更好的展示,大家可以试试看!如果不会桑基图的绘图代码,也可以试试看让人工智能大模型帮大家!