生存预后不显著?最佳阈值来帮你!| 附完整代码 + 注释

大家在进行生存预后分析时发现结果不显著,是不是当头一棒!两眼一黑!难不成这就代表我们的研究没意义吗?NONONO!别慌!说不定还有救!快来看看最佳阈值能不能捞你一把!

对生存分析感兴趣的小伙伴可以查看:看完不会来揍我 | 生存分析详解 | 从基础概念到生存曲线绘制 | 代码注释 + 结果解读

生存分析不显著怎么办

通常情况下,为了确定一个二分变量(例如基因表达高/低)的最佳阈值,我们可能会使用中位数作为阈值,将样本分为两组,然后对生存曲线进行比较。但有时候使用中位数作为阈值可能并不足以找到显著的差异,这时可以考虑使用最佳阈值方法来寻找更加适合的阈值。来!咱们今天就一起去xio习一下!

老规矩!本文所用到的数据和代码,我已经上传到了GitHub,有需要的话,大家可以在公众号后台回复最佳阈值即可获得存放数据的链接,很多需要注意的问题也会在代码注释中进行详细说明。不过我在分享过程中也会把每一步的输入数据和输出结果进行展示,大家可以作为参考并调整自己的数据格式,然后直接用自己的数据跑,也是没有任何问题的!

# 生存预后不显著?最佳阈值来帮你!

# 加载包,没安装的记得安装一下哟!
library(survival)
library(survminer)

# 加载数据
best_threshold_data <- read.csv("./best_threshold_data.csv")
head(best_threshold_data)
#            sample risk_score OS OS.time
# 1 TCGA-06-0878-01   2.538694  0     218
# 2 TCGA-26-5135-01   3.736050  1     270
# 3 TCGA-06-5859-01   3.701219  0     139
# 4 TCGA-06-2563-01   3.318001  0     932
# 5 TCGA-41-2571-01   5.102783  1      26
# 6 TCGA-28-5207-01   6.899652  1     343

# 数据包含了四列:样本名称(sample)、风险评分(risk_score)、生存状态(OS)和生存时间(OS.time)。

# 使用中位数作为阈值来将样本分为高风险组和低风险组
# 如果风险评分大于等于中位数,则标记为"High Risk",否则标记为"Low Risk"
best_threshold_data$group <- ifelse(best_threshold_data$risk_score >= median(best_threshold_data$risk_score), "High Risk", "Low Risk")

# 创建生存对象(Surv对象),包含生存时间和生存状态信息
surv_obj <- Surv(time = best_threshold_data$OS.time, event = best_threshold_data$OS)

# 使用survfit()函数拟合生存曲线
surv_fit <- survfit(surv_obj ~ best_threshold_data$group)

# 绘制生存曲线
ggsurvplot(surv_fit, data = best_threshold_data, surv.median.line = "hv",
           pval = TRUE,  # 显示p值
           xlab = "Time (days)", ylab = "Survival Probability",  # x轴和y轴标签
           legend.title = "",  # 图例标题为空
           break.x.by = 1000,  # x轴刻度间隔
           color = "strata",  # 根据分组着色
           palette = c("#bc5148", "#3090a1"))  # 自定义颜色

哎!最恶毒的诅咒莫过于“祝你P > 0.05”!!!这不显著可咋整,咱这分析不就没意义了嘛!

且慢!我们的救兵来啦!下面请欣赏它的表演!

最佳阈值选择

目前比较常见的方法有:

  • 使用survminer包中的surv_cutpoint函数实现
  • 使用cutoff包中的logrank函数实现
  • 基于X-Tile软件实现

下面,咱们就挨个介绍!

survminer包的surv_cutpoint函数

# survminer包的surv_cutpoint函数
# 使用survminer包的surv_cutpoint函数来寻找最佳阈值
best_threshold_surv <- surv_cutpoint(best_threshold_data,
                                     time = "OS.time",  # 生存时间列名
                                     event = "OS",      # 生存事件列名
                                     variables = "risk_score",  # 需要寻找阈值的变量列名
                                     minprop = 0.3,     # 最小比例,防止找到的阈值过于极端
                                     progressbar = TRUE)  # 显示进度条

# 查看找到的最佳阈值的摘要统计信息
summary(best_threshold_surv)
#            cutpoint statistic
# risk_score 4.420631  1.748393

# 我们这里只计算了一个变量的最佳阈值,还可以计算多个变量的最佳阈值,只需将`variables`参数设为`c("变量1, "变量2", "变量3")`。

# 根据找到的最佳阈值对数据进行分组
best_threshold_data <- surv_categorize(best_threshold_surv)

