普林斯顿Stata教程 - Stata编程

译者:谢做翰 | 连玉君 | (知乎 | 简书 | 码云)

原文连接:Princeton Stata 在线课程 (Princeton University - Stata Tutorial )

Stata 现场培训报名中git

Stata连享会 精品专题 || 精彩推文
程序员

专题连接

目录

3.1 暂元github

  • 3.1.1 在暂元中存储文本
  • 3.1.2 在暂元中存储结果
  • 3.1.3 全局暂元与键盘映射
  • 3.1.4 关于暂元的更多信息
    3.2 循环
  • 3.2.1 遍历数字序列循环
  • 3.2.2遍历列表中的元素
  • 3.2.3 循环专用列表
  • 3.2.4 while循环
  • 3.2.5 条件执行

3.3 编写命令web

  • 3.3.1 无参数程序
  • 3.3.2 有参数的程序
  • 3.3.3 复合引号
  • 3.3.4 位置参数
  • 3.3.5 使用Stata语法
  • 3.3.6建立新变量
  • 3.3.7 Coale-McNeil 拟合

3.4其余主题express


这部分是对Stata编程的简单介绍。主要讨论暂元循环,并展现如何编写简单程序。编程是一个很大的主题,我在这里仅进行一些提示,但愿能激发你进一步学习的兴趣。本文所涵盖的材料将帮助你更有效地使用Stata。编程

Stata 9引入了一种新的很是强大的矩阵编程语言Mata。这极大扩展了程序员的工具,远远超出了这里所讨论的暂元,可是Mata是一个值得单独讨论的主题,因此本文不会对此进行介绍。然而,您在这里的努力不会白费,由于Mata仅是Stata编程的补充,而不是彻底替代。
要了解关于Stata编程的更多信息,我建议您使用Kit Baum的Stata编程简介,如今已发布到第二版。您也能够查阅用户指南第18章,根据须要参考。Nick Cox在Stata Journal的专栏也是学习Stata的绝佳资源。网络

3.1 暂元

暂元是一个与一些文本相关联的名称,依据范围可分为全局暂元与暂元。编程语言

3.1.1 在暂元中存储文本

暂元名称最多为31个字符,而且仅在当前环境(语境)中被识别(console,do file或programe)。编辑器

暂元定义语句为local name [=] text,输入 `name’ (请注意使用反引号和左引号。)进行调用。svg

第一种变体不带等号,用于存储任意文本,最多可达64k个字符(在Stata SE中最多可达100万个字符)。文本一般用引号引发来,但不是必须。

示例:回归方程中的控制变量

有时你须要运行一堆回归方程,其中包括一组标准的控制变量,好比age,agesq,education,和income。固然,你能够在每一个等式中键入这些名称,或者能够剪切和粘贴名称,但这些方法很繁琐且容易出错。聪明的方法是定义一个暂元

local controls age agesq education income

而后,输入命令

regress outcome treatment `controls'

它与一下命令彻底等价

regress outcome treatment age agesq education income

若是只运行一次回归,不须要保存信息,可是若是你必须运行多个具备不一样结果或处理方式的模型,使用暂元能够提升效率并确保一致性。

这种方法还有一个好处是,若是之后你意识到你应该对某个控制变量取对数,你只需改变暂元的定义便可,好比将income改成logimcome,对暂元所作的改变会在全部后续模型中应用。

警告:输入不存在的暂元不是错误;,只是会返回一个空字符串。因此要当心拼写正确的暂元名称。若是输入regress outcome treatment `contrls’,Stata将读取regress outcome treatment,由于暂元contrls不存在。若是你输入control的话,也会发生一样的状况,由于暂元名称不能按变量名称的方式缩写。

示例:管理虚拟变量

假设你正在参与人口调查工做,受访人按年龄以5年分为一组,从age15to19age45to49共分为七组。其中有六组会做为虚拟变量在回归中使用。定义一个暂元

local age "age20to24 age25to29 age30to34 age35to39 age40to44 age45to49"

而后在你的回归模型中使用

regress ceb `age' urban

