(1)理论介绍
(2)实践操作
1.理论介绍
第一步:mice()函数默认生存5个填补后的数据集,由于填补过程的随机成分,这五个数据集略有差异。
第二步:with()函数可依次对插补后的5个完整数据集应用统计模型(包括线性模型和广义线性模型)
第三步:pool()函数将这些单独的分析结果整合为1组结果。最终模型的标准误和p值都将准确地反映出由于缺失值和多重插补而产生的不确定性。
那么多重插补会根据自动根据数据类型建立想用的模型插补缺失数据,那么常见的数据类型有4类,如下:
l连续变量:调用预测均值填补,"pmm",Predictive mean matching
l二分类变量:调用logistic回归模型填补,"logreg",Logistic regression imputation
l无序多分类变量:调用无序多分类logistic回归模型填补,"polyreg",Polytomous regression imputation for unordered categorical data
l有序多分类变量:调用比例优势模型填补,"polr",Proportional odds model
2.实践操作
目的:对ms2013里面的缺失数据采用mice包的常规方法进行填补
填补数据的整个流程有以下6步:
l第一步:导入数据
l第二步:整理数据
l第三步:查看数据集变量缺失情况
l第四步:mice函数填补数据
l第五步:填补后5个数据库按众数进行提取形成最终的数据库
l第六步:导出数据: 加载writexl包
代码实现
#导入数据
.libPaths()#查看R包位置
.libPaths("D:/Program File/R/R-4.3.2/library")#定义包安装位置
setwd("E:/02学习/经验/03R语言图形绘制/18R语言进行多重插补合集")#设置工作空间
getwd()#加载工作空间
#下载所需要的包
install.packages("mice")
install.packages("ranger")
install.packages("writexl")
library(lattice) #调入函数包
library(MASS)
library(nnet)
library(mice) #前三个包是mice的基础
library(foreign)
library(ranger)
#第一步:导入数据
data1<-read.csv("ms2013.csv",
as.is = TRUE,header = T,sep = ",", fileEncoding='utf-8')
str(data1)
#第二步:整理数据
#分类变量转为因子:是否吸烟、零食爱好、MS聚集、MS
a<-c("是否吸烟","零食爱好","MS聚集","MS")#填入需要转化的变量
data1[,a]<-lapply(data1[,a],as.factor)#转因子
#有序分类变量变为有序因子:饮酒频率
data1$饮酒频率<-factor(data1$饮酒频率,ordered=TRUE)
#第三步:查看数据集变量缺失情况
md.pattern(data1)
#将上述的缺失情况图导出
library(Cairo)
# Cairo.capabilities() # 检查当前电脑所支持的格式
# 1. 创建画布
Cairo::CairoPNG(
filename = "查看缺失图.png", # 文件名称
width = 100, # 宽
height = 50, # 高
units = "cm", # 单位
dpi = 300) # 分辨率
# 2. 绘图
#查看缺失图
p1<-md.pattern(data1)
# 3. 关闭画布
dev.off()
#第四步:mice函数填补数据
x<-mice(data1,m=5,seed=6666)
#m为默认插补数据集数量,5为默认值;seed为随机化种子数
x$method#查看每个变量所用的插补方法
x$imp#查看填补结果
#(2)填补后查看填补结果
#蓝色是原始数据,红色是插补的数据
stripplot(x,pch=19,cex=1.2,alpha=.3)
#它的局限性是只能查看数值型的变量,对于因子变量无法查看
#(3)插补数据统计分析,因变量自己指定,这里我的理解的是你可以依据
#统计分析的结果,看插补的哪个数据集对结局更有意义,然后选择相应的插补数据库;
fit<-with(x,glm(MS~吸烟年龄+是否吸烟+零食爱好+饮酒频率,family = binomial))
fit
#统计分析结果汇总
fit<-pool(fit)
summary(fit)
#第五步:但是一般来说,我们想要在填补后,对5个数据库进行提取形成最终的数据库
#本次按照5个数据库填补的众数形成最终的数据库
#(1)complete选择填补后的5个数据库
x1<-complete(x,action=01)
x2<-complete(x,action=02)
x3<-complete(x,action=03)
x4<-complete(x,action=04)
x5<-complete(x,action=05)
#(2)提取指定插补的变量和匹配变量:pid 吸烟年龄+是否吸烟+零食爱好+饮酒频率
library(tidyverse)
tb_data1<-select(x1,pid,吸烟年龄,是否吸烟,零食爱好,饮酒频率)
tb_data2<-select(x2,pid,吸烟年龄,是否吸烟,零食爱好,饮酒频率)
tb_data3<-select(x3,pid,吸烟年龄,是否吸烟,零食爱好,饮酒频率)
tb_data4<-select(x4,pid,吸烟年龄,是否吸烟,零食爱好,饮酒频率)
tb_data5<-select(x5,pid,吸烟年龄,是否吸烟,零食爱好,饮酒频率)
#(3)由于最终的数据库不能有重复变量名,因此除匹配变量外,其他变量需要依次改名
names(tb_data1)<-c("pid","吸烟年龄1","是否吸烟1","零食爱好1","饮酒频率1")
names(tb_data2)<-c("pid","吸烟年龄2","是否吸烟2","零食爱好2","饮酒频率2")
names(tb_data3)<-c("pid","吸烟年龄3","是否吸烟3","零食爱好3","饮酒频率3")
names(tb_data4)<-c("pid","吸烟年龄4","是否吸烟4","零食爱好4","饮酒频率4")
names(tb_data5)<-c("pid","吸烟年龄5","是否吸烟5","零食爱好5","饮酒频率5")
#(4)匹配tb_data1-5这5个数据库
# 创建一个包含所有数据框的列表
data_list <- list(tb_data1, tb_data2, tb_data3, tb_data4, tb_data5)
# 使用 Reduce 函数合并列表中的所有数据框:by="pid"代表匹配变量
tb_data <- Reduce(function(x, y) merge(x, y, by = "pid", all = TRUE), data_list)
如下:tb_data数据集里面有很多变量
#(5)下面是自建的计算多个变量众数的函数,其结果就是生成新变量
#data:数据集,list:代表哪些变量
a<-function(data,list){
apply(data[, list], 1, function(x) {
unique_x <- unique(x)#计算输入行(x)中的唯一值,并将结果存储在unique_x变量中。
unique_x[which.max(table(x))]#table(x)计算输入行(x)中每个值出现的次数,which.max()函数找出出现次数最多的值
})
}
#比如:以下指从吸烟年龄1-5中的众数形成吸烟年龄这个变量
tb_data$吸烟年龄<-a(data=tb_data,
list = c("吸烟年龄1", "吸烟年龄2", "吸烟年龄3", "吸烟年龄4", "吸烟年龄5"))
tb_data$是否吸烟<-a(data=tb_data,
list = c("是否吸烟1", "是否吸烟2", "是否吸烟3", "是否吸烟4", "是否吸烟5"))
tb_data$零食爱好<-a(data=tb_data,
list = c("零食爱好1", "零食爱好2", "零食爱好3", "零食爱好4", "零食爱好5"))
tb_data$饮酒频率<-a(data=tb_data,
list = c("饮酒频率1", "饮酒频率2", "饮酒频率3", "饮酒频率4", "饮酒频率5"))
#(6)提取上面按照众数形成的最后的变量
tb_data<-select(tb_data,#数据集
pid,吸烟年龄,是否吸烟,零食爱好,饮酒频率)
#第六步:导出数据: 加载writexl包
library(writexl)
# 导出数据为xlsx格式
write_xlsx(tb_data, "tb_data.xlsx")
本公众号致力于分享实用的医学科研干货和热点科研文章共享平台,如果您有任何医学科研相关问题或经验分享,可以私信我!
谢谢阅读,以上均为个人在科研实践过程中的一些做法,如有错误敬请指正!!!
End
关注我获得
更多精彩