[关闭]
@liuyuxi 2021-05-05T14:23:35.000000Z 字数 10639 阅读 62

stata命令笔记

stata


tempname

  tempname为指定的本地宏名称分配名称,可作为定义临时标量或矩阵名称使用。当程序或执行文件结束时,任何具有这些指定名称的标量或矩阵将被删除。类似的还有tempfile(临时文件)、tempvar(临时变量)1

  1. tempname resmat //设定一个临时矩阵叫做resmat

  司继春stata讲义第40页补充了用di调用时的注意事项。

nullmat()

  nullmat()函数:函数作用就是创造了一个空函数,就好像一个空瓶子,我们就只要把新的东西装进去就可以了,而不用考虑这个东西之前是否存在,有点儿类似Python中的空列表或者空词典,通过这个命令可以缩短命令,提高程序运行速度。2

mat,mkmatsvmat

  mat也即matrix
  主要参考:stata带你进入奇幻的矩阵世界

  1. *直接录入矩阵
  2. mat X = (2,6,1\3,10,12\2,9,5) //逗号表示每一列,\表示每一行的分隔符
  3. mat list X //矩阵的输出
  4. *特定类型矩阵
  5. mat a=I(3) //生成单位矩阵I(n)函数,其中n表示阶数
  6. mat list a
  7. mat b=J(2,3,4) //生成特定行列(m,n)的矩阵且元素均为k,其函数形式为J(m,n,k)
  8. mat list b
  9. mat c=(1,2,3)
  10. mat C=diag(c) //以c中元素为对角元素利用diag函数生成对角矩阵
  11. mat list C
  12. *矩阵运算
  13. mat d1=d*d //矩阵相乘
  14. mat list d1
  15. mat d2=d#d //矩阵直乘
  16. mat list d2
  17. *数据与矩阵的相互转换
  18. sysuse auto,clear //调用系统数据
  19. keep in 1/6 //以前六行数据为例
  20. mkmat mpg //将mpg数据转换为一列矩阵
  21. mat list mpg
  22. mkmat foreign weight displacement ,mat(x) //转换为多列矩阵
  23. mat list x
  24. svmat x,names(x) //矩阵转换为数据主要调用svmat命令,注意:最后生成的变量是x1。
  25. matrix drop //删除矩阵
  26. matrix rename //矩阵改名
  27. matrix dir //列出所有矩阵及其维数
  28. mat colnames A=A1 A2 //为矩阵的列命名
  29. mat rownames A=obs1 obs2 obs3 obs4 //为矩阵的行命名

矩阵中的函数

rowsof(M):矩阵M的行数。

stata返回值

  值得参考的文章:朝花夕拾 | stata返回值
  e-class一般在我们用stata做模型估计的时候出现,如regresslogistic;r-class一般出现在例如summarizedescribe等命令中;c-class主要储存系统参数。

  1. *列出内存中所有返回值
  2. ereturn list // 列出内存中所有的e-class返回值
  3. return list // 列出内存中所有的r-class返回值
  4. creturn list // 列出内存中所有的c-class返回值
  5. * 回归后调用e-class
  6. dis e(r2) // 该模型的拟合度
  7. dis e(F) //该模型的F值
  8. mat list e(b) //系数向量
  9. mat list e(V) //方差协方差矩阵
  10. *e(sample)
  11. use http://www.ats.ucla.edu/stat/stata/notes/hsb2, clear
  12. regress read math science if write>=50
  13. predict p1
  14. summarize p1
  15. predict p2 if e(sample)==1 //if e(sample)==1 的作用是针对我们刚刚在模型估计中用到的那些样本。
  16. sum p2
  17. predict p3 if e(sample)==0
  18. sum p3

missing()

  当数据存在缺漏值时,传统的做法是使用drop命令。但是有时候需要同时去除多个变量中存在的缺漏值,亦或者要面对不同格式的缺漏值,例如 "." 和 " " 等等,此时missing()可以轻松完成该目标3

  1. * 基本语法: missing(x1,x2,...,xn) or mi(x1,x2,...,xn)
  2. sysuse "nlsw88", clear
  3. sum wage hours industry union
  4. drop if missing(wage, hours, industry, union) //去除缺漏值
  5. * 也可以
  6. egen miss = rowmiss(wage hours industry union)
  7. drop if miss > 0

  其他相关命令:cond(),inrange(),inlist(),clip();参考自《Stata数据处理:条件函数知多少?》

宏的妙用

  参考自“学术小白公众号”《Stata中local、global与常见命令使用》