这不只更短,更具可读性,并且更接近你的意图。这也使得改变对年龄的表示更为容易,若是您之后决定使用线性和二次项表示年龄,则只需定义暂元local age "age agesq"并从新运行模型。请注意,第一个age是暂元的名称,第二个是变量的名称。在此我用引号使代码更清晰。

请注意嵌套的暂元。若是一个暂元中包含了另外一个暂元(在此不妨称为子暂元),新暂元的内容是在建立那一刻就肯定的(解析),而不是在被评估时被解析。例如,若是你定义暂元local controls `age’ income education。在定义新暂元control时Stata认为其中包含子暂元age并对子暂元内容展开解读,就算在将来你改变了子暂元age的内容,新暂元中保留的依然是建立时点子暂元的内容与形式。

可是,有一种方法能够实现新暂元随子暂元同步更新的效果。诀窍是在定义暂元时输入斜杠号避开暂元评估字符local controls `age’ income education。如今Stata不评估暂元,因此controls内容变成了**`age’ income education**。当暂元controls被评估时,Stata才会发现它包含暂元age并对其展开解读。

3.1.2 在暂元中存储结果

第二种类型的暂元定义local name = text(含等于号)用于存储结果。它指示Stata将右侧的文本视为表达式,对其进行评估,并在指定名称中存储结果的文本表达。

假设你只是运行一个回归,并想存储R平方结果,以便与后面的回归进行比较。你知道regress命令将残差平方和存储在e(r2)中,因此你认为以下命令将会奏效:

local rsq e(r2)

但事实并不是如此。您的暂元所存储是公式e(r2),如过你输入

display "`rsq'"

你看到的是一条公式,而不是咱们所要的数值。解决方法是使用等号链接local rsq = e(r2),这会t提示Stata计算表达式并存储结果。

要看到差别,请尝试一下代码

. sysuse auto, clear
(1978 Automobile Data)

. quietly regress mpg weight

. local rsqf e(r2)

. local rsqv = e(r2)

. di `rsqf'       // this has the current R-squared
.65153125

. di `rsqv'       // as does this
.65153125

. quietly regress mpg weight foreign

. di `rsqf'       // the formula has the new R-squared
.66270291

. di `rsqv'       // this guy has the old one
.65153125

当你仅仅是想存储文本信息是也可使用等号,但我并不推荐,尤为当你使用的是旧版Stata时,会带来没必要要的麻烦。以local controls = "age agesq education income"为例,使用等号不影响正常工做,但会使右引号左边内容被Stata计算,并被标记为字符串格式——最多输入244个字符,而正常暂元文本可输入更多内容。

3.1.3 全局暂元与键盘映射

全局暂元名称最多可包含32个字符,正如名称所示,它具备全局范围。

你能够定义一个全局暂元,global name [=] text并使用$name进行计算。(你可能须要用${name}限定名称的结尾)

我建议你避免使用全局暂元,由于存在名称冲突的可能性。一个有用的应用是使用键盘上的功能键映射。若是你在一个名字很长的共享网络文件夹上工做,请尝试

global F5 \\server\shared\research\project\subproject\

