@liuyuxi
2021-05-05T14:23:35.000000Z
字数 10639
阅读 245
stata
tempname tempname为指定的本地宏名称分配名称,可作为定义临时标量或矩阵名称使用。当程序或执行文件结束时,任何具有这些指定名称的标量或矩阵将被删除。类似的还有tempfile(临时文件)、tempvar(临时变量)1。
tempname resmat //设定一个临时矩阵叫做resmat
司继春stata讲义第40页补充了用di调用时的注意事项。
nullmat() nullmat()函数:函数作用就是创造了一个空函数,就好像一个空瓶子,我们就只要把新的东西装进去就可以了,而不用考虑这个东西之前是否存在,有点儿类似Python中的空列表或者空词典,通过这个命令可以缩短命令,提高程序运行速度。2
mat,mkmat与svmat mat也即matrix
主要参考:stata带你进入奇幻的矩阵世界
*直接录入矩阵mat X = (2,6,1\3,10,12\2,9,5) //逗号表示每一列,\表示每一行的分隔符mat list X //矩阵的输出*特定类型矩阵mat a=I(3) //生成单位矩阵I(n)函数,其中n表示阶数mat list amat b=J(2,3,4) //生成特定行列(m,n)的矩阵且元素均为k,其函数形式为J(m,n,k)mat list bmat c=(1,2,3)mat C=diag(c) //以c中元素为对角元素利用diag函数生成对角矩阵mat list C*矩阵运算mat d1=d*d //矩阵相乘mat list d1mat d2=d#d //矩阵直乘mat list d2*数据与矩阵的相互转换sysuse auto,clear //调用系统数据keep in 1/6 //以前六行数据为例mkmat mpg //将mpg数据转换为一列矩阵mat list mpgmkmat foreign weight displacement ,mat(x) //转换为多列矩阵mat list xsvmat x,names(x) //矩阵转换为数据主要调用svmat命令,注意:最后生成的变量是x1。matrix drop //删除矩阵matrix rename //矩阵改名matrix dir //列出所有矩阵及其维数mat colnames A=A1 A2 //为矩阵的列命名mat rownames A=obs1 obs2 obs3 obs4 //为矩阵的行命名
rowsof(M):矩阵M的行数。
值得参考的文章:朝花夕拾 | stata返回值
e-class一般在我们用stata做模型估计的时候出现,如regress或logistic;r-class一般出现在例如summarize或describe等命令中;c-class主要储存系统参数。
*列出内存中所有返回值ereturn list // 列出内存中所有的e-class返回值return list // 列出内存中所有的r-class返回值creturn list // 列出内存中所有的c-class返回值* 回归后调用e-classdis e(r2) // 该模型的拟合度dis e(F) //该模型的F值mat list e(b) //系数向量mat list e(V) //方差协方差矩阵*e(sample)use http://www.ats.ucla.edu/stat/stata/notes/hsb2, clearregress read math science if write>=50predict p1summarize p1predict p2 if e(sample)==1 //if e(sample)==1 的作用是针对我们刚刚在模型估计中用到的那些样本。sum p2predict p3 if e(sample)==0sum p3
missing() 当数据存在缺漏值时,传统的做法是使用drop命令。但是有时候需要同时去除多个变量中存在的缺漏值,亦或者要面对不同格式的缺漏值,例如 "." 和 " " 等等,此时missing()可以轻松完成该目标3:
* 基本语法: missing(x1,x2,...,xn) or mi(x1,x2,...,xn)sysuse "nlsw88", clearsum wage hours industry uniondrop if missing(wage, hours, industry, union) //去除缺漏值* 也可以egen miss = rowmiss(wage hours industry union)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键左边。
*for local--------------------------------------------------------local name "happy every day " //将happy every day定义为namedis `name' //展示定义结果happy every day //前两行命令同时使用,展示成功dis `name' //单独使用,展示失败,因为stata已经忘记曾经定义了什么local x=4 //直接赋值local x x1 x2 x3 //将变量赋给局部暂元*for global--------------------------------------------------------global name "happy every day " //将happy every day定义为namedis $name //展示定义结果happy every day //前两行命令同时使用,展示成功dis $name //单独使用,展示成功,因为stata还记得曾经定义了什么happy every dayglobal y ln_incomeglobal keyx birth_placeglobal x x1 x2 x3 x4 x5 x6reg $y &keyx $x ,r //与下面的估计一致reg ln_income birth_place x1 x2 x3 x4 x5 x6,r
文中还介绍了while,foreach,forvalue等。
local与复合引用 local为局部宏(lclnames)指定字符串。允许双引号(“and”)和复合双引号(`“and”'),如果字符串中嵌入了引号,则应当使用复合双引号。
根据help quotes可知:双引号("")常用于封闭字符串,stata中有两类双引号("")与(`""'),后者又称“复合双引号”,与前者作用相同,除非编程所需,否则一般不必使用“复合双引号”。
local a `"example"'if `"`answ'"' == `"yes"' {...}*此处只有`"`answ'"'一处的复合双引号比"`answ'" 的一般双引号更好,`"example"'与`"yes"'的复合双引号均并未比普通双引号更好。
`"`answ`"' 比"`answ`" 更好是因为局部宏`answ`可能本身就包含了(简单或复合)双引号,而(此处所用的)复合双引号最妙的地方就在于他是嵌套的。假设`answ`包含字符串``I "think" so'',那么if "`answ'"=="yes"会使stata迷惑,因为它会被扩展为 if "I "think" so"=="yes";而 if `"`answ'"'==`"yes"'则会被stata扩展为 if `"I "think" so"'==`"yes"'。因为简单形式的开双引号与闭双引号在形式上是一样的,都是";而复合形式的双引号的开双引号与闭双引号却并不相同,开是`",闭是"',所以stata可以根据相应符号来进行封闭。`"I "think" so"'更易于被stata理解,而"I "think" so"更像是一堆无可救药的杂烩。因为stata可以区分开闭引号,所以即使嵌套的复合引号也是可以理解的,比如:`"I `"think"' so"'。的确,复合双引号使你发现你的视野更加断断续续、不清晰,尤其是当其与宏替代字符`'相联系在一起的时候。这也正是就算在编程的工作中,我们也很少使用他们的原因。在进行下面的编程中,使用复合双引号是完全可以接受的:local a "example"if `"`answ'"' == "yes" {...}当然,如果宏内并不包含双引号或者并不在意会发生什么的话,也可以用"`answ'"来代替。
此句code常见于各种合成控制安慰剂检验的推文与贴子中,均以加州控烟案例为基础。我曾以为此code是Abadie(2010)所撰,后在Harvard Dataverse中查到此文的code是用R写成,后来读了刘友金(2018,《房产税对产业转移的影响:来自重庆和上海的经验证据》)所附的code后才知此句原是国人手笔,但后来又发现出处应在stata论坛上,研读此句后有心得如下。原code为:
forvalues i = 1/39{...local names `"`names' `"`i'"'"'...}
如果局部宏内的字符串中没有加入双引号的话,上段code原本应该是:
forvalues i = 1/39{...local names "`names' `"`i'"'"...}
然而宏内包含着双引号,因此,按照help quotes所只称的,应该将局部宏的"..."改为`"..."'。而此处似乎实际上是一个由局部宏嵌套包含自身所构成的局部宏,因为"..."中的`names'似乎正好是在调用上次循环中所建立的局部宏中的内容,而这个宏的右边刚好是由复合双引号所引导的,由局部暂元左撇号与右撇号所包裹的i。这里按说只是把新一次循环中所产生的新次序i加到以往的局部暂元中去,又并非定义新的字符串内部含有双引号的暂元,似乎并无必要在"...."内部使用复合双引号,因此,此处或许可以删去复合引号,从而"...."内部就没有了双引号,因此就也可将原本定义局部暂元的复合双引号删去。因此,修改后的code应为:
forvalues i = 1/39{...local names "`names' `i'"...}
恰与连玉君教授讲义中的相同。
经初步检查,三段code作用相同:
*1原版forvalues i = 1/39{local names `"`names' `"`i'"'"'}di `names'123456789101112131415161718192021222324252627282930313233343536373839*2去外单引号forvalues i = 1/39{local names "`names' `"`i'"'"}di `names'123456789101112131415161718192021222324252627282930313233343536373839*3修改版forvalues i = 1/39{local names "`names' `i'"}di `names'123456789101112131415161718192021222324252627282930313233343536373839
merge的nogenerate选项 nogenerate选项可确保 _merge不被产生出来,这在merge中同时指定了keep(match)选项时会比较有用。
lpattern设定线条的类型,比如虚线;lcolor设定线条的轮廓颜色。
参考自《Stata绘图:世行可视化案例-条形图-密度函数图-地图-断点回归图-散点图》
可以采取两种方法:(1)将不同画图命令用“||”相间隔;(2)将不同画图命令用“(...)”来括起来。4
参考《stata图形坐标轴带箭头》,“魅力数据与机器学习”公众号
*画出从(0,0)到(0,1)和从(0,0)到(2,0)两条带箭头的直线twoway (pcarrowi 0 0 0 1 0 0 2 0)twoway (pcarrowi 0 0 0 1 0 0 2 0) (pcarrowi 0 0 1 1)twoway (pcarrowi 0 0 0 1 0 0 2 0) (pcarrowi 0 0 1 1) (function y = 2*x, range(0 1))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))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)) ///subtitle(`"{fontface "楷体":喜欢{subscript:就}拿{superscript:去}, 不{superscript:用}{subscript:谢}谢我!}"', c(green))
foreach,forvalue与while forvalue只可与数值相搭配,而foreach则相对更一般化,可与数值、文件、变量等相搭配,while一般用作条件语句。可用levelsof将相关数值保存到宏之中,再用foreach进行数值调用。
foreach命令可参考《 “环环”入扣之foreach命令》
levelsof命令可参考《Stata中变量观测值的亲密伙伴——levelsof命令》
*forval用法forval i = 1/3{....}forval i = 1(2)15{....}forval k = 5 10 to 300 {....}*foreach用法*与数值相联系*foreach x in 1/1000{ //错误代码!并不与forval 相应命令等价,应使用下条命令....}foreach i of numlist 1 4/8 13(2)21 103 {....}*与变量相联系*不用宏时foreach var of newlist z1-z20 {....}foreach var of varlist pri-rep t* {....}*用宏时*用varlist调用宏需要加引用符号local vars "............"foreach var of varlist `vars'{....}*用local调用宏不需要加引用符号local vars "............"foreach var of local vars{....}levelsof state, local(year)foreach i of numlist `year'{.......}*与文件相联系时*excel文件转换local vlist "......"foreach file in xx xx xx {insheet $vlist using `file'.txt ,clearsave `file'.dta,replace}local files: dir "`c(pwd)'" files "*.xlsx"foreach file in `files'{local filename = subinstr("`file'",substr("`file'",-5,.),"",.)import excel using "`file'", clearsave "../output/`filename'.dta", replace}*数据集合并foreach file in female.dta male.dta {append using `file' /*纵向合并*/}list, sep(4)
label:给数据集、数值与变量加标签 部分数据集中可以实现将数值显示为文字。
label参考自:《让你的数据一目了然--label命令介绍》
elabel参考自:《Stata:elabel命令-强大的标签管理工具》
*对数据集贴标签label data "Abadie(2010)_合成控制法_加州戒烟案例" //给数据集加标签des*对数值贴标签label define fillinlb 1 "发生变动" 0 "未发生变动" //设置标签名fillinlb,也就是要告诉Stata,变量下不同观察值的含义。label values fillin fillinlb //将设置的标签名fillinlb赋值给具体变量fillinl。*对已经存在的值标签进行修改,就需要使用add、modify、replace选项。label define stkcdlb 1 "平安银行" 600519 "茅台"label define stkcdlb 600900 "长江电力", add //add用于添加标签名内容label values stkcd stkcdlblabel define stkcdlb 600519 "贵州茅台", modify //modify用于对已存在的标签名内容做修改label define fillinglb 1 "变动" 0 "未变动", replace //replace用于替换已存在的标签名内容*查看标签label dir //显示有哪些值标签label list //显示所有值标签的具体内容des //可同时查看所有标签(表/值/变量)*删除标签label drop stkcdlb //删除标签
if与else if语句
*基本语句if exp {commands}else {commands}*扩展语句if exp {commands}else if {commands}else {commands}
参考:
在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表示的是恢复到原来的默认模式。
#delimit ;tw(scatter mpg weight if foreign==0)(scatter mpg weight if foreign==1),title(行驶历程与车重关系)ytitle(里程)legend(label(1 国产车)label(2 进口车));#delimit cr
des2参考自:《Tips 14:des2描述性统计》
价值:可以便于在不敲代码时查看数据。
sysuse auto,clearssc install des2des2*然后就可以点了,这时候默认为tabdes2 , cmd(summarize)*再点,就是sum了。*再详细,help des2
tabdisptabdisp主要用于以图表形式展示数据,并不计算统计量,是为编程者设计的命令。虽然只为编程应用所设计,但是也可用于交互式呈现数据。为了计算并以图表形式展示统计量,则可用table命令。
选项cellvar(varnames):此选项用于指定表格中所要呈现的数值型或文字型变量,最多不超过5个。
选项left:此选项用于指定表格中的列标签左对齐。
tabdisp _Co_Number , c(_W_Weight) leftlogout, save("Table2") excel replace fix(8): ///tabdisp _Co_Number if _Co_Number~=. , c(_W_Weight) left
format参考自:《Stata中的数值型》
format只控制数据的显示格式,并不改变内存中数据的大小。通常的格式是f格式,也叫固定格式;e格式,指数格式(科学计数法),用于非常大或非常小的数字;g格式,也叫一般格式(数据的转换)。Stata会自动选择f格式或e格式,以达到更好的效果。
format varlist %14.2g*varlist 是要改变格式的变量;*14 表示我们显示格式的宽度;*2 表示小数点后保留两位;*f 表示固定格式,g表示通用格式,e表示科学计数法。format varlist %-14.2g* - 表示左对齐format varlist %-14.2gc* c 表示给数据加上千分位符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)。
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。
*将this is the day中的第一个is替换成Xsubinstr("this is the day","is","X",1) = "thX is the day"*将this is the hour中的前2个is替换成Xsubinstr("this is the hour","is","X",2) = "thX X the hour"*将this is this中的所有is替换成Xsubinstr("this is this","is","X",.) = "thX X thX"*将this is the day中的第一个is单词替换成Xsubinword("this is the day","is","X",1) = "this X the day"*将this is the hour中的所有is单词替换成Xsubinword("this is the hour","is","X",.) = "this X the hour"*将this is this中的所有th单词替换成X,没有th单词不进行替换subinword("this is this","th","X",.) = "this is this"* 替换某个字符串变量var中的所有空格,并生成新的变量newvargen 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处理文字变量和字符变量》
*trim(s)将字符串s的首字母之前和末尾的空格去掉例如:trim(" this ") ="this"*ltrim(s) 将字符串s中首字母之前的空格去掉例如:ltrim(" this") = "this"*itrim(s)` 将字符间多于一个空格缩减为一个空格例如:itrim("hello there") = "hello there"