@liuyuxi
2021-05-05T14:23:35.000000Z
字数 10639
阅读 62
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 a
mat b=J(2,3,4) //生成特定行列(m,n)的矩阵且元素均为k,其函数形式为J(m,n,k)
mat list b
mat c=(1,2,3)
mat C=diag(c) //以c中元素为对角元素利用diag函数生成对角矩阵
mat list C
*矩阵运算
mat d1=d*d //矩阵相乘
mat list d1
mat d2=d#d //矩阵直乘
mat list d2
*数据与矩阵的相互转换
sysuse auto,clear //调用系统数据
keep in 1/6 //以前六行数据为例
mkmat mpg //将mpg数据转换为一列矩阵
mat list mpg
mkmat foreign weight displacement ,mat(x) //转换为多列矩阵
mat list x
svmat 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-class
dis 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, clear
regress read math science if write>=50
predict p1
summarize p1
predict p2 if e(sample)==1 //if e(sample)==1 的作用是针对我们刚刚在模型估计中用到的那些样本。
sum p2
predict p3 if e(sample)==0
sum p3
missing()
当数据存在缺漏值时,传统的做法是使用drop
命令。但是有时候需要同时去除多个变量中存在的缺漏值,亦或者要面对不同格式的缺漏值,例如 "." 和 " " 等等,此时missing()
可以轻松完成该目标3:
* 基本语法: missing(x1,x2,...,xn) or mi(x1,x2,...,xn)
sysuse "nlsw88", clear
sum wage hours industry union
drop 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定义为name
dis `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定义为name
dis $name //展示定义结果
happy every day //前两行命令同时使用,展示成功
dis $name //单独使用,展示成功,因为stata还记得曾经定义了什么
happy every day
global y ln_income
global keyx birth_place
global x x1 x2 x3 x4 x5 x6
reg $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 ,clear
save `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'", clear
save "../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 stkcdlb
label 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,clear
ssc install des2
des2
*然后就可以点了,这时候默认为tab
des2 , cmd(summarize)
*再点,就是sum了。
*再详细,help des2
tabdisp
tabdisp
主要用于以图表形式展示数据,并不计算统计量,是为编程者设计的命令。虽然只为编程应用所设计,但是也可用于交互式呈现数据。为了计算并以图表形式展示统计量,则可用table
命令。
选项cellvar(varnames)
:此选项用于指定表格中所要呈现的数值型或文字型变量,最多不超过5个。
选项left
:此选项用于指定表格中的列标签左对齐。
tabdisp _Co_Number , c(_W_Weight) left
logout, 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替换成X
subinstr("this is the day","is","X",1) = "thX is the day"
*将this is the hour中的前2个is替换成X
subinstr("this is the hour","is","X",2) = "thX X the hour"
*将this is this中的所有is替换成X
subinstr("this is this","is","X",.) = "thX X thX"
*将this is the day中的第一个is单词替换成X
subinword("this is the day","is","X",1) = "this X the day"
*将this is the hour中的所有is单词替换成X
subinword("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中的所有空格,并生成新的变量newvar
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处理文字变量和字符变量》
*trim(s)将字符串s的首字母之前和末尾的空格去掉
例如:trim(" this ") ="this"
*ltrim(s) 将字符串s中首字母之前的空格去掉
例如:ltrim(" this") = "this"
*itrim(s)` 将字符间多于一个空格缩减为一个空格
例如:itrim("hello there") = "hello there"