教育装备采购网
河南大学体育论坛580*60 第六届图书馆论坛580*60

在Stata中编写估计命令:编写插件

教育装备采购网 2018-11-27 17:25 围观1353次

这篇文章是本系列文章中的第一篇,阐述了如何用其他语言(如C,C 或Java)编写的代码插入到Stata中。这种技术被称为编写插件或为Stata编写动态链接库(DLL)。

可以为任何任务编写插件,包括数据管理、图形分析或统计估算。根据本系列的主题,我们先讨论估算命令的插件。

本文中,将讨论编写插件的利弊,并且讨论一个简单的程序,其计算将在以后的文章中用插件来替换。

什么是插件?

插件是一种或多种用另外一种语言编写的函数,可以从Stata中调用。从技术上讲,另一个程序在被调用时会链接到Stata,这个过程被称为包含其他程序的库到Stata的动态链接。 出于这个原因,插件也被称为DLL。

人们用其他语言编写插件来解决真正困难的问题。 可以为Stata编写插件的三个最常见的原因如下。

  1. 使用另一种语言编写的代码不适用于Stata或Mata。

  2. 在Stata / Mata中有一个编译系统,它不使用内置、快速、矢量化的函数,可以通过使用低级别语言(如C)进行一些计算来使其更快。

  3. 可以使用像C语言这样的低级别语言开发方法,然后将这些方法插入到Stata和其他统计软件包中。

插件的问题在于它们很难。用另一种语言编写和编译的插件要比仅仅使用Stata和Mata编写的插件困难得多。此外,错误的成本很高。插件可能很危险; 可能会损坏内存或做其他事情而导致Stata退出或以其他方式“崩溃”。

在C、C 或Fortran中维护插件是很难的。对于这些插件,您希望其为工作的每个操作系统都编译一个版本。 例如,您可能需要Windows、Mac和Linux或两个版本的编译库。此外,当操作系统获得新版本时,必须重新编译插件,并且可能需要为操作系统的旧版本和新版本分发版本。

Java插件更容易维护,但它们通常比用C、C 或Fortran编写的插件慢。可以分发单个Java库以便在所有支持的操作系统上运行。只需在Java环境中需要更改时重新编译即可。尽管存在这些困难,但在某些情况下,插件可以使Stata实现可用或可行。本系列文章演示了如何用不同语言编写和编译插件。

平均估计量

首先讨论在代码块1中给出的mymean10.ado,它实现了命令mymean10。mymean10计算用户指定的变量均值和估计量的方差 - 协方差(VCE)的样本平均估计量。 mymean10允许用户指定if限制和in范围,处理指定变量中的缺失值,但不允许任何选项。

mymean10.ado使用Mata进行计算。随后的文章中将用插件计算代替这些Mata计算。

请注意程序的结构。第6-7行解析用户输入的内容,第10行使用Mata工作函数mymean_work()进行计算,第12-18行存储并显示结果,第21-40行定义mymean_work()。

我们来看看这些部分。

在第6行,syntax创建本地宏varlist,其中包含用户指定的变量。syntax还创建了本地宏if 和in,分别包含任何限制或用户指定的范围。第7行中,marksample使用本地宏varlist,if和in来创建样本包含变量。该样本包含变量对于每个包括的观察值是1,对于每个排除的观察值是0。样本包含变量说明了用户指定的if限制条件或明确排除了观察结果的in范围,并且在varlist中的任何变量中都缺失的值,这些值隐含地排除了观察结果。marksample将此样本变量的名称放在本地宏touse中。

第8行,tempname将临时名称放入本地宏b,V和N中。这些名称未被使用,当mymean10完成时,将删除存储在这些名称中的对象。我们使用临时名称来避免覆盖用户创建的全局对象,如Stata矩阵和Stata标量。

第10行使用了一行调用Mata工作函数mymean_work()来计算点估计值,VCE和样本大小。mymean_work()将点估计的矢量放入Stata矩阵中,其名称存储在本地宏b中。mymean_work()将VCE放入Stata矩阵中,其名称存储在本地宏V中。并且mymean_work()将包含的观察数量放在Stata标量中,其名称存储在本地宏N中。

