导读
前段时间我们爬虫俱乐部的Stata学员群有学员问了这样的一个问题:
虽然帮助这位学员解决了这个问题,但是我一时竟想不起来如何向他展示正确结果。只能用最原始直白的方法——截图,以图为证。在征求那位学员的同意下,我借用了他的数据集来还原这个过程,在此感谢那位大方的学员。(读者朋友们可以在后台回复"levelsof"来获取相关数据。)use wiod1.dta,clear
keep if strpos(Description,"FINANCIAL INTERMEDIATION") //保留符合条件的观测值
执行以上操作后,观察数据集,我们会发现这个数据比较规整,每个国家都占两行,直接看最后一行,行数除以2,就知道有多少个国家符合条件。
但对于比较乱的数据集,假设某数据集有的国家数据占三行,有的占四行,这时通过肉眼就很难观察有多少个不同的国家了。而用接下来介绍的levelsof命令就能轻松获取这个信息了!levelsof命令的含义为"Distinct levels of a variable"。它对指定变量的不同取值进行排序。执行上行命令在结果窗口就会显示Country变量的不同取值,相当于进行了一次去重:
更绝妙的是:levelsof是r-类命令,它的运行结果储存在"r()",可以通过输入"return list"来显示。它以r(N)
储存指定变量的总观测值数,以r(r)
储存指定变量不同观测值的个数,以r(levels)
储存指定变量不同取值。所以,根据标量r(r)的值我们就知道有多少个不同的国家了。
当然,到这里还只是levelsof这个命令的入门,且没有展示levelsof的主要用途,接下来本文就要完整介绍levelsof这个命令了。
1.基本语法与选项
levelsof varname [if] [in] [, options]
选项 |
功能 |
clean |
清除字符串变量取值结果的复合双引号 |
local(macname) |
将排序后的取值结果放在一个宏中 |
missing |
将缺失值纳入取值中 |
separate(separator) |
设置取值结果的分隔符 |
matcell(matname) |
以矩阵的形式储存不同取值的频数 |
matrow(matname) |
以矩阵的形式储存数值型变量的不同取值 |
hexadecimal |
使用16进位制展示数值型变量 |
仍然以导读中的数据集为例,我们来体会一下几个常用选项的用法:levelsof Country in 1/10,clean separate(;) local(country) matcell(freq)
display "`country'"
matrix list freq
此时观察结果展示窗口可以发现:Country变量前十行观测值不同取值的复合双引号不显示,且不同取值以分号隔开;local()选项生成了一个存储不同取值的局部宏;matcell()选项生成了一个矩阵来存储不同取值的频数。
还有一个值得一提的选项是hexadecimal()。levelsof命令有一个小缺陷是它展示的数值型变量取值精度有限,当数值精度要求高时,显示的可能与实际取值不完全一样。虽然在实际使用中这种情况很少,Stata也提供了一个hexadecimal()选项来解决这个问题。clear
set obs 5
gen x=_n
gen y=ln(x)
levelsof y, matrow(A) hexadecimal
matrix list A
如下所示,此时变量y的不同取值以16进位制展示,确保了数据的准确度。另外,在这里我们用了matrow()选项将不同取值储存在矩阵A中,矩阵A中的值仍是十进位制。
2.案例介绍
levelsof命令最主要的用途是调用变量的观测值来实现某种目的。下面我们介绍一个词云图绘制的案例。在绘制词云图时,去除无意义的停用词是很重要的一步。停用词表和分词结果是不同的两个数据集。这意味着我们要调用停用词表中的停用词,将它与分词结果中的每一个词进行匹配,去除分词结果中的停用词。clear
infix strL v 1-12000 using 分词结果.txt, clear
rename v word
然后,使用起死回生命令“preserve ,restore”。这意味着,在preserve 后我们可以肆无忌惮的折腾数据,只要restore一下,原数据就会重现。我们读入停用词表,利用levelsof将停用词表中的停用词放在宏中,然后再重现原数据,调用存放停用词的宏。preserve
import delimited using 停用词表.txt, clear encoding("utf-8")
levelsof v1, local(keyword) //将停用词放在局部宏keyword中
restore
*删除分词结果中的停用词
foreach word in `keyword' {
drop if word == "`word'"
}
注意:levelsof的local()选项定义的是一个局部宏,上述命令必须同时执行。最后,在安装了wordcloud这个命令的基础下,绘制词云图。bysort word: gen frequency = _N
duplicates drop
gsort -frequency
wordcloud word frequency using 词云.html, replace size(15 80) range(3840 2160)
shellout 词云.html
此外,levelsof命令在网络爬虫时也经常使用。比如,在爬取新浪财经高管数据时,我们要改变网址中的股票代码来循环,这时就需要调用股票代码这个变量的观测值。总之,要调用变量观测值来达到某种目的时,不要忘记levelsof命令这个亲密伙伴!