我个人经常在stata的do文档中用到global,用于定义变量。上面方程中$y等同于我们数据集中的ln_income $keyx 等同于数据集中的birth_place,$x等同于数据集中的x1 x2 x3 x4 x5 x6。这样做有两个好处:第一,在论文做稳健性检验的时候,比如替换一个衡量y的变量就行,那么再重新定义一下y的宏就可以,回归方程可以不用改变;第二,在论文中有时候控制变量太多,而我们有需要跑很多次回归,每次都要输入一堆的控制变量,用$x,两个字符就可以代替,省时间,省空间,do文档看起来也更加美观

局部暂元的快捷键

  局部暂元中的左撇号(`)位于键盘中Tab键上方,右撇号(')位于Enter键左边。

  1. *for local--------------------------------------------------------
  2. local name "happy every day " //将happy every day定义为name
  3. dis `name' //展示定义结果
  4. happy every day //前两行命令同时使用,展示成功
  5. dis `name' //单独使用,展示失败,因为stata已经忘记曾经定义了什么
  6. local x=4 //直接赋值
  7. local x x1 x2 x3 //将变量赋给局部暂元
  8. *for global--------------------------------------------------------
  9. global name "happy every day " //将happy every day定义为name
  10. dis $name //展示定义结果
  11. happy every day //前两行命令同时使用,展示成功
  12. dis $name //单独使用,展示成功,因为stata还记得曾经定义了什么
  13. happy every day
  14. global y ln_income
  15. global keyx birth_place
  16. global x x1 x2 x3 x4 x5 x6
  17. reg $y &keyx $x ,r //与下面的估计一致
  18. reg ln_income birth_place x1 x2 x3 x4 x5 x6,r

文中还介绍了while,foreach,forvalue等。

local与复合引用

  local为局部宏(lclnames)指定字符串。允许双引号(“and”)和复合双引号(`“and”'),如果字符串中嵌入了引号,则应当使用复合双引号。
  根据help quotes可知:双引号("")常用于封闭字符串,stata中有两类双引号("")与(`""'),后者又称“复合双引号”,与前者作用相同,除非编程所需,否则一般不必使用“复合双引号”。

  1. local a `"example"'
  2. if `"`answ'"' == `"yes"' {
  3. ...
  4. }
  5. *此处只有`"`answ'"'一处的复合双引号比"`answ'" 的一般双引号更好,`"example"'与`"yes"'的复合双引号均并未比普通双引号更好。
  1. `"`answ`"' 比"`answ`" 更好是因为局部宏`answ`可能本身就包含了(简单或复合)双引号,而(此处所用的)复合双引号最妙的地方就在于他是嵌套的。假设`answ`包含字符串``I "think" so'',那么
  2. if "`answ'"=="yes"会使stata迷惑,因为它会被扩展为 if "I "think" so"=="yes";而 if `"`answ'"'==`"yes"'则会被stata扩展为 if `"I "think" so"'==`"yes"'。因为简单形式的开双引号与闭双引号在形式上是一样的,都是";而复合形式的双引号的开双引号与闭双引号却并不相同,开是`",闭是"',所以stata可以根据相应符号来进行封闭。`"I "think" so"'更易于被stata理解,
  3. 而"I "think" so"更像是一堆无可救药的杂烩。
  4. 因为stata可以区分开闭引号,所以即使嵌套的复合引号也是可以理解的,比如:`"I `"think"' so"'。
  5. 的确,复合双引号使你发现你的视野更加断断续续、不清晰,尤其是当其与宏替代字符`'相联系在一起的时候。这也正是就算在编程的工作中,我们也很少使用他们的原因。在进行下面的编程中,使用复合双引号是完全可以接受的:
  6. local a "example"
  7. if `"`answ'"' == "yes" {
  8. ...
  9. }
  10. 当然,如果宏内并不包含双引号或者并不在意会发生什么的话,也可以用"`answ'"来代替。

注解合成控制安慰剂检验中常见的一句代码

  此句code常见于各种合成控制安慰剂检验的推文与贴子中,均以加州控烟案例为基础。我曾以为此code是Abadie(2010)所撰,后在Harvard Dataverse中查到此文的code是用R写成,后来读了刘友金(2018,《房产税对产业转移的影响:来自重庆和上海的经验证据》)所附的code后才知此句原是国人手笔,但后来又发现出处应在stata论坛上,研读此句后有心得如下。原code为:

  1. forvalues i = 1/39{
  2. ...
  3. local names `"`names' `"`i'"'"'
  4. ...
  5. }

  如果局部宏内的字符串中没有加入双引号的话,上段code原本应该是:

  1. forvalues i = 1/39{
  2. ...
  3. local names "`names' `"`i'"'"
  4. ...
  5. }

  然而宏内包含着双引号,因此,按照help quotes所只称的,应该将局部宏的"..."改为`"..."'。而此处似乎实际上是一个由局部宏嵌套包含自身所构成的局部宏,因为"..."中的`names'似乎正好是在调用上次循环中所建立的局部宏中的内容,而这个宏的右边刚好是由复合双引号所引导的,由局部暂元左撇号与右撇号所包裹的i。这里按说只是把新一次循环中所产生的新次序i加到以往的局部暂元中去,又并非定义新的字符串内部含有双引号的暂元,似乎并无必要在"...."内部使用复合双引号,因此,此处或许可以删去复合引号,从而"...."内部就没有了双引号,因此就也可将原本定义局部暂元的复合双引号删去。因此,修改后的code应为:

  1. forvalues i = 1/39{
  2. ...
  3. local names "`names' `i'"
  4. ...
  5. }

  恰与连玉君教授讲义中的相同。
  经初步检查,三段code作用相同:

  1. *1原版
  2. forvalues i = 1/39{
  3. local names `"`names' `"`i'"'"'
  4. }
  5. di `names'
  6. 123456789101112131415161718192021222324252627282930313233343536373839
  7. *2去外单引号
  8. forvalues i = 1/39{
  9. local names "`names' `"`i'"'"
  10. }
  11. di `names'
  12. 123456789101112131415161718192021222324252627282930313233343536373839
  13. *3修改版
  14. forvalues i = 1/39{
  15. local names "`names' `i'"
  16. }
  17. di `names'
  18. 123456789101112131415161718192021222324252627282930313233343536373839

mergenogenerate选项

  nogenerate选项可确保 _merge不被产生出来,这在merge中同时指定了keep(match)选项时会比较有用。

画图的option

  lpattern设定线条的类型,比如虚线;lcolor设定线条的轮廓颜色。
  参考自《Stata绘图:世行可视化案例-条形图-密度函数图-地图-断点回归图-散点图》

在同一幅图里画多条线

  可以采取两种方法:(1)将不同画图命令用“||”相间隔;(2)将不同画图命令用“(...)”来括起来。4

在图中画出箭头

参考《stata图形坐标轴带箭头》,“魅力数据与机器学习”公众号

  1. *画出从(0,0)到(0,1)和从(0,0)到(2,0)两条带箭头的直线
  2. twoway (pcarrowi 0 0 0 1 0 0 2 0)
  3. twoway (pcarrowi 0 0 0 1 0 0 2 0) (pcarrowi 0 0 1 1)
  4. twoway (pcarrowi 0 0 0 1 0 0 2 0) (pcarrowi 0 0 1 1) (function y = 2*x, range(0 1))
  5. twoway (pcarrowi 0 0 0 1 0 0 2 0) (pcarrowi 0 0 1 1) (function y = 2*x, range(0 1)), xlabel(,angle(0) format(%03.1f)) ylabel(,angle(0) format(%03.1f)) title(`"{fontface "隶书":这样的图形,你喜欢吗?}"', c(red))
  6. twoway (pcarrowi 0 0 0 1 0 0 2 0) ///
  7. (pcarrowi 0 0 1 1) ///
  8. (function y = 2*x, range(0 1)), ///
  9. xlabel(,angle(0) format(%03.1f)) ///
  10. ylabel(,angle(0) format(%03.1f)) ///
  11. title(`"{fontface "隶书":这样的图形,你喜欢吗?}"', c(red)) ///
  12. subtitle(`"{fontface "楷体":喜欢{subscript:就}拿{superscript:去}, 不{superscript:用}{subscript:谢}谢我!}"', c(green))

循环语句:foreach,forvaluewhile

  forvalue只可与数值相搭配,而foreach则相对更一般化,可与数值、文件、变量等相搭配,while一般用作条件语句。可用levelsof将相关数值保存到宏之中,再用foreach进行数值调用。
foreach命令可参考《 “环环”入扣之foreach命令》
levelsof命令可参考《Stata中变量观测值的亲密伙伴——levelsof命令》

  1. *forval用法
  2. forval i = 1/3{
  3. ....
  4. }
  5. forval i = 1(2)15{
  6. ....
  7. }
  8. forval k = 5 10 to 300 {
  9. ....
  10. }
  11. *foreach用法
  12. *与数值相联系
  13. *foreach x in 1/1000{ //错误代码!并不与forval 相应命令等价,应使用下条命令
  14. ....
  15. }
  16. foreach i of numlist 1 4/8 13(2)21 103 {
  17. ....
  18. }
  19. *与变量相联系
  20. *不用宏时
  21. foreach var of newlist z1-z20 {
  22. ....
  23. }
  24. foreach var of varlist pri-rep t* {
  25. ....
  26. }
  27. *用宏时
  28. *用varlist调用宏需要加引用符号
  29. local vars "............"
  30. foreach var of varlist `vars'{
  31. ....
  32. }
  33. *用local调用宏不需要加引用符号
  34. local vars "............"
  35. foreach var of local vars{
  36. ....
  37. }
  38. levelsof state, local(year)
  39. foreach i of numlist `year'{
  40. .......
  41. }
  42. *与文件相联系时
  43. *excel文件转换
  44. local vlist "......"
  45. foreach file in xx xx xx {
  46. insheet $vlist using `file'.txt ,clear
  47. save `file'.dta,replace
  48. }
  49. local files: dir "`c(pwd)'" files "*.xlsx"
  50. foreach file in `files'{
  51. local filename = subinstr("`file'",substr("`file'",-5,.),"",.)
  52. import excel using "`file'", clear
  53. save "../output/`filename'.dta", replace
  54. }
  55. *数据集合并
  56. foreach file in female.dta male.dta {
  57. append using `file' /*纵向合并*/
  58. }
  59. list, sep(4)

label:给数据集、数值与变量加标签

  部分数据集中可以实现将数值显示为文字。
  label参考自:《让你的数据一目了然--label命令介绍》
  elabel参考自:《Stata:elabel命令-强大的标签管理工具》

  1. *对数据集贴标签
  2. label data "Abadie(2010)_合成控制法_加州戒烟案例" //给数据集加标签
  3. des
  4. *对数值贴标签
  5. label define fillinlb 1 "发生变动" 0 "未发生变动" //设置标签名fillinlb,也就是要告诉Stata,变量下不同观察值的含义。
  6. label values fillin fillinlb //将设置的标签名fillinlb赋值给具体变量fillinl。
  7. *对已经存在的值标签进行修改,就需要使用addmodifyreplace选项。
  8. label define stkcdlb 1 "平安银行" 600519 "茅台"
  9. label define stkcdlb 600900 "长江电力", add //add用于添加标签名内容
  10. label values stkcd stkcdlb
  11. label define stkcdlb 600519 "贵州茅台", modify //modify用于对已存在的标签名内容做修改
  12. label define fillinglb 1 "变动" 0 "未变动", replace //replace用于替换已存在的标签名内容
  13. *查看标签
  14. label dir //显示有哪些值标签
  15. label list //显示所有值标签的具体内容
  16. des //可同时查看所有标签(表/值/变量)
  17. *删除标签
  18. label drop stkcdlb //删除标签

条件语句

ifelse if语句

  1. *基本语句
  2. if exp {
  3. commands
  4. }
  5. else {
  6. commands
  7. }
  8. *扩展语句
  9. if exp {
  10. commands
  11. }
  12. else if {
  13. commands
  14. }
  15. else {
  16. commands
  17. }

stata画图

参考:
在Stata里面,怎么折腾一幅条形图?
普林斯顿Stata教程 - Stata做图

图例:legend选项

legend选项有许多子选项;用order可以列出图的关键点(即1和2)及其标签。legend(off)可确保无图例,legend(order(1 2 3))可只显示前三个图例。

#delimit ;#delimit cr

参考自:《Stata 中 Do-file 编辑器的使用》《让do文件更直观易懂的两个小方法》
#delimit ;这条命令表示将默认设置的回车分隔符(cr)改变为分号(“;”),在这种情况下,回车后分割开来的多条命令依旧是一条完整的命令,只有在程序的结尾加上“;”,stata才会认为这条程序已编写完毕。
#delimit cr表示的是恢复到原来的默认模式。

  1. #delimit ;
  2. tw(scatter mpg weight if foreign==0)
  3. (scatter mpg weight if foreign==1),
  4. title(行驶历程与车重关系)ytitle(里程)
  5. legend(label(1 国产车)label(2 进口车));
  6. #delimit cr

des2

参考自:《Tips 14:des2描述性统计》
价值:可以便于在不敲代码时查看数据。

  1. sysuse auto,clear
  2. ssc install des2
  3. des2
  4. *然后就可以点了,这时候默认为tab
  5. des2 , cmd(summarize)
  6. *再点,就是sum了。
  7. *再详细,help des2

tabdisp

tabdisp主要用于以图表形式展示数据,并不计算统计量,是为编程者设计的命令。虽然只为编程应用所设计,但是也可用于交互式呈现数据。为了计算并以图表形式展示统计量,则可用table命令。
选项cellvar(varnames):此选项用于指定表格中所要呈现的数值型或文字型变量,最多不超过5个。
选项left:此选项用于指定表格中的列标签左对齐。

  1. tabdisp _Co_Number , c(_W_Weight) left
  2. logout, save("Table2") excel replace fix(8): ///
  3. tabdisp _Co_Number if _Co_Number~=. , c(_W_Weight) left

format

参考自:《Stata中的数值型》
format只控制数据的显示格式,并不改变内存中数据的大小。通常的格式是f格式,也叫固定格式;e格式,指数格式(科学计数法),用于非常大或非常小的数字;g格式,也叫一般格式(数据的转换)。Stata会自动选择f格式或e格式,以达到更好的效果。

  1. format varlist %14.2g
  2. *varlist 是要改变格式的变量;
  3. *14 表示我们显示格式的宽度;
  4. *2 表示小数点后保留两位;
  5. *f 表示固定格式,g表示通用格式,e表示科学计数法。
  6. format varlist %-14.2g
  7. * - 表示左对齐
  8. format varlist %-14.2gc
  9. * c 表示给数据加上千分位符
  10. format varlist %4.2f

在%#w.#df格式中,#w表示字节长度,#d表示保留几位小数。
在类似%#w.#df格式中,#w一定得大于#d,要不然会报错。

数值型变量按其精度区分,有5种类型:
byte表示占1个字节,介于-127和100之间的整数;
int表示占2个字节,介于-32,767与32,740之间的整数;
long表示占4个字节,介于-2,147,483,647和2,147,483,620之间的整数;
float存储的变量的字节数也是4位;double存储的变量的字节数是8位。当运算精度要求很高的时候,需要将变量设置成浮点型(float)或双精度型(double)。

stata中的函数与其他命令

wordcount(s):计算s中单词的个数。
ustrwordcount(s[,loc]):按照loc的定义计算s中的单词的个数。
字符串函数参考:《Stata常用字符串数据处理函数》《Stata常用字符函数(一)》《七条建议:用Stata处理文字变量和字符变量》《Stata 函数大全》
subinstr/subinword参考:《stata命令详解-函数subinstr/subinword》

subinst(s1,s2,s3,n):字符串函数。将字符串s1中的字符串s2出现的前n个,替换成字符串s3。
subinword(s1,s2,s3,n):字符串函数。将字符串s1中的单词s2出现的前n个,替换成字符串s3。

  1. *将this is the day中的第一个is替换成X
  2. subinstr("this is the day","is","X",1) = "thX is the day"
  3. *将this is the hour中的前2is替换成X
  4. subinstr("this is the hour","is","X",2) = "thX X the hour"
  5. *将this is this中的所有is替换成X
  6. subinstr("this is this","is","X",.) = "thX X thX"
  7. *将this is the day中的第一个is单词替换成X
  8. subinword("this is the day","is","X",1) = "this X the day"
  9. *将this is the hour中的所有is单词替换成X
  10. subinword("this is the hour","is","X",.) = "this X the hour"
  11. *将this is this中的所有th单词替换成X,没有th单词不进行替换
  12. subinword("this is this","th","X",.) = "this is this"
  13. * 替换某个字符串变量var中的所有空格,并生成新的变量newvar
  14. gen newvar=subinstr(var," ","",.)

trim()itrim()

如果字符串中存在多余的空格,比如 "I Love Python"," I Love Python","I Love Python "," I Love Python",Stata 会认为这是四个不同的字符串,转换为数字变量的时候,也会对应到四个不同的数字。在处理这类问题的时候,通常使用 trim()itrim() 函数,去掉字符串两端的空格,或者规范字符串内部的空格,将上述四个字符串处理成相同的字符串 "I Love Python"。具体详见 help string functions
引自《七条建议:用Stata处理文字变量和字符变量》

  1. *trim(s)将字符串s的首字母之前和末尾的空格去掉
  2. 例如:trim(" this ") ="this"
  3. *ltrim(s) 将字符串s中首字母之前的空格去掉
  4. 例如:ltrim(" this") = "this"
  5. *itrim(s)` 将字符间多于一个空格缩减为一个空格
  6. 例如:itrim("hello there") = "hello there"

参考文献

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注