# 创建生存对象(Surv对象),包含生存时间和生存状态信息
surv_obj <- Surv(time = best_threshold_data$OS.time, event = best_threshold_data$OS)

# 使用survfit()函数拟合生存曲线
surv_fit <- survfit(surv_obj ~ best_threshold_data$risk_score)

# 绘制生存曲线
ggsurvplot(surv_fit, data = best_threshold_data, surv.median.line = "hv",
           pval = TRUE,                    # 显示p值
           xlab = "Time (days)", ylab = "Survival Probability",  # x轴和y轴标签
           legend.title = "",             # 图例标题为空
           break.x.by = 1000,             # x轴刻度间隔
           color = "strata",              # 根据分组着色
           palette = c("#bc5148", "#3090a1"))  # 自定义颜色

是不是比上面显著多啦!

cutoff包的logrank函数

# cutoff包的logrank函数

# 重新加载数据
best_threshold_data <- read.csv("./best_threshold_data.csv")

# 加载cutoff包
library(cutoff)

# 使用cutoff包的logrank函数来寻找最佳阈值
best_threshold_surv_2 <- logrank(data = best_threshold_data,
                                 time = "OS.time",  # 生存时间列名
                                 y = "OS",          # 生存事件列名
                                 x = "risk_score",  # 需要寻找阈值的变量列名
                                 cut.numb = 1,      # 截点个数
                                 n.per = 0.2,       # 分组后每组样本量占总样本量的最小比例
                                 y.per = 0.1,       # 分组后每组中较少结果的最小比例
                                 p.cut = 0.1,       # p值截断
                                 round = 5)         # 保留几位小数

# 打印找到的最佳阈值及相关信息
best_threshold_surv_2[order(best_threshold_surv_2$pvalue, decreasing = F), ]
#      cut1      n           n.per     y           y.per  pvalue p.adjust
# 1 4.420631 103/51 0.66883/0.33117 76/47 0.73786/0.92157 0.07617 7.08378 

# 根据找到的最佳阈值对数据进行分组
best_threshold_data$Group = ifelse(best_threshold_data$risk_score >= 
                                     best_threshold_surv_2[order(best_threshold_surv_2$pvalue, decreasing = F), ][1, 1],
                                   "High Risk","Low Risk")

# 创建生存对象(Surv对象),包含生存时间和生存状态信息
surv_obj <- Surv(time = best_threshold_data$OS.time, event = best_threshold_data$OS)

# 使用survfit()函数拟合生存曲线
surv_fit <- survfit(surv_obj ~ best_threshold_data$Group)

# 绘制生存曲线
ggsurvplot(surv_fit, data = best_threshold_data, surv.median.line = "hv",
           pval = TRUE,                    # 显示p值
           xlab = "Time (days)", ylab = "Survival Probability",  # x轴和y轴标签
           legend.title = "",             # 图例标题为空
           break.x.by = 1000,             # x轴刻度间隔
           color = "strata",              # 根据分组着色
           palette = c("#bc5148", "#3090a1"))  # 自定义颜色

虽然不如刚刚那个,但也比原来好多啦是不!

X-Tile

这个我就不详细介绍啦!有兴趣的小伙伴们可以去点点点试试!

官网:https://medicine.yale.edu/lab/rimm/research/software/

教程:https://cloud.tencent.com/developer/news/283239

小小总结

  1. survminer包的surv_cutpoint函数
    • 基于maxstat包的maxstat.test函数计算出Maximally Selected Rank Statistics,通过最大化差异来确定最佳阈值。
    • 可以同时计算多个变量的最佳截断值。
    • 一次只能找到一个最佳截断值,无法同时找到多个截断值。
  2. cutoff包的logrank函数
    • 在自由度固定的情况下,计算log-rank卡方值,通过检验分组之间的差异来确定最佳阈值。
    • 提供了不同的函数用于计算多种模型的截断点,例如cox、linear、logit等,每种模型都使用对应的统计检验来确定阈值。
    • 一次只能找到一个最佳截断值。
  3. X-tile软件
    • 基于log-rank卡方值来确定最佳截断值,将数据分为不同组,可以选择找到一个或两个最佳截断值,以将数据分成两组或三组。
    • 一次只能计算一个变量的最佳阈值。

大家自行选择哟!依据个人经验,俺更推荐survminer包的surv_cutpoint函数,它在多数情况下表现都还不戳!个人观点,仅供参考!最终解释权归小蛮要所有!

文末碎碎念

那今天的分享就到这里啦!我们下期再见哟!

最后顺便给自己推荐一下嘿嘿嘿!

