循环进行距离匹配

问题描述

我想按行业和年份将经过处理的公司与控制公司进行匹配,考虑到在盈利能力(roa)方面最接近的公司。我想要1:1个比赛。我正在使用距离测量(mahalanobis)。

我的样本中有530,000个企业年度观测值,即267,000处理过的观测值和263,000对照观测值。这是我的代码:

gen neighbor1 = .
gen idobs = .

levelsof industry 
local a = r(levels)

levelsof year
local b = r(levels)

foreach i in `a' {  
foreach j in `b'{    
capture noisily psmatch2 treat if industry == `i' & year == `j',mahalanobis(roa) 
capture noisily replace neighbor1 = _n1 if industry == `i' & year == `j' 
capture noisily replace idobs = _id if industry == `i' & year == `j'
drop _treated _support _weight _id _n1 _nn  
}  
}

Treat是我的治疗变量。对于已处理的观察,其值为1;对于未处理的观察,其值为0

命令psmatch2将创建变量_n1_id等。 _n1是匹配观察值(最近的邻居)的ID号,_id是每个观察值唯一的ID号(1-530,000)。

代码“有效”,即未收到任何错误消息。我的变量neighbor1具有290,724个非缺失的观察结果。

但是,这些290,724观察值在1933之间变化,这很奇怪。变量neighbor1应该为我提供匹配观察值的观察ID号,它可以在1530,000之间变化。

该代码似乎擦除或忽略了不同子组中匹配过程的结果。我在做什么错了?


编辑:

我找到了一个公共数据集,并修改了以前的代码,以便您可以使用该数据集运行我的代码,并更清楚地了解问题所在。

我正在使用Vella和Verbeek(1998)的面板数据来研究每年545-1980的{​​{1}}人的工作,该工作来自以下网站:https://www.stata.com/texts/eacsap/

让我们说,我要匹配已观察到的观察值(即人),以根据婚姻状况(1987)和年份(考虑工作时间相似的人(married)来控制观察值,即最短的距离。

为此示例,我创建了一个随机处理变量(hours

treat

此代码应该做的是查看观察的每个子组:use http://www.stata.com/data/jwooldridge/eacsap/wagepan.dta gen treat = round(runiform()) gen neighbor1 = . gen idobs = . levelsof married local a = r(levels) levelsof year local b = r(levels) foreach i in `a' { foreach j in `b'{ capture noisily psmatch2 treat if married == `i' & year == `j',mahalanobis(hours) capture noisily replace neighbor1 = _n1 if married == `i' & year == `j' capture noisily replace idobs = _id if married == `i' & year == `j' drop _treated _support _weight _id _n1 _nn } } 444个未婚的观察,1980中已婚的101个观察, ...,以及1980中已婚的335观察。考虑到工作小时数最短的距离,我希望在每个亚组中将经过处理的观察结果与对照观察结果进行匹配。

运行代码后,我看到两个问题。

首先,变量1987idobs1之间应采用唯一的数字,因为此数据集中有4360个观测值。这只是一个ID号。事实并非如此。一些观察值可以具有ID号43601等。

第二,2neighbor11之间变化,这意味着匹配的观测值仅具有从2041之间变化的ID号。

我的代码有什么问题?

解决方法

这是使用命令iematch的解决方案,该命令通过软件包ietoolkit-> ssc install ietoolkit安装。为了公开起见,我编写了此命令。如果您想要ATT,psmatch2很棒。但是,如果您想要的只是使用最近的邻居对两组观察值进行匹配,那么iematch会更干净。

在两个命令中,您都需要在子集中使每个行业年份匹配,然后合并该信息。在这两个命令中,匹配的组ID将在每个子集中从1重新开始。

使用示例数据,这会为每个子集创建一个matchID变量,然后您将不得不找到一种将它们组合为单个matchID的方法,而不会在整个数据集中产生冲突。

* use data set and keep only vars required for simplicity
use http://www.stata.com/data/jwooldridge/eacsap/wagepan.dta,clear
keep year married hour

* Set seed for replicability. NEVER use the 123456 seed in production,randomize a new seed
set seed 123456

*Generate mock treatment
gen treat = round(runiform())

*generate vars to store results
gen matchResult = .
gen matchDiff = .
gen matchCount = .

*Create locals for loops
levelsof married 
local married_statuses = r(levels)

levelsof year 
local years = r(levels)

*Loop over each subgroup
foreach year of local years {
    foreach married_status of local married_statuses {
        *This command is similar to psmatch2,but a simplified version for 
        * when you are not looking for the ATT. 
        * This command is only about matching.
        iematch if married == `married_status' & year == `year',grp(treat) match(hour) seedok m1 maxmatch(1)
      
        *These variables list meta info about the match. See helpfile for docs,*but this copy info from each subset in this loop to single vars for 
        *the full data set. Then the loop specfic vars are dropped
        replace matchResult     = _matchResult  if married == `married_status' & year == `year'
        replace matchDiff   = _matchDiff    if married == `married_status' & year == `year'
        replace matchCount  = _matchCount   if married == `married_status' & year == `year'
        drop _matchResult _matchDiff _matchCount
      
        *For each loop you will get a match ID restarting at 1 for each loop. 
        *Therefore we need to save them in one var for each loop and combine afterwards.
        rename _matchID matchID_`married_status'_`year'
    }
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...