You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用R计算基于linear mixed effects model的Longitudinal repeated measures study的样本量

使用R计算基于linear mixed effects model的Longitudinal repeated measures study的样本量

Hey 你好呀!我完全懂你的困扰——找了好多R的样本量计算例子都是有分组的,偏偏你的研究是单组重复测量,要验证患者在3次随访里能不能稳住基线得分,而且你对R还不太熟。刚好我可以给你一步步演示怎么用线性混合效应模型(LMM)来搞定这个计算,都是实操的代码,你跟着跑就行~

先理清楚你的核心参数:

  • 单组,每个患者有4个时间点(基线+3次随访)
  • 基线得分均值20,标准差4.5
  • 临床意义上的得分下降是6分(也就是如果下降超过6分,就认为有临床影响)
  • 研究目的:确认患者随访时的得分是否维持在基线水平(要么检测是否出现临床相关下降,要么证明下降没到这个程度)

第一步:安装并加载需要的包

我们要用lme4来拟合混合模型,simr来做样本量的模拟和power分析——模拟法是单组重复测量LMM最直观的样本量计算方式,因为没有现成的简单公式,而且灵活度高,适合你这种场景。

# 安装包(第一次用的时候跑)
install.packages(c("lme4", "simr"))

# 加载包
library(lme4)
library(simr)

第二步:构建模拟数据集(先假设一个初始样本量)

我们先从一个小的初始样本量(比如20人)开始,构建符合你研究场景的模拟数据,这样才能拟合模型做后续的power分析。这里我会把你给的参数都加进去,还会考虑个体间的变异(毕竟不同患者的基线得分肯定有差异):

# 设定核心参数,你可以根据你的研究调整!
n_initial <- 20  # 先假设20个样本,后面再找最优值
time_points <- c(0,1,2,3)  # 0=基线,1/2/3=三次随访
baseline_mean <- 20  # 基线均值
clin_drop <- 6  # 临床相关的下降幅度
sd_individual <- 3  # 个体间的变异SD(不同患者基线的差异)
sd_residual <- sqrt(4.5^2 - sd_individual^2)  # 个体内的残差SD(同一个患者不同时间点的波动)

# 生成模拟数据
set.seed(123)  # 固定随机种子,让结果可重复
dat <- expand.grid(id = 1:n_initial, time = time_points)  # 每个患者对应4个时间点
dat$rand_int <- rnorm(n_initial, 0, sd_individual)[dat$id]  # 给每个患者加个体随机截距
# 计算得分:基线得分=基线均值+个体截距;随访时下降clin_drop,再加上残差波动
dat$score <- baseline_mean + dat$rand_int + ifelse(dat$time == 0, 0, -clin_drop) + rnorm(nrow(dat), 0, sd_residual)

第三步:拟合线性混合效应模型

我们拟合一个带随机截距的LMM,把时间作为固定效应(因为我们要检测时间对得分的影响):

# 拟合模型
model <- lmer(score ~ time + (1|id), data = dat)
# 看看模型结果,确认参数符合我们的设定
summary(model)

第四步:用simr做Power分析和样本量估算

现在我们要计算,当真实存在6分的下降时,不同样本量下我们有多大的概率能检测到这个差异(也就是power),然后找到power达到80%(行业通用标准)的最小样本量。

# 先看初始样本量(20人)的power
powerSim(model, test = fixed("time"))

# 模拟不同样本量的power变化(从10到100,每次加10)
power_curve <- powerCurve(model, test = fixed("time"), along = "id", breaks = seq(10, 100, 10))
# 可视化power曲线,更直观
plot(power_curve)

# 直接计算达到80% power的最小样本量
required_n <- findPower(model, test = fixed("time"), target = 0.8, along = "id")
print(required_n)

一些你可能需要调整的细节

  • 个体间变异的设定:我这里设的sd_individual=3,如果你不确定你的研究里个体差异有多大,也可以把它设为0(这时候残差SD直接用4.5),不过现实中不同患者的基线肯定有差异,所以尽量根据类似研究的结果调整这个值。
  • 等效性检验vs优效性检验:上面的代码是检测“是否存在临床相关的下降”(优效性检验),如果你的研究目的是证明患者能维持基线(即下降不超过6分),这属于等效性检验,代码要稍微调整:
    # 自定义等效性检验函数:检验时间效应的系数是否大于-6(即下降不超6分)
    eq_test <- function(mod) {
      time_coef <- fixef(mod)["time"]
      time_se <- se.fixef(mod)["time"]
      t_stat <- (time_coef + 6) / time_se  # 检验H0: time <= -6 vs H1: time > -6
      p_val <- 1 - pt(t_stat, df = df.residual(mod))
      return(p_val)
    }
    
    # 假设真实情况是没有下降(time系数为0),计算能证明等效的power
    fixef(model)["time"] <- 0
    powerSim(model, test = eq_test)
    
  • 缺失值考虑:如果你的研究预计会有缺失数据,可以用simraddMissing函数模拟缺失情况,再重新计算power,这样结果更贴合实际。

最后碎碎念

其实单组重复测量的样本量计算没有绝对的“标准答案”,因为很多参数(比如个体间变异)都是基于假设的,你可以多调整几次参数,看看样本量的变化范围,这样得到的结果更稳妥。如果你跑代码的时候遇到报错,或者对参数设定有疑问,随时提出来就行!

火山引擎 最新活动