如果我的分享对你有用的话,欢迎关注点赞在看转发分享阿巴阿巴阿巴阿巴巴巴!这可是我的第一原动力!

蟹蟹你们的喜欢和支持!!!

啊对!如果小伙伴们有需求的话,也可以加入我们的交流群:一定要知道 | 永久免费的生信交流群终于来啦!

还有兴趣的话,也可以看看我掏心掏肺的干货满满 | 给生信小白的入门小建议 | 掏心掏肺版!绝对干货满满!

如果有小伙伴对付费分析有需求的话,可以看看这里:个性化科研服务 | 付费分析试营业正式启动啦!定制你的专属生信分析!可提供1v1答疑!

入群链接后续可能会不定期更新,主要是因为群满换码或是其他原因,如果小伙伴点开它之后发现,咦,怎么失效啦!不要慌!咱们辛苦一下动动小手去主页的要咨询那里,点击进交流群即可入群!

参考资料
  1. https://cloud.tencent.com/developer/article/1875291
  2. https://mp.weixin.qq.com/s/pOgbzHZNQC8z7KdrrrNd1A
  3. https://mp.weixin.qq.com/s/TB43jWO7CX8_o2eUXWl1Fw

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

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

相关文章

DAY by DAY 史上最全的Linux常用命令汇总----man

man是按照手册的章节号的顺序进行搜索的。 man设置了如下的功能键&#xff1a; 功能键 功能 空格键 显示手册页的下一屏 Enter键 一次滚动手册页的一行 b 回滚一屏 f 前滚一屏 q 退出man命令 h 列出所有功能键 /word 搜索word字符串 注意&#xff1a…

多数问题求解之蒙特卡洛与分治法

多数问题&#xff08;Majority Problem&#xff09;是一个有多种求解方法的经典问题&#xff0c;其问题定义如下&#xff1a; 给定一个大小为 n n n的数组&#xff0c;找出其中出现次数超过 n / 2 n/2 n/2的元素 例如&#xff1a;当输入数组为 [ 5 , 3 , 5 , 2 , 3 , 5 , 5 ] […

Qt 如何搭建Lua的运行环境

一、Lua简介 Lua 是一种强大的、高效的、轻量级的、可嵌入的脚本语言。它支持过程&#xff08;procedural&#xff09;编程、面向对象编程、函数式编程以及数据描述。Lua 是动态类型的&#xff0c;运行速度快&#xff0c;支持自动内存管理&#xff0c;因此被广泛用于配置、脚本…

java-集合工具类Collections

我们在使用它的时候记得导包 常见API 我们就简单看看第一第二个方法&#xff0c;代码如下&#xff0c;其余的知道用就行

基于经验模式分解和小波阈值的自适应降噪研究_杨铮

目的 针对轴承信号在采集过程中容易受到不同环境下噪声干扰&#xff0c;提出EMD分解结合小波阈值的自适应降噪的方法&#xff0c;对轴承振动信号进行降噪处理&#xff0c;提取出所需要的振动信号。方法 首先对含有噪声的轴承信号进行EMD分解&#xff0c;得到n个IMF并进行小波阈…

GUROBI之数学启发式算法Matheuristics

参考运小筹的帖子&#xff1a;优化求解器 | Gurobi 数学启发式算法&#xff1a;参数类型与案例实现 - 知乎 (zhihu.com) 简言之&#xff0c;数学启发式是算法就是数学规划和启发式算法的融合&#xff0c;与元启发式算法相比&#xff0c;数学启发式算法具有更强的理论性。 在GUR…

C++初阶

1.缺省参数 给缺省参数的时候&#xff0c;不能声明&#xff0c;定义同时给&#xff0c;只能声明的时候给缺省参数&#xff0c;同时给程序报错&#xff1b; 2.函数重载 C语言不允许同名函数的存在&#xff0c;函数名不能相同&#xff0c;C引入函数重载&#xff0c;函数名可以…

SOLIDWORKS 2024新版价格 SOLIDWORKS2024专业版白金版多少钱?

达索 SOLIDWORKS 一直以来都致力于让每位设计师和工程师的设计都触手可及。SOLIDWORKS贯彻的使命就是通过功能强大且易于使用的产品开发解决方案&#xff0c;在创造、协作和提供创新的产品体验方面助您一臂之力。SOLIDWORKS 2024延续了这一期望&#xff0c;同时开启了强化使用S…

Altium Designer快速入门及项目实战教程之PCB设计(四)

一、引言 在我们的Altium Designer系列教程中&#xff0c;我们已经一起走过了软件界面的初识、原理图的绘制&#xff0c;以及元件库的建立。今天&#xff0c;我们将进入这一系列教程的高潮部分——PCB设计。 PCB设计不仅是电子产品开发过程中的核心&#xff0c;也是检验一个电…

