「财政研究」2019 年第 4 期中有篇论文<经济分权、地方政府竞争与城市全要素生产率> 提到了衡量政府竞争程度的指标。以往的文献通常采用经济增长率、外商直接投资和宏观税负, 背后的逻辑是指标数值越大,代表地方政府竞争越激烈。但是三种方式都无法揭示本地政府受相邻地区地方政府决策的影响,因此该论文提出可以用地区经济增长率与空间权重矩阵的乘积 Wgdpg 衡量地方政府竞争。今天我们就一起来看下如何在 Stata 中通过矩阵运算的方法来计算这一指标。

地区经济增长率通常使用地区生产总值的增长率衡量,这一指标在之前分享的城市统计年鉴面板数据里面有,这里提取了出来:
1999~2022 年中国城市统计年鉴面板数据:https://rstata.duanshu.com/#/brief/course/1dcad8873f394c31a4f082bd74e916b2
- 1998~2021年各地级市地区生产总值面板数据.dta
另外因为 2018 年的城市统计年鉴(上面的数据是 2017 年的)没有提供全市的地区生产总值,所以我又从 EPS 获取了 2017 年的数据进行补充。
首先读取“2019年各市是否接壤矩阵(对角线为0).xlsx”文件并处理,该文件来源于平台上之前分享的「历年各省市区县邻接矩阵、质心距离矩阵、质心距离倒数矩阵数据」。
历年各省市区县邻接矩阵、质心距离矩阵、质心距离倒数矩阵数据:https://rstata.duanshu.com/#/brief/course/eb331d940dbf4907b75d75b4914da67d
import excel using "2019年各市是否接壤矩阵(对角线为0).xlsx", clear foreach i of varlist _all { cap replace `i' = subinstr(`i', "-", "_", .) if _n == 1 } nrow 1
destring, replace replace 城市 = subinstr(城市, "-", "_", .) save "2019年各市是否接壤矩阵(对角线为0)", replace
|
因为 Stata 中的变量名不支持带“-”号的,所以这里都替换成了“_”。
因为城市统计年鉴里面没有提供 2017 年的全市地区生产总值,所以再从 EPS 获取一份 2017 年的处理下:
use 2017, clear ren 城市名称 市 ren 城市代码 市代码 ren 国内生产总值万元 地区生产总值_当年价格_亿元_全市 replace 地区生产总值_当年价格_亿元_全市 = 地区生产总值_当年价格_亿元_全市 / 10000 drop if missing(地区生产总值_当年价格_亿元_全市) drop 市代码 replace 市 = "北京市" if 市 == "北京" save 2017b, replace
|
这份数据里面有市代码变量,但是担心可能不是和我们这份城市统计年鉴数据一个版本的,所以匹配下试试:
shp2dta using "2019行政区划/市.shp", database(citycode2019) coord(coord) replace cap erase coord.dta use citycode2019, clear drop *类型 _ID merge 1:1 市 using 2017b
keep if _m == 3 drop _m save "2017c", replace
|
然后就可以把 2017 年的数据合并到总数据里面,再补充下缺失值:
use "1998~2021年各地级市地区生产总值面板数据", clear drop if 年份 == 2017 append using 2017c gen 城市 = 省 + "_" + 市 encode 城市, gen(city) xtset city 年份 replace 地区生产总值增长率_百分比_全市 = ((地区生产总值_当年价格_亿元_全市 - L.地区生产总值_当年价格_亿元_全市) / 地区生产总值_当年价格_亿元_全市) * 100 if missing(地区生产总值增长率_百分比_全市) drop city save "1998~2021年各地级市地区生产总值面板数据(填补后)", replace
|
我们再以 2021 年的数据为例看一下如何计算这一指标。
保留 2021 年的数据和矩阵匹配:
use "1998~2021年各地级市地区生产总值面板数据(填补后)", clear keep if 年份 == 2021 drop if missing(地区生产总值增长率_百分比_全市) merge 1:1 城市 using "2019年各市是否接壤矩阵(对角线为0).dta" keep if _m == 3 drop _m
|
为了避免矩阵的顺序错乱,我们首先锁定数据的行顺序:
这样如果后面有操作导致行序变了,只需要 gsort id 就可以修正了(不过这个在下面没用到)。
然后根据城市顺序重新排列下列序:
*- 循环获取城市列表 local vlist = "" forval i = 1/`=_N' { local vlist `vlist' `=城市[`i']' } keep 年份 省代码 省 市代码 市 地区生产总值_当年价格_亿元_全市 地区生产总值增长率_百分比_全市 城市 `vlist' order 年份 省代码 省 市代码 市 地区生产总值_当年价格_亿元_全市 地区生产总值增长率_百分比_全市 城市 `vlist'
|
下面就可以使用 mkmat 命令把变量值转换成矩阵了:
mkmat 地区生产总值增长率_百分比_全市, mat(m1) mkmat `vlist', mat(m2)
|
注意这里也用到了 vlist,试过 local 变量。local 变量的定义和使用要一并运行,所以这里的代码要和上面的一段代码同时运行才可以。
这样的话,m1 就是个 nxn 的矩阵,m2 是 nx1 的矩阵,两者相乘就得到了 nx1 的矩阵:
mat Wgdpg = m2 * m1
keep 省代码 省 市代码 市 svmat Wgdpg
list in 1/10
*> +------------------------------------------------------+ *> | 省代码 省 市代码 市 Wgdpg1 | *> |------------------------------------------------------| *> 1. | 310000 上海市 310000 上海市 26.2 | *> 2. | 530000 云南省 530900 临沧市 12.8 | *> 3. | 530000 云南省 530700 丽江市 8.3 | *> 4. | 530000 云南省 530500 保山市 7.4 | *> 5. | 530000 云南省 530100 昆明市 31.16 | *> |------------------------------------------------------| *> 6. | 530000 云南省 530600 昭通市 39.87 | *> 7. | 530000 云南省 530800 普洱市 16.46 | *> 8. | 530000 云南省 530300 曲靖市 38.6 | *> 9. | 530000 云南省 530400 玉溪市 10.4 | *> 10. | 150000 内蒙古自治区 150900 乌兰察布市 38.55 | *> +------------------------------------------------------+
|
svmat 可以把矩阵再转换成变量。
然后就可以循环所有年份的了:
cap mkdir "结果数据" use "1998~2021年各地级市地区生产总值面板数据(填补后)", clear forval i = 1998/2021 { preserve qui { keep if 年份 == `i' drop if missing(地区生产总值增长率_百分比_全市) merge 1:1 城市 using "2019年各市是否接壤矩阵(对角线为0).dta" keep if _m == 3 drop _m
local vlist = "" forval j = 1/`=_N' { local vlist `vlist' `=城市[`j']' } keep 年份 省代码 省 市代码 市 地区生产总值_当年价格_亿元_全市 地区生产总值增长率_百分比_全市 城市 `vlist' order 年份 省代码 省 市代码 市 地区生产总值_当年价格_亿元_全市 地区生产总值增长率_百分比_全市 城市 `vlist'
mkmat 地区生产总值增长率_百分比_全市, mat(m1) mkmat `vlist', mat(m2) mat Wgdpg = m2 * m1
keep 省代码 省 市代码 市 svmat Wgdpg } save "结果数据/`i'", replace restore }
|
最后合并所有年份的就得到了总的计算结果:
use 结果数据/1998.dta, clear gen 年份 = 1998 forval i = 1999/2021 { append using 结果数据/`i'.dta replace 年份 = `i' if missing(年份) } order 年份 ren Wgdpg1 Wgdpg
list in 1/10
save "Wgdpg计算结果", replace
|
另外如果是区县的可能使用 Mata 的矩阵运算会更快速点,首先以 2021 年的为例:
clear all use "1998~2021年各地级市地区生产总值面板数据(填补后)", clear keep if 年份 == 2021 drop if missing(地区生产总值增长率_百分比_全市) merge 1:1 城市 using "2019年各市是否接壤矩阵(对角线为0).dta" keep if _m == 3 drop _m
local vlist = "" forval i = 1/`=_N' { local vlist `vlist' `=城市[`i']' } keep 年份 省代码 省 市代码 市 地区生产总值_当年价格_亿元_全市 地区生产总值增长率_百分比_全市 城市 `vlist' order 年份 省代码 省 市代码 市 地区生产总值_当年价格_亿元_全市 地区生产总值增长率_百分比_全市 城市 `vlist'
mata: m1 = st_data(., "`vlist'") m2 = st_data(., "地区生产总值增长率_百分比_全市") Wgdpg = m1 * m2 st_matrix("Wgdpg", Wgdpg) end
keep 省代码 省 市代码 市 svmat Wgdpg
|
循环所有年份可以采用下面的代码:
clear all mata: void matfun() { vlist = st_local("vlist") m1 = st_data(., vlist) m2 = st_data(., "地区生产总值增长率_百分比_全市") Wgdpg = m1 * m2 st_matrix("Wgdpg", Wgdpg) } end
cap mkdir "结果数据2" use "1998~2021年各地级市地区生产总值面板数据(填补后)", clear forval i = 1998/2021 { preserve qui { keep if 年份 == `i' drop if missing(地区生产总值增长率_百分比_全市) merge 1:1 城市 using "2019年各市是否接壤矩阵(对角线为0).dta" keep if _m == 3 drop _m
local vlist = "" forval j = 1/`=_N' { local vlist `vlist' `=城市[`j']' } keep 年份 省代码 省 市代码 市 地区生产总值_当年价格_亿元_全市 地区生产总值增长率_百分比_全市 城市 `vlist' order 年份 省代码 省 市代码 市 地区生产总值_当年价格_亿元_全市 地区生产总值增长率_百分比_全市 城市 `vlist'
mata: matfun()
keep 省代码 省 市代码 市 svmat Wgdpg } save "结果数据2/`i'", replace restore }
|
合并代码就和上面的一样了。
点击这里跳转到 RStata 短书平台获取附件:名师讲堂|使用 Stata 计算地方政府竞争衡量指标:矩阵运算的应用
评论