当你打F5时,Stata会替换全名。而你的do files可使用命令do${F5}dofile(咱们须要大括号来代表暂元名称是F5,而不是F5dofile

显然你不想在每次使用Stata时输入这个暂元,你能够将其输入到你的profile.do文件——每次运行Stata时执行的一组命令。一般状况下,你的我的配置文件最好存储在Stata的启动目录C:\data中。help profilew了解更多信息。

3.1.4 关于暂元的更多信息

暂元也可用于使用扩展暂元函数获取和存储关于系统或数据集中变量的信息。例如,你能够检索变量和值标签。还有一些命令能够管理你的暂元集合,包括macro listmacro drophelp macro了解更多信息。

3.2 循环

循环用于完成重复性任务。Stata的命令容许循环遍历数字序列和包括变量列表在内的各类类型列表。在咱们开始以前,不要忘记Stata本身作了不少循环。若是你想计算收入的对数,你能够在Stata中用一行代码来实现:

gen logincome = log(income)

这行代码隐晦地在全部观测值上循环,计算每一个收入的对数,又称为矢量化操做。你能够本身编写循环,可是没有必要。第一,你不须要;第二,你的代码会比Stata内置循环慢不少

3.2.1 遍历数字序列循环

基本的循环命令采用这种形式

forvalues number = sequence {
    ... body of loop using `number' ...
}

forvalues是一个关键字,number是一个暂元的名称,它将被设置为序列中的每一个数字,sequence是一个以下形式的数值范围

  • min/max:从minmax以1为步长的数字序列,例如1/3产生1,2和 3
  • first(step)last:从firstlaststep为步长依次排列的数字序列例如15(5)50为15,20,25,30,35,40,45和50。

(指定第二种序列的方法有两种,这里列出的是最清晰的,替代方案请参阅help forvalues

开头的左大括号必须是第一行的最后一项(注释除外),而且循环必须以独立成行的右大括号结束。循环会对序列中的每一个值执行一次并将结果保存在暂元number(本例中暂元名为number)中。

建立虚拟变量

这是我最喜欢的建立年龄组虚拟变量的方式。虽然Stata 11引入了因子变量,Stata 13改进了估算表格的标签,大大减小了“滚动本身的”虚拟变量的需求,但代码仍然具备启发性。

forvalues bot = 20(5)45 {
    local top = `bot' + 4
    gen age`bot'to`top' = age >= `bot' & age <= `top'
}

这将建立一组虚拟变量age20to24age45to49。循环时,暂元bot将以5为步长在20和45范围内取值表示年龄组的下限(即20,25,30,35,40和45)。

在循环内部,咱们建立一个暂元top来表示年龄段的上限,它等于下限加4。第一次循环中bot是20,因此top是24.咱们使用等号来存储bot加4的结果

下一行是一个简单的生成语句。第一次循环时语句会显示gen age20to24 = age >= 20 & age <= 24(你能够创建本身的暂元来查看),这将建立第一个虚拟变量,而后Stata将返回顶部建立下一个。

连享会计量方法专题……

3.2.2遍历列表中的元素

第二个循环命令是foreach,它有六种风格,以处理不一样类型的列表。我将从通用列表开始:

foreach item in a-list-of-things {
    ... body of loop using `item' ...
}

foreach是一个关键字,item是本身选择的暂元名称,in是另外一个关键字,紧跟着是空格分隔的单词。试试这个例子

foreach animal in cats and dogs {
    display "`animal'"
}

因为暂元animal被设置为列表中的每一个单词,所以该循环将输出**“猫”“和”“狗” **。Stata不知道“和”不是一种动物,但即便这样作,它也不会在乎,由于这个列表是通用的。

若是你想循环一个不规则的数字序列 - 例如你须要用Coale-Demeny区域模型生命表对第2,6和12级作一些事情 - 你能够编写

foreach level in 2 6 12 {
… do something with `level’ …
}
这多是你须要了解循环的所有内容。

3.2.3 循环专用列表

foreach还有其余五种变体,它们在特定类型的列表上循环,我如今简要介绍它们。

变量列表

也许是最有用的变体

foreach varname of varlist list-of-variables {
    ... body of loop using `varname' ...
}

这里foreachofvarlist是关键字,它们必须准确输入。list-of-variables是一个存储变量名字的列表。你能够进行适当缩写,好比使用类型变量的名称var*来指代以“var”开头的全部变量,或var1-var3对变量var1var3进行引用。

这种循环的有点是foreach varname in list-of-variables命令中Stata会检查列表中的每一个名称是否确实是现有的变量,而且能够缩写或使用扩展名称。

若是你须要对新生成变量进行循环,使用命令foreach varname of newlist list-of-new-variables。关键字newlist替换原有的varlist,告诉Stata检查列表中此前不存在的变量名称。

遍历暂元中词汇

其余两个变体循环遍历本地或全局暂元中的单词,格式是分别使用关键字globallocal,后跟暂元名称(代替列表名)。例如,这里有一种方法能够从暂元中列出控制变量名称

foreach control of local controls {
    display "`control'"
}

在数据集中咱们可使用foreachvarlist来实现相同目的。

数字列表

Stata中有一个foreach变体专门用于处理forvalues没法处理的数字列表。

假设一项调查在1980年开始进行,并在1985年和1995跟进。(在1990年虽然他们一样但愿跟进,但并未获得资助),要对间隔不规则数字列表进行循环,你可使用

foreach year of numlist 1980 1985 1995 {
    display "`year'"
}

你能够作一些比打印年份名更有趣的事情,好比将numlist指定为1 2 3或1/5((意思是1 2 3 4 5)),或是1(2)7(从1到7以2为步长计数以获得1 3 5 7); 更多信息help numlist

这个命令优于优势通用命令的地方是Stata会检查数字列表中的每一个元素是否为一个数字。

3.2.4 while循环

与许多编程语言同样,Stata也有一个while循环,它具备如下结构

while condition {
    ... do something ...
}

条件是表达式。**只要条件为真(非零),循环就会执行。**一般状况下,内部循环时会有条件不知足,不然代码将永远运行。

while循环一种典型用途是迭代估计,当连续估计的差值大于预设的容差循环继续进行。迭代计数一般用于检测对象是否缺少收敛性。

continue [,break]命令将会中断包括while,forvalues,foreach在内的全部循环。该命令将中止当前迭代并继续下一个迭代,除非已经指定了break,不然将退出循环。

3.2.5 条件执行

Stata的也有一个if编程命令,为了避免与限定子集的限定符if混淆(如summarize mpg if foreign),该if命令具备如下结构

if expression {
    ... commands to be executed if expression is true ...
}
else {
    ... optional block to be executed if expression is false ...
}

这里if和可选的else是关键字,help exp了解表达式信息。{必须是一行中最后一项(注释除外),}必须单独成行。

若是ifelse部分由单个命令组成,便不须要大括号而且能够单独成行,如if expression command。但不可使用括号状况下同行成列如if expression { command }。你能够将代码分红三行来使用大括号,这一般会提升代码的可读性。

在这里咱们设置一个简单的循环,在十次迭代的五次以后中止,

forvalues iter=1/10 {
    display "`iter'"
    if `iter' >= 5 continue, break
}

连享会计量方法专题……

3.3 编写命令

咱们接下来的任务是编写本身的Stata命令,跟随咱们开发几个简单的程序,一个用于标注你的输出( sign your output),另外一个来评估Coale-McNeil模型的婚礼安排,咱们能够建立以下所示图表:

3.3.1 无参数程序

让咱们开发一个命令,以你的名字标注你的输出。开发一个命令最简单的方法是从一个do文件开始。启动Stata的do-file编辑器(Ctrl+9)并输入:

capture program drop sign
program define sign
    version 9.1
    display as text "Germán Rodríguez "
    display "{txt}{hline 62}"
end

若是你如今输入sign,Stata将使用文本样式显示签名
签名

program drop在须要改变do file内容或从新运行该文件时使用,相似于数据集中的clear命令。由于你不能定义一个已经存在的程序。在一次使用时须要capture,此时没有什么程序须要删除。

version 9.1代表该命令是为Stata版本9.1开发的,能够帮助将来版本的Stata正确运行它,即便语法在此期间发生了变化。

最后一行使用了一些SMCL(Stata Markup Control Language),发音为“smickle”,Stata标记控制语言是Stata输出处理器的名称。SMCL使用纯文本结合大括号中。例如,{txt}将显示模式设置为文本,{hline 62}绘制一个宽度为62个字符的水平线。了解更多关于SMCL类型的信息help smcl

3.3.2 有参数的程序

为了制做有用的程序,你常常须要在命令后面输入参数以传递信息给它们。让咱们写一个可以回应你所说的话的命令:

capture program drop echo
program define echo
    version 9.1
    display as text "`0'"
end

尝试输入echo Programming Stata Tutorial看看会发生什么。

当你调用echo命令时,Stata将参数存储在名为0的暂元中,而且用display命令将暂元结果以文本呈现,因为是文本,因此带上双引号。(假如你输入echo Hi,暂元0由空白变为Hi,命令会读取display Hi,此时stata会报错没法找到Hi命令,咱们但愿命令读取`display “Hi”,所以为暂元添加引号)

echo程序

若是咱们没有指定任何内容,则暂元0将是一个空字符串,该命令将读取display ""而且Stata将打印一个空行。

3.3.3 复合引号

在庆祝以前,咱们须要解决新命令的一个小问题。输入echo The hopefully "final" run,Stata会报错。为何呢?由于 "final"中含有引号在读取命令显示为:

display "The hopefully "final" run"

Stata理解的则是 “The hopefully” final “run”,两个引号包围的词夹着没有引号的final,这在Stata看来是一句无效表达。显然咱们须要一些方法来区份内部和外部引用。

顺便提一句,你能够经过set trace on命令看到Stata执行的整个过程(以下所示)。完成后别忘了输入set trace offhelp trace以了解更多信息。

echo The hopefully "final" run
---------------------------------------------------------------- begin echo ---
- version 9.1
- display as text "`0'"
= display as text "The hopefully "final" run"
The hopefully final" run" invalid name
------------------------------------------------------------------ end echo ---
r(198);

那么问题该如何解决呢?答案是使用Stata的复合引号:
`"开始," '结束,例如`"compound quotes"'。因为打开和关闭符号不一样,这些引号能够嵌套。复合引号能够在任何使用双引号的地方使用。若是引用的文本包含双引号,则必须使用复合引号。
因此咱们的最终版本是display "`0'"

program define echo
    version 9.1
    if `"`0'"' != "" display as text `"`0'"'
end

你会注意到我删去了capture drop line这是由于咱们如今准备将程序保存为ado文件。输入sysdir以找出您的我的ado目录位置,而后将文件保存为echo.ado。如今你能够在任意时刻调用该命令。

(ps,若是要确认新建命令没有和官方命令重名,输入which echo.Stata ,获得回复file echo.Stata not allowable filetype便可)

3.3.4 位置参数

Stata除了将全部参数一块儿存储在暂元0,还会把参数的文本分别存储在暂元’1’,‘2’,'3’等等之中(使用参数做为分隔符),并在这些暂元中对解析参数。

一般你会先解析暂元`1'而后转向下一个。这时mac shift命令会派上用场,由于它将全部的暂元都向下移动一个,因此如今2的内容在1,3的内容在2等等。这样,你只需一直对暂元1处理便可,直到列表耗尽时1内容为空,你的工做就完成了。

下是显示参数内容的规范程序:

capture program drop echo
program define echo
    version 9.1
    while "`1'" != "" {
        display `"`1'"'
        mac shift
    }
end

不要忘记mac shift,不然你的程序可能会永远运行。(或者直到你按下break

尝试echo one two three testingecho one "two and three" four。体会如何经过使用引号将多个单词分组为单个参数。

(ps:咱们不只能够将参数传递给命令,还能够将其传递给do files,help do以便了解更多信息。)

3.3.5 使用Stata语法

若是你使用标准的stata语句,你能够充分利用stata本身的解析器,它能够方便地将全部元素存储在暂元中供你使用,不过一个标准的stata语句意味你的参数必须是一个变量列表,或是权重,if/in子句,或是一堆选项中的一种或多种。

一个命令原型
让咱们编写一个命令,用一个给定的均值,标准差和结婚比例的Coale-McNeil模型计算必定年龄段的结婚几率。咱们设计的使用语法是:

pnupt age, generate(married) [ mean(25) stdev(5) pem(1)]

对照语法,咱们须要包含确切年龄数据的年龄变量,以及一个必须选项——在给定结婚比例时生成一个新变量。还有一些可选选项指定平均值,标准差和结婚比例,固然这些都预设有默认值。
所以,咱们须要一个具备确切年份的年龄的现有变量,以及一个强制选项,指定一个以已婚比例生成的新变量。还有一些选项能够指定时间表中的平均值,标准误差和结婚比例,全部这些都有默认值。这是命令的第一步

capture program drop pnupt
program define pnupt
    version  9.1
    syntax varname, Generate(name) ///
        [ Mean(real 25) Stdev(real 5) Pem(real 1) ]
    // ... we don't do anything yet ...
end

首先要注意的是,该syntax命令看起来很是像咱们的原型。

变量列表

在咱们的语法中的第一个元素是一个变量列表varlist。你能够指定最小值和最大值,例如一个须要两个变量的程序varlist(min=2 max=2)。当咱们只有一个变量时,能够输入varname,这是varlist(min=1 max=1)的简称。

而后,Stata将确保您的程序调用时使用的是一个现有变量的名称,该变量将被存储在名为varlist的暂元中。(t即便你只有一个变量并在你的语法语句中使用varname,暂元名依然是varlis)尝试pnupt nonesuch,Stata会抱错,说“variable nonesuch not found”。

(若是你以前有过编程经验,而且花费大部分时间用于检查输入错误,仅少部分真正用于手头任务,你将会很是喜欢syntax,由于它为你执行了不少错误检查)

选项和默认值

可选语法元素包含在方括号[]中。在咱们的命令中,generate选项是必需的,其余三个是可选的。尝试使用这些命令生成一个范围在15到50的年龄变量小测试数据集

drop _all
set obs 36
gen age = 14 + _n

如今尝试pnupt age。此次Stata并未对age变量报错,但提示 ‘option generate() required’。带参数的选项须要指定参数类型(integer,real,string,name)和默认(不强制)值。generate须要一个name,没有默认值。尝试pnupt age, gen(2)。Stata会抱怨说2不是一个变量名。

正常状况下,选项的内容将存储在与选项同名的暂元中。

检查参数
如今咱们须要作一些工做来检查名称是不是一个有效的变量名称,咱们使用confirm

confirm new variable `generate'

而后Stata检查你是否能够生成这个变量,若是不行,则发出错误110.尝试pnupt age, gen(age),Stata会说 ‘age already defined’。

如今你应该清楚,stata会检查均值,标准差和结婚比例这三个选项是否有指定数值(缩写为m()s()p()),这些值必须是实数,并将被存储在名为mean, stdev, 和pem的暂元中。

你能够对输入作更多的检查。让咱们快速检查全部三个参数是负数,其中比例不能大于1。

if (`mean' <= 0 | `stdev' <= 0 | `pem' <= 0 | `pem' > 1) {
    di as error "invalid parameters"
    exit 110
}

你可能但愿对每一个参数进行单独检查,这正是接下来咱们要作的。

临时变量

咱们如今准备利用Coale-McNeil模型和伽玛分布之间的关系作一些计算,下面是该程序的工做版本

program define pnupt
*! Coale-McNeil cumulative nuptiality schedule v1 GR 24-Feb-06
    version 9.1
    syntax varname, Generate(name) [Mean(real 25) Stdev(real 5) Pem(real 1)]
    confirm new var `generate'
    if `mean' <= 0 | `stdev' <= 0 | `pem' <= 0 | `pem' > 1 {
        display as error "invalid parameters"
        exit 198
    }
    tempname z g
    gen `z' = (`varlist' - `mean')/`stdev'
    gen `g' = gammap(0.604, exp(-1.896 * (`z' + 0.805)))
    gen `generate' = `pem' * (1 - `g') 
