一键自动生成符合预期统计结果的医学研究数据库:模拟研究的理论和实现

文摘   科学   2024-11-02 09:27   上海  

本文介绍如何用利用文本提示语,命令 MSTATA 医学统计机器人,生成研究者想要的医学研究数据库,此数据库能够得到预期的统计分析假设结果。广泛用于临床研究领域,数据锁库后,真实数据未解锁前的模拟分析、方法学探索、和统计代码调试等多个领域。


为什么要自动生成医学研究数据库


在医学研究中,数据模拟(simulation)分析是进行科学探索和设计的关键步骤。模拟分析是指利用人工生成的数据来构建研究数据库,这些数据并不是真实的数据,而是通过设定特定的分布和特征进行生成的。这种模拟数据库的生成在正式研究数据锁库、数据解锁前,发挥着至关重要的作用。


在医学研究的筹备阶段,往往需要使用模拟数据来完成研究设计书的撰写、CRF(病例报告表)设计、统计分析计划书的制定、dry run(统计分析代码的预调试)等多项工作。这不仅能帮助科研人员测试设计的合理性,还能提前发现潜在问题,为后续数据分析提供依据和保障。


在临床试验领域,模拟数据能提供丰富的应用场景。例如,通过设置分布参数和特定关联模式,我们可以模拟患者组的治疗效果,验证不同统计方法的适用性和表现,从而选择最合适的分析方法。这些步骤在设计研究时具有重要意义。


通过 pubmed 检索,我们发现大量的论文是通过随机生成的模拟数据,进行统计方法学探索,以及对临床研究的验证。在药物研发领域,生成模拟数据,是高级统计师必备的技能,行业里有一套系统的理论体系和指导纲要,关于如何模拟和利用虚拟数据。


如何在人工智能时代利用提示语命令生成模拟数据


在传统的统计学研究中,数据模拟是一项复杂且技术要求高的工作,往往由专业的统计师根据严谨的数学模型来完成。这些统计师需要深入理解变量之间的关系,设计出满足研究需求的数据结构,以确保生成的数据具有良好的代表性和科学性。


传统模拟数据的生成方式


以往,生成模拟数据主要依赖于专业统计师的知识和编程技能。这一过程通常涉及:


设定数据分布:例如年龄可以服从正态分布,二分类变量(如是否吸烟)可以服从二项分布,生存时间可能符合Weibull分布等。每个变量的分布特征需精确设定,才能接近真实数据。


变量关系的设定:在数据模拟中,不同变量之间往往存在关联。例如,在肺癌研究中,年龄和死亡可能呈现正相关;在儿童肥胖研究中,活动量和肥胖率负相关。专业统计师会通过设定相关系数矩阵、协方差矩阵等,来模拟不同变量之间的关联性。


复杂的数学模型:如果涉及多种变量的交互效应,生成数据需要建立多维模型。例如,生成一个多元正态分布的数据集时,必须设定协方差矩阵以确保不同变量间的相关性。相对简单的模拟代码可能包括多行甚至数十行数学运算,代码的复杂程度大大增加了数据模拟的门槛。


这类模拟需要深入的统计学知识,尤其是对数据分布、变量相关性的掌握,以及编程语言(如R或Python)的熟练运用。因此,非专业人士很难自行生成合理的数据,模拟过程主要依赖于专业人士。


人工智能时代的提示语数据生成


如今,随着技术的进步,生成模拟数据的门槛大大降低。得益于自然语言处理技术,普通人也可以通过提示语命令快速生成符合特定要求的模拟数据集,免去了复杂的编程工作。提示语生成模拟数据的过程大致如下:


自然语言描述:用户只需用简单的自然语言描述数据需求,例如“请生成一个包含1000例样本的高血压数据集,变量包括年龄、性别、BMI、收缩压等。”通过清晰明了的描述,即可定义变量的基本信息,MSTATA 医学统计机器人会自动理解并设定数据结构。


系统自动推断关系:在提示语中,用户可以指明不同变量之间的关系,例如“低运动量组的肥胖风险比高运动量组高”。MSTATA 医学统计机器人会据此自动推断变量之间的相关性,并通过调整数据分布或权重实现这种关联,而不需要用户编写任何代码。


算法自动化生成数据:MSTATA 医学统计机器人会根据用户的提示语自动调用适合的数据生成算法,生成具有一定科学性和合理性的模拟数据。系统能够将复杂的数学公式和变量关系“隐藏”在系统的运算过程中,使生成过程更为直观。


