了解公司是否随时间进入或离开行业

Find out if firm enters or leaves industries over time

我有一个包含公司信息的数据集:

clear
input firm_id str6 industry int fyear int
1084    7372    2010
1084    7375    2010
1084    7372    2011
1084    7375    2011
1084    7372    2012
1084    7375    2012
1084    7372    2013
1084    7375    2013
1084    7372    2014
1084    7375    2014
1094    2865    2002
1094    2879    2002
1094    5122    2002
1094    5169    2002
1094    2865    2003
1094    2879    2003
1094    5122    2003
1094    5169    2003
1094    2865    2004
1094    2879    2004
1094    5122    2004
1094    5169    2004
1094    2865    2005
1094    2879    2005
1094    5122    2005
1094    5169    2005
1094    2865    2006
1094    2879    2006
1094    5122    2006
1094    5169    2006
1094    2865    2007
1094    2879    2007
1094    5169    2007
1094    2865    2008
1094    2879    2008
end

除了 firm_id 之外,它还包括有关公司在给定年份活跃的行业的信息。

我如何才能知道一家公司在给定年份离开和进入了多少个行业?

我知道我可以通过编写一个 "loop in a loop" 来做到这一点,该 "loop in a loop" 查看每个单独的观察结果并检查 year 是否存在相同的 firm_idindustry 组合+1。但是我的数据集很大,这样效率会非常低。

我也考虑过使用 reshape wide 的解决方案,但也找不到解决我的问题的方法(当然这会产生非常多的变量并且效率也不高)。

如果您尝试为每家公司生成一个单一的观察结果,其中包含公司每年进入和退出的行业数量,我相信以下代码应该有效。变量 enterleave 表示(分别)公司是否进入或存在给定观察中的行业。在数据中对这些年使用 foreach 循环,然后您可以生成每个变量,指示公司每年是进入还是退出。

bys firm_id industry (fyear): gen prevyear = fyear[_n-1]
gen yrdifpast = fyear - prevyear
gen enter = yrdifpast > 1

bys firm_id industry (fyear): gen nextyear = fyear[_n+1]
gen yrdiffuture = nextyear - fyear
gen leave = yrdiffuture > 1

levelsof fyear, local(years)
foreach yr of local years {
    gen in_`yr'  = fyear==`yr'&enter==1
    gen out_`yr' = fyear==`yr'&leave==1
}

collapse (sum) in_* out_*, by(firm_id)

list
     +----------------------------------------------------------------------------------------------+
  1. | firm_id | in_2002 | in_2003 | in_2004 | in_2005  | in_2006  | in_2007  | in_2008  | in_2010  |
     |    1084 |       0 |       0 |       0 |       0  |       0  |       0  |       0  |       2  |
     |---------+---------+---------+---------+----------+----------+----------+----------+----------|
     | in_2011 | in_2012 | in_2013 | in_2014 | out_2002 | out_2003 | out_2004 | out_2005 | out_2006 |
     |       0 |       0 |       0 |       0 |        0 |        0 |        0 |        0 |        0 |
     |----------------------------------------------------------------------------------------------|
     |  out_2007  |  out_2008  |  out_2010  |  out_2011   |  out_2012   |  out_2013   |  out_2014   |
     |         0  |         0  |         0  |         0   |         0   |         0   |         2   |
     +----------------------------------------------------------------------------------------------+

     +----------------------------------------------------------------------------------------------+
  2. | firm_id | in_2002 | in_2003 | in_2004 | in_2005  | in_2006  | in_2007  | in_2008  | in_2010  |
     |    1094 |       4 |       0 |       0 |       0  |       0  |       0  |       0  |       0  |
     |---------+---------+---------+---------+----------+----------+----------+----------+----------|
     | in_2011 | in_2012 | in_2013 | in_2014 | out_2002 | out_2003 | out_2004 | out_2005 | out_2006 |
     |       0 |       0 |       0 |       0 |        0 |        0 |        0 |        0 |        1 |
     |----------------------------------------------------------------------------------------------|
     |  out_2007  |  out_2008  |  out_2010  |  out_2011   |  out_2012   |  out_2013   |  out_2014   |
     |         1  |         2  |         0  |         0   |         0   |         0   |         0   |
     +----------------------------------------------------------------------------------------------+

我看不出这里需要任何循环。但需要的是精确和明确的规则。在这里,只要有记录的第一年在数据集中的第一年之后,一家公司就会进入一个行业,而只要有记录的最后一年在数据集中的最后一年之前,一家公司就会离开。此外,如果记录在案的下一年晚了一年多,则一家公司离开了该行业,如果记录在案的前一年晚了一年多,则该公司进入了该行业。这允许离开和重新进入,尽管这种变化可能不太可能。

summarize fyear, meanonly 
local first = r(min) 
local last = r(max)     
bysort firm_id industry (fyear) : generate enter = (fyear > `first') if _n == 1 
by firm_id industry : replace enter = (fyear - fyear[_n-1]) > 1 if _n > 1    
by firm_id industry : generate leave = fyear < `last' if _n == _N 
by firm_id industry : replace leave = (fyear[_n+1] - fyear) > 1 if _n < _N 

table fyear firm_id, c(sum enter sum leave)