上次的推文:如何使用 Stata 绘制一幅彩色的照片?给你的图表添加一个冰墩墩! 中我们爬取了冬奥会奖牌榜数据并绘图展示,但是那篇推文中并没有对数据爬取代码进行详细的讲解,今天我们就专门来学习下这个奖牌榜数据的爬起和绘图展示。
将冬奥会奖牌榜数据可以从这里看到:
https://tiyu.baidu.com/beijing2022/home/tab/%E5%A5%96%E7%89%8C%E6%A6%9C/from/pc
查看网页源代码可以看到网页上的数据就在源代码里面:
| 对着网页的空白处按鼠标右键选择显示网页源代码 |
 |
| 很容易发现我们需要的数据就在这里 |
 |
所以这是个静态网页,我们可以使用 copy 命令把这个网页下载下来:
clear copy "https://tiyu.baidu.com/beijing2022/home/tab/%E5%A5%96%E7%89%8C%E6%A6%9C/from/pc" temp.html, replace
|
使用 infix 命令可以把这个文件读进 Stata 中:
infix strL v 1-10000 using temp.html, clear
|
strL v 1-10000 表示把 temp.html 文件每一行的 1-1000 个字符读进变量 v 中,变量 v 的类型是 strL (长字符串)。
分析源代码我们可以看到我们需要的数据所在行都有个 national-box:
| 图表 |
 |
所以我们仅仅保留含有 national-box 的行:
keep if index(v, "national-box")
|
发现变量 v 里面存在空格,会影响下一步的处理,所以先把空格删去:
replace v = subinstr(v, " ", "", .)
|
| 图表 |
 |
为了我们需要的数据从变量 v 中分离出来,我们可以先选择合适的切分符号对变量 v 进行切分,“><” 就非常合适:
| 图表 |
 |
检查可以发现我们需要奖牌数据在下面这几个变量中:
并且所需的数据还都在 > 和 < 中间,所以可以对所有的变量应用正则表达式提取数据:
foreach i of varlist _all { replace `i' = ustrregexs(1) if ustrregexm(`i', ">(.*)<") }
compress destring _all, replace
|
再重命名下变量就可以了:
ren v6 国家 ren v9 金牌 ren v10 银牌 ren v11 铜牌 ren v12 总计 save data, replace
|
| 图表 |
 |
这样我们就爬取好了这份数据,下面我们选择前十个国家进行绘图展示:
use data, clear keep in 1/10 sencode 国家, gsort(-金牌) replace
|
sencode 命令需要使用 ssc install sencode 安装,可以生成有序因子变量。
为了使用 twoway 绘制堆叠柱状图,我们需要对数据进行叠加:
replace 银牌 = 银牌 + 铜牌 replace 金牌 = 银牌 + 金牌
tw bar 铜牌 国家, barwidth(0.7) color("239 199 16") || rbar 银牌 铜牌 国家, barwidth(0.7) color("190 190 190") || rbar 金牌 银牌 国家, barwidth(0.7) color("222 174 121") xla(1(1)10, value ang(45)) xti("") yti("奖牌数") leg(row(1) pos(11) ring(0) order(1 "金牌" 2 "银牌" 3 "铜牌")) yla(0(5)45) ti("2022 年北京冬奥会获得金牌前十名的代表团奖牌数") subti("绘制:微信公众号 RStata") caption("数据来源:百度体育" "<https://tiyu.baidu.com/beijing2022/home/tab/%E5%A5%96%E7%89%8C%E6%A6%9C/from/pc>")
|
| 图表 |
 |
如果想把柱体按照高矮顺序排列,我们需要根据奖牌总数进行 sencode:
use data, clear keep in 1/10 sencode 国家, gsort(-总计) replace
replace 银牌 = 银牌 + 铜牌 replace 金牌 = 银牌 + 金牌
tw bar 铜牌 国家, barwidth(0.7) color("239 199 16") || rbar 银牌 铜牌 国家, barwidth(0.7) color("190 190 190") || rbar 金牌 银牌 国家, barwidth(0.7) color("222 174 121") xla(1(1)10, value ang(45)) xti("") yti("奖牌数") leg(row(1) pos(11) ring(0) order(1 "金牌" 2 "银牌" 3 "铜牌")) yla(0(5)45) ti("2022 年北京冬奥会获得金牌前十名的代表团奖牌数") subti("绘制:微信公众号 RStata") caption("数据来源:百度体育" "<https://tiyu.baidu.com/beijing2022/home/tab/%E5%A5%96%E7%89%8C%E6%A6%9C/from/pc>")
|
| 图表 |
 |
点击这里跳转到 RStata 短书平台获取附件:使用 Stata 爬取冬奥会奖牌榜数据并绘图展示
评论