软件通过www.mstata.com 访问,进入软件后,进入“数据准备” 菜单,选择 “让MSTATA机器人根据您的命令自动生成您期望的科研数据”






示例一:生成肺癌临床数据


提示语:


请给我生成一个2180例样本的,包含年龄、性别、是否吸烟、是否饮酒、临床分期、治疗组别、随访时间和生存状态的临床肺癌数据集,治疗组别包括化疗组和免疫治疗组;年龄为正态分布,61±11岁,不得超过87岁,不得低于31岁;性别男性62%,女性38%;男性吸烟人数约占65%,女性吸烟人数约占28%;男性饮酒人数约占62%,女性饮酒人数约占48%;临床分期只包括III期和IV期,IV期占60%;随访时间的单位为天,为整数,最大随访时间不得超过720天,随访时间服从 Weibull 分布,化疗组1150例,中位生存时间约6个月,免疫治疗组1030例,中位生存时间约10个月;生存状态1代表死亡,0代表censor,随访时间等于720天的人生存状态全部设置为0;其他我没有提到的变量你自由发挥。


这段提示语的设计思路:


生成样本的年龄:设定年龄的分布为正态分布(61±11岁),并限定年龄范围在31至87岁。

生成性别和吸烟情况:通过设定性别的比例,再进一步生成与性别相关的吸烟概率。

生成随访时间和生存状态:使用Weibull分布生成随访时间,并设定各治疗组的中位生存时间。

此方法不仅保证了数据的真实感,还使生成的数据适合特定临床试验的设计需求。



通过此提示语,MSTATA 医学统计机器人生成了一个数据库,可以直接下载,并附上了一段代码,该代码使用R语言生成满足条件的模拟数据:


library(MASS)

# 设置随机种子,以便结果可复现set.seed(123)

# 生成样本数量n <- 2180

# 生成年龄数据(正态分布,61±11岁)age <- round(rnorm(n, mean = 61, sd = 11))

# 限制年龄范围age[age < 31] <- 31age[age > 87] <- 87

# 生成性别数据(男性62%,女性38%)gender <- sample(c("男", "女"), n, replace = TRUE, prob = c(0.62, 0.38))

# 生成吸烟数据smoking <- ifelse(gender == "男", sample(c(1, 0), n, replace = TRUE, prob = c(0.65, 0.35)), sample(c(1, 0), n, replace = TRUE, prob = c(0.28, 0.72)))

# 生成饮酒数据drinking <- ifelse(gender == "男", sample(c(1, 0), n, replace = TRUE, prob = c(0.62, 0.38)), sample(c(1, 0), n, replace = TRUE, prob = c(0.48, 0.52)))

# 生成临床分期数据(III期和IV期,IV期占60%)stage <- sample(c("III", "IV"), n, replace = TRUE, prob = c(0.4, 0.6))

# 生成治疗组别(化疗组和免疫治疗组)treatment <- sample(c("化疗组", "免疫治疗组"), n, replace = TRUE, prob = c(1150/2180, 1030/2180))

# 生成随访时间(服从Weibull分布,最大随访时间720天)follow_up_time <- round(rweibull(n, shape = 1.5, scale = 200))follow_up_time[follow_up_time > 720] <- 720 # 确保随访时间不超过720

# 生成生存状态(0为censor,1为死亡)survival_status <- rep(1, n) # 默认全部为死亡survival_status[follow_up_time == 720] <- 0 # 随访时间720天的生存状态设置为0

# 设置生存状态基于治疗组和中位生存时间median_survival_chemo <- 180 # 6个月median_survival_immuno <- 300 # 10个月chemo_indices <- which(treatment == "化疗组")immuno_indices <- which(treatment == "免疫治疗组")

# 生成生存时间(基于中位生存时间的指数分布)survival_time <- c( rexp(length(chemo_indices), rate = log(2) / median_survival_chemo), rexp(length(immuno_indices), rate = log(2) / median_survival_immuno))

# 整合数据df <- data.frame( 年龄 = age, 性别 = gender, 是否吸烟 = smoking, 是否饮酒 = drinking, 临床分期 = stage, 治疗组别 = treatment, 随访时间 = follow_up_time, 生存状态 = survival_status)

