马尔科夫链既往我在系列文章《手把手带你复现一篇一区9.1分肌少症和马尔科夫链》的文章已经有过介绍,它的特点是:"未来只取决于现在,与过去无关"。主要研究的是状态和概率的变化。比如我在手机打字:你nih,会出现很多选项:你好,你和,你还等等,这就是软件统计了咱们打各个字符的概率,这个就是马尔科夫链的一个应用。自然语言处理:用马尔科夫链生成文本(比如根据前一个词预测下一个词)。

在既往文章中咱们介绍的是由吸收状态的马尔科夫链,问题来了,什么是吸收状态的马尔科夫链?这个就是相当于有一个结局变量,比如在《手把手带你复现一篇一区9.1分肌少症和马尔科夫链》这篇文章中死亡是它的结局变量,分析了肌少症在不同时期的转换最后死亡的关系,没有结局变量也是能做的,研究的是协变量对概率转换的影响,下面我来演示一下
先导入数据和R包
r
library(scitable)
library(ggscitable)
library(tidyverse)
setwd("E:/公众号文章2025年/charls+马尔科夫链")
bc2 <-read.csv('bcmsm.csv',header=T)
str(bc2)

这个是个非常简单的数据,而且是模拟数据,不对临床操作产生建议,time是时间,state这里是我自定义的,我把肾功能的肌酐按低到高,把肾功能分成了3个状态,然后看这三个状态转换的概率,drinkl:是否饮酒。这里我们仍然使用一阶的马尔科夫链,
下面咱们进行分析,其实很简单,和之前的参数差不多,添加一个参数death_state=F就可以了
r
out2<-sci_msm(data=bc2,ID="ID",time = "time",state = "state",digits = 7,death_state=F,
username=username,token=token)
咱们把相关数据提取出来
r
tb2<-out2[["tb2"]]

看下转移人数
r
out2[["statetable"]]

看下不同年份的转移率,这里没有吸收状态,要定义一个观察年限,咱们这里是长年限是4年,所以我定义成4年
r
probability.msm(out2,time = c(2,4),tot = 4)

结果还生成了平均时间和总停留时间,下面咱们来看下喝酒对肾功能转换的影响,在cov这里把喝酒添加进去
r
out3<-sci_msm(data=bc2,ID="ID",time = "time",state = "state",digits = 7,death_state=F,cov="drinkl",
username=username,token=token)
基础的分析和前面一样,我来介绍概率分析,假设我想知道喝酒对状态1(就是没有肾病患者)的肾功能转换影响,state=1表示观察状态1的转变,没有吸收状态要指定观察总时间tot=4,
r
#没有吸收状态要指定观察总时间tot=4,
out4<-probability.msm(out3,time = c(1,2,3,4),cov="drinkl",state=1,tot=4)
r
提取数据
data5<-out4[["data"]]

上图可以看到各种转变,假设我对中间的1转成2感兴趣
r
data5$cov<-as.factor(data5$cov)
data5$cov<-factor(data5$cov,labels = c("nodrinkl", "drinkl"))
names(data5)<-c("State11","State12","State13","t","cov")
colors <- c("nodrinkl" = "#FFD1DC", "drinkl" = "#FF4D4D")
绘图
r
ggplot(data5, aes(x = t, y = State12, color = cov, group = cov)) +
geom_point(size = 5) +
geom_line(size = 1.2) +
scale_color_manual(values = colors) +
labs(title = "State1 → State2", x = "observation interval", y = "possibility ") +
theme_minimal() +
theme(
legend.title = element_text(size = 12, face = "bold"),
legend.text = element_text(size = 10),
plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12),
legend.position = c(0.85, 0.2),
panel.grid.minor = element_blank()
) +
guides(color = guide_legend(title = NULL))

可以看到,相对于没有喝酒,喝酒更容易(更高概率)导致肾功能向恶化转变(模拟数据不构成临床指导)