使用R进行倾向得分匹配(PSM)

article/2025/7/23 23:28:03

【译文】使用R进行倾向得分匹配(PSM)

作者 Norbert Köhler

译者 钱亦欣

根据维基百科,倾向得分匹配(PSM)是一种用来评估处置效应的统计方法。广义说来,它将样本根据其特性分类,而不同类样本间的差异就可以看作处置效应的无偏估计。因此,PSM不仅仅是随机试验的一种替代方法,它也是流行病研究中进行样本比较的重要方法之一。让我们举个栗子:

与健康相关的生活质量(HRQOL)被认为是癌症治疗的重要结果之一。对癌症患者而言,最常用的HRQOL测度是通过欧洲癌症研究与治疗中心的调查问卷计算得出的。EORTC QLD-C30是一个由30个项目组成,包括5个功能量表,9个症状量表和一个全球生活质量量表的的问卷。所有量表都会给出一个0-100之间的得分。症状量表得分越高代表被调查人生活压力越大,其余两个量表得分越高代表生活质量越高。

然而,如果没有任何参照,直接对数据进行解释是很困难的。幸运的是,EORTC QLQ-C30问卷也在一些一般人群调查中使用,我们可以对比患者的得分和一般人群的得分差异,从而判断患者的负担症状和一些功能障碍是否能归因于癌症治疗。PSM在这里可以以年龄和性别等特征,将相似的患者和一般人群进行匹配。

本文我会演示如在在R中实现PSM。更为详尽的说明请参考: “A Step-by-Step Guide to Propensity Score Matching in R” 。

生成两个随机数据框

由于我不希望在本文使用真实数据,我需要生成一些仿真数据。使用Wakefield包可以很容易地实现这个功能。

第一步,我们创建一个名为df.patients的数据框,我希望它包含250个病人的年龄和性别数据,所有病人的年龄都要在30-78岁之间,并且70%的病人被设定为男性。

set.seed(1234)
df.patients <- r_data_frame(n = 250, age(x = 30:78, name = 'Age'), sex(x = c("Male", "Female"), prob = c(0.70, 0.30), name = "Sex"))
df.patients$Sample <- as.factor('Patients')

summary函数会返回创建的数据框的基本信息,如你所见,患者平均年龄为53.7岁,并且大约70%为男性。

summary(df.patients)
##       Age            Sex           Sample   
##  Min.   :30.00   Male  :173   Patients:250  
##  1st Qu.:42.00   Female: 77                 
##  Median :54.00                              
##  Mean   :53.71                              
##  3rd Qu.:66.00                              
##  Max.   :78.00

第二步,我们需要创建另一个名为df.population的数据框。我希望这个数据集的数据和患者的有些不同,因此正常人群的年龄区间被设定为18-80岁,并且男女各占一半。

set.seed(1234)
df.population <- r_data_frame(n = 1000, age(x = 18:80, name = 'Age'), sex(x = c("Male", "Female"), prob = c(0.50, 0.50), name = "Sex"))
df.population$Sample <- as.factor('Population')

下方表格显示样本平均年龄为49.5岁,男女比例也大致相等。

summary(df.population)
##       Age            Sex             Sample    
##  Min.   :18.00   Male  :485   Population:1000  
##  1st Qu.:34.00   Female:515                    
##  Median :50.00                                 
##  Mean   :49.46                                 
##  3rd Qu.:65.00                                 
##  Max.   :80.00

合并数据框

在匹配样本之前,我们需要把两个数据框合并。先生成一个新变量Group来代表观测来自哪个全体(逻辑型变量),再添加另一个变量Distress来反应个体的痛苦程度。Distress变量是利用Wakefield包中的age函数创建的,可以发现,女性承受的痛苦级别更高。

mydata <- rbind(df.patients, df.population)
mydata$Group <- as.logical(mydata$Sample == 'Patients')
mydata$Distress <- ifelse(mydata$Sex == 'Male', age(nrow(mydata), x = 0:42, name = 'Distress'),age(nrow(mydata), x = 15:42, name = 'Distress'))

当我们比较两类样本的年龄和性别分布时,我们可以发现明显的区别:

pacman::p_load(tableone)
table1 <- CreateTableOne(vars = c('Age', 'Sex', 'Distress'), data = mydata, factorVars = 'Sex', strata = 'Sample')
table1 <- print(table1, printToggle = FALSE, noSpaces = TRUE)
kable(table1[,1:3],  align = 'c', caption = 'Table 1: Comparison of unmatched samples')

更进一步,我们还发现一般人群的痛苦程度显著较高。

样本匹配