# 调整生存状态for (i in seq_along(survival_time)) { if (survival_time[i] < follow_up_time[i]) { survival_status[i] <- 1 # 如果生存时间小于随访时间则设置为死亡 } else { survival_status[i] <- 0 # 否则为censor }}

# 更新数据框中的生存状态df$生存状态 <- survival_status

# 最终的数据集命名为dfprint(head(df)) # 打印前6行以验证结果




这段代码旨在生成一个模拟的临床数据集,包含年龄、性别、吸烟情况、饮酒情况、临床分期、治疗组别、随访时间和生存状态等变量。首先,代码加载了必要的库并设定随机种子,以确保生成的数据可重复。接着,设定样本量为2180人,通过服从正态分布的年龄生成数据,并将年龄限制在合理的范围内,以确保数据的真实感。性别变量根据男性62%、女性38%的比例分布生成。为了模拟更细致的特征,代码进一步生成吸烟和饮酒数据,通过性别来设定不同的吸烟和饮酒概率。例如,男性的吸烟和饮酒概率分别高于女性,以反映现实中两性习惯的差异。


临床分期和治疗组别数据也按设定的比例生成,其中大多数患者为IV期,且化疗组与免疫治疗组人数符合设定比例。随访时间使用Weibull分布生成,确保时间变量的合理性,并将其限制在720天内以模拟临床试验的最长随访期。生存状态则初始设置为1(死亡),并将随访时间为720天的患者设置为0(未发生事件),即在随访期结束时未发生死亡事件的患者标记为“未结局”。


进一步地,代码根据不同治疗组的中位生存时间(化疗组6个月,免疫治疗组10个月),生成基于指数分布的生存时间。指数分布的速率参数由中位生存时间确定,从而使生成的数据接近设定的生存时间。最后,将所有变量合并至数据框,并根据生存时间与随访时间的关系来调整生存状态:若生存时间小于随访时间,标记为1(已发生事件),否则标记为0(未发生事件)。通过这种方法,生成的数据不仅在单个变量上保持合理性,还确保了变量间的关系符合临床研究的特征。最终,代码输出的数据集具备良好的模拟效果,适用于后续的统计分析和研究设计验证。





示例二:生成儿童肥胖症数据


提示语:


请生成一个包含1200例儿童样本的肥胖症临床数据集,变量包括年龄、性别、日常活动量、家庭收入水平、零食摄入频率(低、高)以及是否肥胖。年龄在6至16岁之间,均值为11岁,标准差为3岁;男孩占53%,女孩占47%;日常活动量分为高、低两类;家庭收入分为高、低两类;设置低活动量组与高活动量组的肥胖风险比(OR)为2.0。零食摄入频率高与低组的肥胖风险比(OR)为3.3。家庭收入高组比低组的肥胖风险比(OR)为1.1。请从OR值倒推零食摄入频率的数据、活动量的数据和家庭收入的数据。其他变量可自由生成。


在此提示中,MSTATA 医学统计机器人自动生成了R代码,该代码逐步生成儿童的年龄、性别、活动量、家庭收入水平及肥胖状态,并根据设定的OR值来调整每个变量的肥胖风险,最终模拟出合理的肥胖数据。


此生成过程展示了如何通过OR倒推变量,确保数据集中的每个变量不仅符合生成条件,还能准确反映特定的临床关系。



返回的代码:


# 检查并安装必要的R包if (!require(dplyr)) {  install.packages("dplyr")}

set.seed(123) # 设置随机种子以保证结果可重复

# 生成1200个儿童样本的年龄数据ages <- rnorm(1200, mean = 11, sd = 3) # 年龄均值11,标准差3ages <- round(ages) # 四舍五入到最近的整数ages <- pmin(pmax(ages, 6), 16) # 确保年龄在6到16岁之间

# 生成性别数据(男孩53%,女孩47%)gender <- sample(c("男孩", "女孩"), 1200, replace = TRUE, prob = c(0.53, 0.47))

# 生成家庭收入水平数据(高收入占50%,低收入占50%)income_level <- sample(c("高", "低"), 1200, replace = TRUE, prob = c(0.5, 0.5))

# 生成日常活动量数据,先随机生成,然后根据活动量影响肥胖的情况进行调整activity_level <- sample(c("高", "低"), 1200, replace = TRUE, prob = c(0.5, 0.5))

# 计算肥胖的概率obesity_prob <- numeric(1200)