end

咱们能够将几率公式一行写出,但这会牺牲可读性。相反,咱们先对年龄变量进行标准化,只是咱们该如何称呼这个新变量呢?你或许会叫它z,这固然能够。只是若是你命令的用户恰巧有一个变量叫z该怎么办呢?当咱们计算伽玛函数后,咱们又应该如何命令称呼结果呢?

上述问题的答案是tempname命令,该命令使stata生成惟一的临时变量名,本例中两个变量名会分别被存储在暂元zg中。因为这些暂元是本地的,所以不存在名称冲突的问题。临时变量的另外一个特色是当程序结束时它们会自动消失,全部工做stata会自动替你作好。

gen `z' = (`varlist' - `mean')/`stdev'

这行代码乍一看会有些奇怪,但请记住咱们全部感兴趣的量如今都存储在暂元中,咱们调用时必须先对暂元解析:z'获取咱们临时变量的名称,varlist’获取用户指定的年龄变量的名称,mean'获取平均值,stdev’获得标准差的值。在暂元代换以后,这行代码会读取相似的内容gen _000001 = (age-22.44)/5.28,这可能会更有意义。

if/in

你可能在考虑容许用户在命令中指定ifin条件,这须要添加到syntax中,它们将被存储在暂元中,而后你能够在计算中使用它们,在这种状况下传递给生成。

有关此主题类型的更详细的讨论help syntax

3.3.6建立新变量

有时你编写的命令会建立一个新的变量。事实上,这就是咱们的小命令所作的。若是咱们可使用egen像这样的一种命令输入形式会很是方便:

egen married = pnupt(age), mean(22.48) stdev(5.29) pem(0.858)

答案是确定的。由于egen是用户可扩展的。要实现一个名为pnupt的函数,你必须建立一个程序(do files )的_gpnupt,换句话说就是添加前缀_g。关于egen扩展的文档有点稀少,但一旦你知道了这个基本事实,你只须要查看egen命令的源文件并复制便可。

因此这里是咱们的Coale-McNeil命令版本的egen

program define _gpnupt
*! Coale-McNeil cumulative nuptiality schedule v1 GR 24-Feb-06
    version 9.1
    syntax newvarname=/exp [, Mean(real 25) Stdev(real 5) Pem(real 1)]
    if `mean' <= 0 | `stdev' <= 0 | `pem' <= 0 | `pem' > 1 {
        display as error "invalid parameters"
        exit 198
    }
    tempname z g
    gen `z' = (`exp' - `mean')/`stdev'
    gen `g' = gammap(0.604, exp(-1.896 * (`z' + 0.805)))
    gen `typlist' `varlist' = `pem' * (1 - `g') 
end

这个版本和上一个之间的差别很小,主要体如今egen接受表达式输入而不是单单变量输入.输入参数会被解析并存储在一个名为exp的临时变量中。输出变量被指定为varlist,在本例中为newvarname。这就是为何z如今与expgen产生varlisttyplist的存在是由于egen可让你指定输出变量的类型(默认状况下为float)并传递给咱们的函数,函数再将它传递给gen

3.3.7 Coale-McNeil 拟合

咱们准备揭示最初的图形是如何制做的。这些数据能够在我网站的人口统计部分的Stata文件中找到,数据包括已婚和单身女性的年龄。咱们将计算观察到的已婚比例,根据Rodríguez和Trussell(1980)的估计值计算拟合值,并绘制结果图。这一切只需几行代码便可完成。

use http://data.princeton.edu/eco572/datasets/cohhnupt
gen obs = ever/total
egen fit = pnupt(age+0.5), mean(22.44) stdev(5.28) pem(.858)
gen agem = age + 0.5
twoway (scatter obs agem) (line fit agem), ///
    title(Proportions Married by Age) subtitle(Colombia 1976) ///
    ytitle(Proportion married) xtitle(age)

3.4其余主题

因为缺少时间和篇幅,我尚未讨论程序返回值,help return了解更多信息。对于能够发布估计结果的估计命令的相关主题,请参阅help ereturnhelp _estimates。关于估计的重要参考是Maximum Likelihood Estimation with Stata, Fourth Edition, by Gould, Pitblado and Poi (2010).

其余有趣的主题还有矩阵(help matrix),对于输出更深刻的讨论须要了解更多SMCL的信息(help smcl)。对于图形工做,你可能想要学习类的编程(help class)并学习sersets(help serset)。为你的命令提供一个图形用户界面help dialog programming

[参考]: RodríguezG.和Trussell TJ(1980);测量数据对Coale模型婚姻调度参数的最大似然估计;世界生育率调查技术公告

关于咱们

  • 「Stata 连享会」 由中山大学连玉君老师团队创办,按期分享实证分析经验, 公众号:StataChina
  • 公众号推文同步发布于 CSDN简书知乎Stata专栏。可在百度中搜索关键词 「Stata连享会」查看往期推文。
  • 点击推文底部【阅读原文】能够查看推文中的连接并下载相关资料。
  • 欢迎赐稿: 欢迎赐稿。录用稿件达 三篇 以上,便可 免费 得到一期 Stata 现场培训资格。
  • E-mail: StataChina@163.com
  • 往期推文:计量专题 || 精品课程 || 简书推文 || 公众号合集

点击此处-查看完整推文列表


欢迎加入Stata连享会(公众号: StataChina)

原文连接:Princeton Stata 在线课程 (Princeton University - Stata Tutorial )