现在,我们已经完成了全部的准备工作,可以开始使用MatchIT包中的matchit函数来匹配两类样本了。函数中method=‘nearest’的设定指明了使用近邻法进行匹配。其他方法包括,次分类,优化匹配等。ratio=1意味着这是一一配对。同时也请注意Group变量需要是逻辑型变量。

set.seed(1234)
match.it <- matchit(Group ~ Age + Sex, data = mydata, method="nearest", ratio=1)
a <- summary(match.it)

为了后续工作的便利,我们将summary函数的输出赋值给名为a的变量。

在匹配万样本后,一般人群样本量所见到了和患者样本一致(250个观测)。

kable(a$nn, digits = 2, align = 'c', caption = 'Table 2: Sample sizes')

根据输出结果,匹配后的年龄和性别分布基本一致了。

kable(a$sum.matched[c(1,2,4)], digits = 2, align = 'c', caption = 'Table 3: Summary of balance for matched data')

倾向得分的分布可以使用MatchIt包中的plot函数进行绘制。

plot(match.it, type = 'jitter', interactive = FALSE)

输出如下:

保存匹配样本

最后,让我们把匹配好的样本保存在df.match数据框里。

df.match <- match.data(match.it)[1:ncol(mydata)]
rm(df.patients, df.population)

现在pacman::p_load(tableone)

table4 <- CreateTableOne(vars = c('Age', 'Sex', 'Distress'), data = df.match, factorVars = 'Sex', strata = 'Sample')
table4 <- print(table4, printToggle = FALSE, noSpaces = TRUE)
kable(table4[,1:3],  align = 'c', caption = 'Table 4: Comparison of matched samples'),我们可以对比两类人群间痛苦程度的差异是否依旧显著。

由于p值为0.222,学生t检验的结果不再显著。因此,PSM帮助我们避免犯下第一类错误。

P.S.1:本文只用的所有包可通过如下代码加载:

pacman::p_load(knitr, wakefield, MatchIt, tableone, captioner)

P.S.2:非常感谢我的同事Katharina Kuba向我推荐了MatchIt包!

注:本文原载与datascienceplus网站

原文链接: http://datascienceplus.com/how-to-use-r-for-matching-samples-propensity-score


http://chatgpt.dhexx.cn/article/Yor4IISv.shtml

相关文章

倾向匹配得分PSM学习笔记

一直在想写倾向匹配得分PSM学习笔记&#xff0c;好好总结一下。但一直拖着&#xff0c;对倾向匹配得分法虽然思想比较理解&#xff0c;但没有系统地学习&#xff0c;所以这篇博客总结一下老师们的一些文章&#xff0c;在总结中学习&#xff0c;哈哈~ 倾向匹配得分PSM学习笔记 …

倾向得分匹配案例分析

一、倾向得分匹配法说明 倾向得分匹配模型是由Rosenbaum和Rubin在1983年提出的&#xff0c;首次运用在生物医药领域&#xff0c;后来被广泛运用在药物治疗、计量研究、政策实施评价等领域。倾向得分匹配模型主要用来解决非处理因素&#xff08;干扰因素&#xff09;的偏差。 …

倾向得分匹配法(PSM)量化评估效果分析

1. 因果推断介绍 如今量化策略实施的效果评估变得越来越重要&#xff0c;数据驱动产品和运营、业务等各方的理念越来越受到重视。如今这方面流行的方法除了实验方法AB testing外&#xff0c;就是因果推断中的各种观察研究方法。 “统计相关性并不意味着因果关系”&#xff0c;数…

PSM倾向得分匹配法【python实操篇】

前言 大家好&#xff0c;我是顾先生&#xff0c;PSM倾向性得分匹配法的Python代码实操终于来啦&#xff01; ​ 对于PSM原理不太熟悉的同学可以看看前一篇文章&#xff1a;PSM倾向得分匹配法【上篇&#xff1a;理论篇】 目前网上PSM实操的相关文章都是R语言、SPSS和STATA实现…

数据分析36计(九):倾向得分匹配法(PSM)量化评估效果分析

1. 因果推断介绍 如今量化策略实施的效果评估变得越来越重要&#xff0c;数据驱动产品和运营、业务等各方的理念越来越受到重视。如今这方面流行的方法除了实验方法AB testing外&#xff0c;就是因果推断中的各种观察研究方法。 “统计相关性并不意味着因果关系”&#xff0c;数…

PSM倾向得分匹配

1. 简要介绍 我们以 是否上大学 () 对 收入 () 的影响为例来说明这个问题。这里&#xff0c;先讲二者的关系设定为如下线性模型&#xff1a; 显然&#xff0c;在模型 (1) 的设定中&#xff0c;我们可能忽略了一些同时影响「解释变量」—— 是否上大学 () 和「被解释变量」——…