for (i in 1:1200) { if (activity_level[i] == "低") { obesity_prob[i] <- 0.4 # 低活动量组设定基础肥胖概率 } else { obesity_prob[i] <- 0.2 # 高活动量组设定基础肥胖概率 } if (income_level[i] == "低") { obesity_prob[i] <- obesity_prob[i] * 1.1 # 家庭收入低组增加10% }}

# 根据零食摄入频率影响肥胖snack_freq <- sample(c("低", "高"), 1200, replace = TRUE, prob = c(0.7, 0.3))for (i in 1:1200) { if (snack_freq[i] == "高") { obesity_prob[i] <- obesity_prob[i] * 3.3 # 高频零食摄入组 }}

# 随机生成肥胖的实际情况obesity_status <- rbinom(1200, 1, pmin(1, obesity_prob))

# 合并所有变量成 data framedf <- data.frame( 年龄 = ages, 性别 = gender, 日常活动量 = activity_level, 家庭收入水平 = income_level, 零食摄入频率 = snack_freq, 是否肥胖 = as.factor(obesity_status))

# 查看生成的数据框的前几行head(df)



这段代码用于生成一个模拟的儿童肥胖症数据集,包含年龄、性别、日常活动量、家庭收入水平、零食摄入频率和肥胖状态等变量。首先,代码检查并安装必要的 dplyr 包,以确保生成和操作数据时具备所需的功能。随机种子 set.seed(123) 确保每次运行时的结果一致,保证数据的可重复性。


然后,代码生成了1200个儿童的年龄数据,设置为均值为11岁,标准差为3岁,模拟出一个符合真实分布的年龄群体。为了使年龄合理,代码对数据进行了截断,确保所有年龄在6至16岁之间。


接下来,代码生成了性别数据,设定男孩的比例为53%,女孩为47%。家庭收入水平数据按50%比例分为“高收入”和“低收入”两个类别。日常活动量数据同样分为“高”和“低”,初始分布为50%。


为了计算肥胖概率,代码首先创建一个空向量 obesity_prob 用于存储每个样本的肥胖概率。根据活动量不同,低活动量组的基础肥胖概率设为0.4,而高活动量组设为0.2,反映低活动量可能导致肥胖风险增加的假设。家庭收入也影响肥胖概率,对于低收入组,肥胖概率增加10%。


接着,代码生成零食摄入频率数据,设定30%的样本属于“高频”组。高频摄入零食的样本肥胖风险进一步增加至3.3倍。这些设定模拟了在肥胖生成中各种生活习惯对风险的累加效应。


最后,通过二项分布 rbinom 函数生成肥胖状态,利用调整后的肥胖概率 obesity_prob 作为事件概率,使最终肥胖状态为1(肥胖)或0(不肥胖)。所有变量被合并至数据框 df,形成完整的数据集。生成的数据框被输出,以供验证。此方法不仅生成了具有代表性的样本,还通过多层次的因素控制,反映了不同变量对肥胖风险的综合影响,使数据更加贴近现实。




示例三:生成高血压数据


提示语:


请生成一个包含1000例样本的高血压临床数据集,变量包括年龄、性别、BMI、收缩压、是否服用降压药、服药依从性、饮酒情况、运动频率和糖尿病史。年龄均值为58岁;男性占50%,女性占50%;服药依从性分为高、低两类;设置高依从性组的收缩压均值比低依从性组低10 mmHg。年龄越大,收缩压也越高。运动频率高组比低组收缩压均值低20,糖尿病组比非糖尿病组收缩压低20。其他变量可自由生成。


本提示旨在生成含有多种健康相关信息的高血压数据集。AI代码生成的关键步骤如下:


年龄和性别的生成:设定年龄均值为58岁,性别比例为1:1。

BMI和运动频率的生成:BMI按正态分布生成,运动频率分为高和低。

收缩压计算:综合年龄、依从性、运动频率和糖尿病状态等因素,动态生成收缩压,确保每个变量都符合设置的条件。

通过此案例,我们可以看到AI生成数据的逻辑严谨性和灵活性,在保证数据生成条件的基础上,还能根据研究需求对变量进行精细调整。




# 检查并安装必要的R包if (!requireNamespace("dplyr", quietly = TRUE)) {  install.packages("dplyr")}if (!requireNamespace("magrittr", quietly = TRUE)) {  install.packages("magrittr")}

# 加载必要的R包library(dplyr)library(magrittr)

# 设置随机种子以便结果可复现set.seed(123)

# 生成样本数量n <- 1000

# 生成年龄、性别、BMI、运动频率、饮酒情况、糖尿病历史age <- rnorm(n, mean = 58, sd = 10) %>% round(0) # 平均58岁,标准差10gender <- sample(c("男性", "女性"), n, replace = TRUE, prob = c(0.5, 0.5))BMI <- rnorm(n, mean = 25, sd = 4) # 平均BMI为25,标准差4exercise_freq <- sample(c("高", "低"), n, replace = TRUE) # 运动频率alcohol_use <- sample(c("是", "否"), n, replace = TRUE) # 饮酒情况diabetes_history <- sample(c("是", "否"), n, replace = TRUE, prob = c(0.2, 0.8)) # 糖尿病历史,20%是,80%否

# 生成服用降压药情况,依从性medication <- sample(c("是", "否"), n, replace = TRUE, prob = c(0.6, 0.4)) # 60%服药adherence <- ifelse(medication == "是", sample(c("高", "低"), sum(medication == "是"), replace = TRUE), NA) # 服药依从性

# 计算收缩压sys_bp <- 120 + (age - 58) * 0.5 # 基础收缩压 + 年龄影响,假设每增加一年收缩压增加0.5 mmHgsys_bp <- sys_bp + ifelse(adherence == "低", 10, 0) # 低依从性组收缩压高10 mmHgsys_bp <- sys_bp + ifelse(exercise_freq == "低", 20, 0) # 运动频率低组收缩压高20 mmHgsys_bp <- sys_bp - ifelse(diabetes_history == "是", 20, 0) # 糖尿病组收缩压低20 mmHg

# 将数据组合为一个数据框df <- data.frame( 年龄 = round(age), 性别 = gender, BMI = round(BMI, 1), 收缩压 = round(sys_bp), 是否服用降压药 = medication, 服药依从性 = adherence, 饮酒情况 = alcohol_use, 运动频率 = exercise_freq, 糖尿病史 = diabetes_history)

# 查看数据框的前几行head(df)




这段代码用于生成一个模拟的高血压患者数据集,包含年龄、性别、BMI、运动频率、饮酒情况、糖尿病史、是否服用降压药、服药依从性和收缩压等变量。以下是对代码的详细解析:


首先,代码检查并安装必要的 dplyr 和 magrittr 包,这两个包提供了数据操作和管道操作的工具。随后,通过 set.seed(123) 设置随机种子,以确保每次生成的数据相同,实现可重复性。


接着,代码设定样本量为1000。通过正态分布生成年龄,均值为58岁,标准差为10岁,模拟高血压患者的典型年龄分布。将年龄数据四舍五入为整数以符合实际。性别数据则按50%比例生成男性和女性样本。


BMI(体重指数)也通过正态分布生成,均值为25,标准差为4,以模拟患者BMI的自然变异。运动频率分为“高”和“低”两类,饮酒情况为“是”或“否”,而糖尿病历史根据20%的概率生成“是”,其余生成“否”,反映糖尿病在高血压人群中的一般发生率。


代码还生成了服用降压药和服药依从性数据。60%的样本被设定为服药,并随机指定高或低的服药依从性。未服药的样本依从性设为缺失值 NA。


然后,代码计算每个样本的收缩压。设定基础收缩压为120 mmHg,并假设每增加1岁收缩压增加0.5 mmHg,以年龄作为主要影响因素。收缩压进一步受到依从性、运动频率和糖尿病史的影响:低依从性组收缩压比高依从性组高10 mmHg,低运动频率组比高运动频率组高20 mmHg,而有糖尿病史的组收缩压降低20 mmHg。通过这种分步调整,模拟了影响收缩压的多重因素,使数据更符合实际的临床情况。


最终,所有变量被整合到一个数据框中,并输出前几行以便验证数据生成效果。整体而言,这段代码通过合理的分布设定和多重因素的层层控制,成功生成了一个具有代表性的高血压患者模拟数据集。



小结


在医学研究领域,通过MSTATA 医学统计机器人生成模拟数据不仅有效提升了研究设计的效率,还能加速分析流程的优化。利用MSTATA的医学统计机器人,我们可以通过精准的提示语设计,生成符合实际研究需求的模拟数据集,轻松探索不同统计方法的效果,从而推动医学科研的发展。



真实世界数据
介绍真实世界数据,真实世界研究和真实世界证据
 最新文章