第12-14行将行和列名称放在存储点估计矢量和VCE的矩阵上。第15-17行将结果存储在e()中,第18行产生标准的Stata输出表。

第21-40行定义了mymean_work()。

第22-24行指定mywork_work()不向其调用者返回任何内容并接受五个字符串标量参数。第一个参数vlist包含用户指定变量的名称。第二个,touse,包含上面讨论的样本包含变量的名称。 最后三个包含将存储结果的名称。当mymean_work()完成时,本地宏bname包含存储点估计向量的Stata矩阵的名称,本地宏vname包含存储在VCE的Stata矩阵的名称,本地宏nname包含存储样本观察数量的Stata标量名称。

现在讨论mymean_work()。第26-28行声明函数中使用的变量。第30行将Stata中的样本包含变量为1的观察副本放入矩阵X。

第31-34行计算结果。31行将点估计值放入Mata向量b中。第32-34行计算VCE并将其存储在Mata矩阵V中。

在36行,st_matrix()将点估计值从b复制到Stata矩阵,其名称存储在bname中。在第37行中,st_matrix()将VCE从V复制到Stata矩阵,其名称存储在vname中。在第38行中,st_numscalar()将样本观察的数量从Mata标量n复制到Stata标量,名称存储在nname中。

当我们编写插件时会发生什么变化?

当我们编写插件时,所有通用结构和许多细节都保持不变。 我们称插件为计算而不是Mata函数有什么变化。

考虑用C语言编写代码来复制mymean_work()执行的计算。三件事可能被改变。首先,我们不会将数据从Stata复制到我们的插件中。 插件环境为我们提供了Stata中数据的视图。 其次,我们必须编写一个函数来实现在第31行执行的平均值。第三,我们必须编写一个函数来实现在第32-34行上执行的VCE计算。

为了便于介绍插件,我在Mata中进行了这些更改,如代码块2中的mymean11.ado所示。

第1-19行中的Stata部分保持不变,调用mymean_work()也是如此。

31和32行与mymean10.ado中的对应行不同。mymean10.ado中的第30行将用户指定变量的观察副本放入矩阵X中,其中样本包含变量为1。第32行mymean11在用户指定变量的所有观察中获得一个名为X的单独视图。 这些关于samp和X的视图更像是插件环境提供的数据访问功能。

在mymean11.ado的第34行中,我们使用MyAve()函数将样本平均值放入b中,将样本包含变量为1的观察数量放入n中。第42-59行的MyAve()代码类似于可写入的代码,例如C。最大的区别是第58行使用Mata运算符将b的每个元素除以标量。插件将包含执行这些操作的函数。

在第35行,我们使用MyV()函数将VCE放入V。 MyV()的代码在61-95行。这段代码也类似于用C编写的代码,同样需要注意的是94行将作为一个函数来实现。

myean11.ado中的第37-39行与mymean10.ado中36-38的对应行相同。

如果我在Mata中编写估算器,不会在myean11中使用该实现。只需将样本包含变量为1的观察值放入Mata视图中,就可以大大加快速度。MyAve()和MyV()函数说明了如何在数据循环中执行计算。插件将实现这些功能的版本。

点击进入北京天演融智软件有限公司展台查看更多 来源:教育装备采购网 作者:科学软件网 责任编辑:张肖 我要投稿
校体购终极页

相关阅读

版权与免责声明:

① 凡本网注明"来源:教育装备采购网"的所有作品,版权均属于教育装备采购网,未经本网授权不得转载、摘编或利用其它方式使用。已获本网授权的作品,应在授权范围内使用,并注明"来源:教育装备采购网"。违者本网将追究相关法律责任。

② 本网凡注明"来源:XXX(非本网)"的作品,均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,且不承担此类作品侵权行为的直接责任及连带责任。如其他媒体、网站或个人从本网下载使用,必须保留本网注明的"稿件来源",并自负版权等法律责任。

③ 如涉及作品内容、版权等问题,请在作品发表之日起两周内与本网联系,否则视为放弃相关权利。

九牧