Maven项目添加依赖

maven仓库&#xff1a;Maven Repository: Search/Browse/Explore (mvnrepository.com) 1.在maven仓库中搜素自己想要的依赖&#xff0c;选择合适的版本号&#xff0c;复制以下内容(依赖坐标)。 2.在pom.xml中把复制的粘贴进去。刷新。&#xff08;注意内容要放在dependencies双…

修改表结构

目录 修改表结构 创建数据表插入数据 修改已有列 修改 member 表的 name 列的定义 为表增加列 增加一个 address 列&#xff0c;这个列上不设置默认值 增加一个 sex 列&#xff0c;这个列上设置默认值 删除表中的列 删除 sex 列 Oracle从入门到总裁:​​​​​​https…

西门子PLCS7-1200位逻辑指令的使用

1.LAD触点 常开触点的位值为1时&#xff0c;常开触点将闭合&#xff08;ON&#xff09;。位值为0时&#xff0c;常开触点将闭合&#xff08;OFF&#xff09;。 常闭触点的位值为1时&#xff0c;常闭触点将闭合&#xff08;OFF&#xff09;。位值为0时&#xff0c;常闭触点将闭…

一文掌握mysql中的查询语句

目录 1. 聚合查询1.1 聚合函数1.2 GROUP BY子句1.3 HAVING 2. 联合查询2.1 内连接2.2 外连接2.3 自连接2.4 子查询2.5 合并查询 1. 聚合查询 1.1 聚合函数 常见的统计总数、计算平局值等操作&#xff0c;可以使用聚合函数来实现&#xff0c;常见的聚合函数有&#xff1a; 函…

从0到1:如何用AI完成高质量的科研论文写作?

人工智能革命&#xff1a;如何让聊天机器人更懂你 人工智能正在以其强大的数据处理和语言生成能力改变世界。在学术界&#xff0c;大语言模型&#xff08;LLM&#xff09;为科学交流带来了一种新的工具。我们旨在有效地将AI工具与学术写作相结合&#xff0c;以更有效和更有影响…

关于图在推荐系统中的研究

业界最新的论文 Intent-aware Recommendation via Disentangled Graph Contrastive Learning 作者&#xff1a;Yuling Wang, Xiao Wang, Xiangzhou Huang, Yanhua Yu, Haoyang Li, Mengdi Zhang, Zirui Guo, Wei Wu 地址&#xff1a;https://arxiv.org/abs/2403.03714 论文…

Java毕业设计-基于spring boot开发的实习管理系统-毕业论文+答辩ppt(附源代码+演示视频)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1.开发说明2.需求分析3、系统功能结构 三、系统实现展示1、前台功能模块2、后台功能模块2.1 管理员功能2.2 教师功能2.3 学生功能2.4 实习单位功能 四、毕设内容和源代码获取总结 Java毕业设…

Ps:清理

清理 Purge命令位于“编辑”菜单下&#xff0c;它主要用于释放 Photoshop 使用的内存资源&#xff0c;有助于提高系统的性能。 通过使用“清理”命令&#xff0c;用户可以有效管理 Photoshop 的资源使用&#xff0c;特别是在处理大型文件或进行长时间编辑会话时。 定期清理可以…

科研学习|论文解读——一种修正评分偏差并精细聚类中心的协同过滤推荐算法

知网链接 一种修正评分偏差并精细聚类中心的协同过滤推荐算法 - 中国知网 (cnki.net) 摘要 协同过滤作为国内外学者普遍关注的推荐算法之一&#xff0c;受评分失真和数据稀疏等问题影响&#xff0c;算法推荐效果不尽如人意。为解决上述问题&#xff0c;本文提出了一种改进的聚类…

web项目的搭建

使用Webstorm并创建Next.js文件 1、配置nodejs环境、安装webstorm【配置node.js可以使用nvm去管理nodejs的版本】 2、需要破解webstorm&#xff0c;可能会导致原本的idea失效&#xff0c;注册码过期 3、taobao的npm过期&#xff0c;导致npm is sass执行不成功&#xff0c;需…

openAI key 与ChatGPTPlus的关系,如何升级ChatGPTPLus

一、前言 先详细介绍一下Plus会员和Open API之间的区别&#xff1a; 实际上&#xff0c;这两者是相互独立的。举例来说&#xff0c;虽然您开通了Plus会员&#xff0c;并不意味着您就可以使用4.0版本的API。尽管这两个账户可以是同一个&#xff0c;但它们是完全独立的平台。 …