stata 倾向得分匹配操作

倾向得分匹配法是一种研究方法&#xff0c;它在研究某项治疗、政策、或者其他事件的影响因素上很常见。对于经济、金融学领域来说&#xff0c;比如需要研究某个劳动者接受某种高等教育对其收入的影响&#xff0c;或者比如研究某个企业运用了某项管理层激励措施以后对企业业绩的…

倾向得分匹配(PSM)的原理以及应用

该文章主要介绍倾向得分匹配&#xff08;PSM, Propensity Score Matching&#xff09;方法的原理以及实现。这是一种理论稍微复杂、但实现较为容易的分析方法&#xff0c;适合非算法同学的使用。可用于&#xff08;基于观察数据的&#xff09;AB实验、增量模型搭建等领域。 文章…

倾向得分匹配只看这篇就够了

一、倾向得分匹配法说明 倾向得分匹配模型是由Rosenbaum和Rubin在1983年提出的&#xff0c;首次运用在生物医药领域&#xff0c;后来被广泛运用在药物治疗、计量研究、政策实施评价等领域。倾向得分匹配模型主要用来解决非处理因素&#xff08;干扰因素&#xff09;的偏差。 …

Android设置图标背景透明

这里写自定义目录标题 Android 设置图标背景透明速览引言调整背景色 Android 设置图标背景透明 速览 设置 android:background"#00ffffff" 引言 适用于 Vector Assets 和 透明背景的图片 想要在Android中使用透明背景的图片 首先得保证图片本身是透明背景的 不然也没…

如何设置背景透明度

设置背景透明度分为两种&#xff1a;一种背景为颜色设置的纯色背景&#xff1b;另一种是图片做背景。 【情况一】纯色背景 关键代码&#xff1a;background:rgba(R,G,B,A) RGB--------三原色&#xff08;red,green,bule&#xff09;A-------透明度 关于三原色最终成型的颜色…

html悬浮背景透明视频教程,在html中使用背景透明的video视频

由于对效果的要求&#xff0c;需要加入透明背景的video。经过了解&#xff0c;现代浏览器(新版 Chrome、Firefox、Safari 等)已经全面支持 webM 格式的视频了&#xff0c;因此可以使用带 alpha 通道的 webM 格式视频满足要求。 要得到透明 webM 格式视频&#xff0c;则需要来源…

Android BottomSheetDialog设置背景透明无效?(解决)

BottomSheetDialog修改背景圆角 解决方法 这里记录一个实际开发过程中遇到的问题&#xff0c;在日常开发中遇到底部弹窗的时候我会第一时间用到BottomSheetDialog&#xff0c;常规的使用就是有一个默认从底部出现的弹窗&#xff0c;但是为了美观&#xff0c;通常会使用圆角&…

dialog设置背景透明

默认dialog是一个白底方形的&#xff0c;如果在xml设置中设置了一种边角是弧形的背景图片&#xff0c;那么显现的dialog角落就会留白 &#xff0c;解决办法&#xff1a; dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent); 效果&#xff1a;只…

Flutter bottomNavigationBar背景透明

Scaffold(extendBody: true,//加这句背景就透明 ..... ) 效果图

html+页面的背景透明,css设置背景透明 元素不透明

css设置背景透明 元素不透明 在做前端页面的时候&#xff0c;我们会遇到这样的情况&#xff0c;需要背景为半透明状态&#xff0c;但是层里面的内容不需要为透明的状态。有时候我们设置的时候会出现不管内容还是背景同时都成透明了&#xff0c;如何实现背景色透明但内容不透明这…

qt实现窗口背景透明

方法一&#xff1a; MainWindow w;//方法一&#xff1a;主界面透明&#xff0c;界面里面的控件不透明w.setWindowFlags(Qt::FramelessWindowHint);//设置无窗口框架边界w.setAttribute(Qt::WA_TranslucentBackground);//设置背景透明w.show(); 编辑界面&#xff1a; 运行效果&…

android fragment 设置透明,DialogFragment背景透明设置

一 、背景 使用自定义DialogFragment实现弹窗效果时,边缘透明图片作为背景图片,依然存在不透明背景; QQ截图20180428154111.png 修复后: QQ截图20180428153910.png 二、实现 因为项目中多个地方使用到DialogFragment,所以稍作了一下封装: import android.app.Dialog; imp…

winform label背景透明

开发时要把label的背景&#xff0c;透明。 在网上找到资料。原文How to Use Transparent Images and Labels in Windows Forms - CodeProject 主要是在用web的 Transparent。&#xff08;我在代码中来设置Color.Transparent没有效果。这个在wpf中设置是可以的&#xff0c;在wi…