2018~2023 年上市公司ESG评级面板数据

为了便于大家理解最终提供的两个版本,下面列示了一些代码,看不懂的小伙伴也不用担心。过几天会出一个专题课程讲解~

今天给大家分享一份 2018~2023 年上市公司 ESG 评级面板数据。原始数据来源于 Wind,不过 Wind 提供的样式难以使用,所以我就帮大家处理好了。

Wind 提供的数据是这样的:

例如平安银行的历史评级是:

2021-02-09, A
2020-02-21, BBB
2019-03-14, BB
2018-03-22, B

而我们方便使用的是面板数据,也就是这种形式的:

平安银行    2018    B
平安银行 2019 BB
平安银行 2020 BBB
平安银行 2021 A

可以使用 Stata 来处理这份数据。首先读取进 Stata 中简单处理下:

use data.dta, clear

*- 去除数据中的换行符和制表符
gen v1 = ustrregexs(0) if ustrregexm(历史评级, "\n")
replace 历史评级 = subinstr(历史评级, v1, ";", .)

gen v2 = ustrregexs(0) if ustrregexm(历史评级, "\r")
replace 历史评级 = subinstr(历史评级, v2, ";", .)
replace 历史评级 = subinstr(历史评级, ";;", ";", .)
replace 历史评级 = subinstr(历史评级, " ", "", .)
drop v1 v2
tostring 评级日期, format(%tdCY-N-D) replace force
replace 历史评级 = 历史评级 + 评级日期 + "," + 评级
drop 评级日期 评级
drop if mi(序号)
save data2, replace

处理这种数据,我的思路是使用 Mata 程序把每个字符串拆开,然后再保存到 Stata 的变量中:

use data2, clear
*- 统计分号的数量:
egen n = ipc_count(历史评级), parse(;)

*- 这里 ipc_count() 函数统计的实际上是分号分割产生的子字符串的数量,空的也算一个

mata:
mata clear
v1 = st_sdata(., "历史评级")
v2 = rowshape(v1, cols(v1))
v3 = invtokens(v2, ";")
v4 = ustrsplit(v3, ";")
v5 = colshape(v4, rows(v4))
end

*- 拓展数据
expand n
gsort 序号

*- 从 mata 的 v4 再创建变量
mata:
stata("cap drop newvar")
st_addvar("strL", "newvar")
st_sstore(., "newvar", v5)
end

这样就快速的把数据分开了:

list 序号 万得代码 n newvar in 1/10

*> +---------------------------------------+
*> | 序号 万得代码 n newvar |
*> |---------------------------------------|
*> 1. | 1 000001.SZ 5 2021-02-09,A |
*> 2. | 1 000001.SZ 5 2020-02-21,BBB |
*> 3. | 1 000001.SZ 5 2019-03-14,BB |
*> 4. | 1 000001.SZ 5 2018-03-22,B |
*> 5. | 1 000001.SZ 5 2022-03-17,A |
*> |---------------------------------------|
*> 6. | 10 000011.SZ 5 2021-04-07,AA |
*> 7. | 10 000011.SZ 5 2020-03-25,AA |
*> 8. | 10 000011.SZ 5 2019-04-02,AA |
*> 9. | 10 000011.SZ 5 2018-04-03,A |
*> 10. | 10 000011.SZ 5 2022-04-07,A |
*> +---------------------------------------+

再用 split 命令把 newvar 拆分开就差不多了:

drop 历史评级
drop if mi(newvar)
split newvar, parse(,)
drop newvar
gen date = date(newvar1, "YMD")
format date %tdCY-N-D
drop newvar1 n
ren date 评级日期
ren newvar2 评级
append using data
drop 历史评级
destring 序号, replace
gsort 万得代码 评级日期

*- 查看所有可能的评级
drop if mi(序号)
codebook 评级

gen 评级num = 1 if 评级 == "CCC"
replace 评级num = 2 if 评级 == "B"
replace 评级num = 3 if 评级 == "BB"
replace 评级num = 4 if 评级 == "BBB"
replace 评级num = 5 if 评级 == "A"
replace 评级num = 6 if 评级 == "AA"
replace 评级num = 7 if 评级 == "AAA"

label define pj 1 "CCC" 2 "B" 3 "BB" 4 "BBB" 5 "A" 6 "AA" 7 "AAA", replace
label val 评级num pj
save data3, replace

不过有些公司在某一年中可能有多个评级结果,因此我们可以使用两种方法把这个数据汇总成面板数据:

  1. 分公司保存每年的最后一次评级:
use data3, clear
gen 评级年份 = yofd(评级日期)
bysort 万得代码 评级年份 (评级日期): keep if _n == _N
drop 评级日期

save "2018~2023年上市公司ESG评级面板数据(版本1)", replace

这就是 版本1 的结果。

  1. 分公司保留每年最高的评级结果:
use data3, clear
gen 评级年份 = yofd(评级日期)
bysort 万得代码 评级年份 (评级num): keep if _n == _N

save "2018~2023年上市公司ESG评级面板数据(版本2)", replace

这就是 版本2 的结果。

两种结果

所以分享的结果有两种版本:

  1. 分公司保存每年的最后一次评级:2018~2023年上市公司ESG评级面板数据(版本1)
  2. 分公司保留每年最高的评级结果:2018~2023年上市公司ESG评级面板数据(版本2)

例如 版本2 的结果:

*>     +------------------------------------+
*> | 序号 万得代码 评级 评级年份 |
*> |------------------------------------|
*> 1. | 1 000001.SZ B 2018 |
*> 2. | 1 000001.SZ BB 2019 |
*> 3. | 1 000001.SZ BBB 2020 |
*> 4. | 1 000001.SZ A 2021 |
*> 5. | 1 000001.SZ A 2022 |
*> |------------------------------------|
*> 6. | 2 000002.SZ BB 2018 |
*> 7. | 2 000002.SZ BB 2019 |
*> 8. | 2 000002.SZ BB 2020 |
*> 9. | 2 000002.SZ BB 2021 |
*> 10. | 2 000002.SZ A 2022 |
*> +------------------------------------+

点击这里跳转到 RStata 短书平台获取附件:2018~2023 年上市公司ESG评级面板数据

评论