查看原文
其他

Stata-Python交互:Stata17 新特性之PyStata的配置与应用

连享会 连享会 2023-10-24

👇 连享会 · 推文导航 | www.lianxh.cn

连享会 · 2022 暑期班

作者:杨晓军 (云南大学)
邮箱:yxj@mail.ynu.edu.cn

温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。或直接长按/扫描如下二维码,直达原文:


目录

  • 1. PyStata 的基本介绍

  • 2. 使用魔法指令实现交互

    • 2.1 魔法指令介绍

    • 2.2 魔法指令参数

  • 3. 使用 pystata.stata 实现交互

    • 3.1 单行和多行 Stata 指令运算

    • 3.2 pystata.stata 中的交互函数

    • 3.3 其他 pystata.stata 函数介绍

  • 4. Stata Function Interface (sfi ) 简介

    • 4.1 sfi 接口函数简介

    • 4.2 常用 sfi.Data 函数实示例

  • 5. 相关推文



每一门程序语言都有自己的特点,或者说有其擅长的领域,对于同一项工作的不同部分,如果我们能够合理搭配使用不同的程序语言或者软件,就可以极大提高工作效率。从计量统计分析的角度来说,我们可以将这一项工作分为数据处理与统计分析两个部分,在数据处理方面 Python 是一个不错的工具,而在统计分析方面使用 Stata 显然会更加方便。

因此,如果能够找到一个在二者之间进行交互的方法,将极大提高我们的数据分析效率。基于以上考虑,从 Stata16 以来,Stata 与 Python 的交互功能开始日益完善。如今,我们可以使用 Stata17 中的 PyStata 来便捷地完成这一项工作。

1. PyStata 的基本介绍

PyStata 是 Stata17 中引入的一个新概念,它涵盖了所有 Stata 和 Python 的交互方式。事实上从 Stata16 开始,我们就可以在 Stata 中调用 Python 代码,并通过 Stata 函数接口 (sfi 模块) 实现 Python 与 Stata 核心功能的交互。

在 Stata17 中,通过 Python 包  pystata,我们可以在基于或支持 IPython 内核的环境中 (例如:Jupyter Notebook、Jupyter Lab、Spyder、PyCharm、VScode 等) 更加方便地调用 Stata 和 Mata。

在正式使用之前,我们需安装以下软件:

  • 正版 Stata17 软件 (必须具备有效的许可证,否则无法调用);
  • 拥有基于或支持 IPython 内核的 Python 环境 (建议使用 Jupyter Lab 或 VScode)。

在此基础上,我们还需要完成如下配置:

  • step 1:在 Python 环境中安装 stata_setup 模块;
# 安装stata_setup模块
pip install --upgrade --user stata_setup
  • step 2:在 Python 环境中导入 stata_setup 模块,并关联 Stata17;
# 导入stata_setup模块
import stata_setup
# 通过stata_setup.config关联 Stata17  
stata_setup.config(r"D:\Program\Stata17""mp"# 填入 Stata17 的本地路径及版本类型
from pystata import stata

2. 使用魔法指令实现交互

2.1 魔法指令介绍

cell magic 基本指令:在 cell 的第一行输入魔法指令 %%stata,接着在该 cell 中输入对应的 Stata 命令。

%%stata
sysuse auto, clear
list

line magic 基本指令:如果你只是想在某一行运行一个单独的 Stata 语句,而在其他行运行 Python 语句,那么就可以使用 line magic 指令,即只需在某一行输入魔法指令 %stata,后面跟上想要运行的 Stata 语句即可。

%stata sysuse auto, clear

2.2 魔法指令参数

2.2.1 Python 调用 Stata 数据

%%stata magic 命令提供了几个参数,可用于控制 Stata 命令的执行以及在 Stata 和 Python 之间传递数据。例如,我们可以使用 -eret-ret-sret 参数,将 Stata 运行结果中的 e()r()s() 结果传递到 Python 变量中。需要注意的是,此命令默认保存和传递的是 Stata 中最后一条命令的运行结果。

%%stata -eret myeret -ret myret -sret mysret
sysuse auto, clear
reg mpg price i.foreign
ds
. sysuse auto, clear
. reg mpg price i.foreign

      Source |       SS           df       MS      Number of obs   =        74
-------------+----------------------------------   F(271)        =     23.01
       Model |  960.866305         2  480.433152   Prob > F        =    0.0000
    Residual |  1482.59315        71  20.8815937   R-squared       =    0.3932
-------------+----------------------------------   Adj R-squared   =    0.3761
       Total |  2443.45946        73  33.4720474   Root MSE        =    4.5696
------------------------------------------------------------------------------
         mpg | Coefficient  Std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
       price |     -0.001      0.000    -5.28   0.000       -0.001      -0.001
             |
     foreign |
    Foreign  |      5.245      1.164     4.51   0.000        2.925       7.565
       _cons |     25.651      1.272    20.17   0.000       23.115      28.186
------------------------------------------------------------------------------

. ds
make          rep78         weight        displacement
price         headroom      length        gear_ratio
mpg           trunk         turn          foreign

以上命令语句是指,将 Stata 语句中的 e()r()s() 传递到 Python 变量 myeretmyretmysret 中。我们可以输出一下这三个变量,看看获取到了哪些信息。

myeret
# myret
# mysret
{'e(N)'74.0,
 'e(df_m)'2.0,
 'e(df_r)'71.0,
 'e(F)'23.007494485746342,
 'e(r2)'0.39324012569622946,
 'e(rmse)'4.569638248831391,
 'e(mss)'960.8663049714787,
 'e(rss)'1482.5931544879809,
 'e(r2_a)'0.3761482982510528,
 'e(ll)'-215.90831771275379,
 'e(ll_0)'-234.39433764823468,
 'e(rank)'3.0,
 'e(cmdline)''regress mpg price i.foreign',
 'e(title)''Linear regression',
 'e(marginsprop)''minus',
 'e(marginsok)''XB default',
 'e(vce)''ols',
 'e(depvar)''mpg',
 'e(cmd)''regress',
 'e(properties)''b V',
 'e(predict)''regres_p',
 'e(model)''ols',
 'e(estat_cmd)''regress_estat',
 'e(b)': array([[-9.59034169e-04,  0.00000000e+00,  5.24527100e+00,
          2.56505843e+01]]),
 'e(V)': array([[ 3.29592449e-08,  0.00000000e+00-1.02918123e-05,
         -2.00142479e-04],
        [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
         -0.00000000e+00],
        [-1.02918123e-05,  0.00000000e+00,  1.35394617e+00,
         -3.39072871e-01],
        [-2.00142479e-04-0.00000000e+00-3.39072871e-01,
          1.61691892e+00]])}

该指令默认获取和传递的数据以字典列表的形式储存,我们可以通过索引直接调用其中的任意一项数据。

# 调用从 Stata 语句中获取到的运行结果
e_b = myeret['e(b)']
e_b
array([[-9.59034169e-04,  0.00000000e+00,  5.24527100e+00,
         2.56505843e+01]])

应用实例:获取当前 Stata 所使用数据集中的所有变量名,然后通过 stata.pdataframe_from_data() 函数将 Stata 数据集输出到 Python 中。

%%stata -eret myeret -ret myret -sret mysret
ds
make        rep78         weight        displacement
price         headroom      length        gear_ratio
mpg           trunk         turn          foreign
# 把 Stata 数据集全部输出到 pd.df
var_list = myret['r(varlist)']
df_stata=stata.pdataframe_from_data(var_list)
df_stata

2.2.2 Stata 调用 Python 数据

我们也可以通过指定 %%stata magic 指令的 -d 参数,将 NumPy 数组或 pandas DataFrame 加载到 Stata 中,使其成为当前的工作数据集。需要注意的是,此数据集会替换当前 Stata 内存中的数据集,并在下一个 cell 中仍然可用。

应用实例:导入一个 df 数据集,并使用 Python 中的 df 数据集作为当前的 Stata 数据集。

# 导入一个外部数据到 Python 中
from sklearn import datasets
bos = datasets.load_boston()
boston = pd.DataFrame(bos.data)
boston.columns = bos.feature_names
boston['MEDV'] = bos.target
boston.head()
%%stata -d boston
describe
Contains data
 Observations:           506                  
    Variables:            14                  
-------------------------------------------------------------------------------
Variable      Storage   Display    Value
    name         type    format    label      Variable label
-------------------------------------------------------------------------------
CRIM            double  %10.0g                
ZN              double  %10.0g                
INDUS           double  %10.0g                
CHAS            double  %10.0g                
NOX             double  %10.0g                
RM              double  %10.0g                
AGE             double  %10.0g                
DIS             double  %10.0g                
RAD             double  %10.0g                
TAX             double  %10.0g                
PTRATIO         double  %10.0g                
B               double  %10.0g                
LSTAT           double  %10.0g                
MEDV            double  %10.0g                
-------------------------------------------------------------------------------
Sorted by: 
     Note: Dataset has changed since last saved.

我们还可以通过指定 -f 参数一次将多个 NumPy 或 pandas DataFrame 加载到 Stata 中,这会使得每个数组或 DataFrame 加载到 Stata 的多个单独 Frame 中。例如:

CHAS0 = boston[boston['CHAS']==0]
CHAS1 = boston[boston['CHAS']==1]
CHAS0
CHAS0
%%stata -f CHAS0,CHAS1
frames dir

3. 使用 pystata.stata 实现交互

3.1 单行和多行 Stata 指令运算

stata.run('sysuse auto, clear')
stata.run('''
summarize
reg mpg price i.foreign
ereturn list
'''
)

3.2 pystata.stata 中的交互函数

可以使用 get_return()get_ereturn()get_sreturn() 函数将 Stata 的 r()e()s() 结果存储为 Python 中的字典。例如:

stata.run('sysuse auto, clear')

myret = stata.get_return()
myeret = stata.get_ereturn()
mysret = stata.get_sreturn()

df_myeret = pd.DataFrame.from_dict(myeret,orient='index')
df_myret = pd.DataFrame.from_dict(myret,orient='index')
df_mysret = pd.DataFrame.from_dict(mysret,orient='index')
df_myeret
df_myret
df_mysret

可以使用 stata.pdataframe_from_data() 将 Stata 数据集作为 Numpy 数组或 pandas DataFrames 传递到 Python 中。例如:

stata.run('sysuse auto, clear')

# 默认传递当前 stata 所使用的整个数据集
myauto = stata.pdataframe_from_data()
myauto.head()

# 指定参数选择当前 stata 所使用数据集的子集
# 例如,我们可将变量 mpg 和 price 的前 10 个观测值存储到 pandas DataFrame 中
myauto1 = stata.pdataframe_from_data('mpg price', range(10))
myauto1

可以使用 stata.pdataframe_to_data() 将数据从 Python 读取到 Stata 中,使其成为当前数据集或将其加载到 Stata 中的特定 Frame 中。例如,将上面的 pd.df 数据集 myauto 加载到 Stata 中,使其成为当前数据集,并列出前三个观测值。

stata.pdataframe_to_data(myauto, force=True# force=True 指的是在加载 Frame 之前清空 Stata 的当前内存
stata.run('list in 1/3')

3.3 其他 pystata.stata 函数介绍

具体函数功能
run(cmd[, quietly, echo, inline])运行一行或一组 Stata 命令
nparray_to_data(arr[, prefix, force])将 Numpy数组加载到 Stata 的内存中,使其成为当前数据集
pdataframe_to_data(df[, force])将 pandas DataFrame 加载到 Stata 的内存中,使其成为当前数据集
nparray_from_data([var, obs, selectvar, …])将当前 Stata 数据集中的值导出到 Numpy 数组中
pdataframe_from_data([var, obs, selectvar, …])将当前 Stata 数据集中的值导出到 pandas DataFrame
nparray_to_frame(arr, stfr[, prefix, force])将 Numpy 数组加载到 Stata 中的指定 Frame 中
pdataframe_to_frame(df, stfr[, force])将pandas DataFrame加载到 Stata 中的指定Frame中
nparray_from_frame(stfr[, var, obs, …])将值从 Stata Frame 中导出到 Numpy 数组中
pdataframe_from_frame(stfr[, var, obs, …])将值从Stata Frame 中导出到 pandas DataFrame
get_return()检索当前的 r()  结果并将其存储在 Python 字典中
get_ereturn()检索当前的 e()结果并将其存储在 Python 字典中
get_sreturn()检索当前的 s() 结果并将其存储在 Python 字典中

4. Stata Function Interface (sfi ) 简介

4.1 sfi 接口函数简介

sfi 模块允许用户将 Python 的功能与 Stata 的核心功能进行交互。该模块可以交互使用,也可以在 do 文件和 ado 文件中使用。在模块中,定义了 Class 用来访问 Stata 特征、当前数据集、Frame、日期和时间、宏、标量、矩阵、值标签、全局 Mata 矩阵、缺失值等。

Class Summary

  • Characteristic (sfi.Characteristic)
  • Data (sfi.Data)
  • Datetime (sfi.Datetime)
  • Frame (sfi.Frame)
  • Macro (sfi.Macro)
  • Mata (sfi.Mata)
  • Matrix (sfi.Matrix)
  • Missing (sfi.Missing)
  • Platform (sfi.Platform)
  • Preference (sfi.Preference)
  • Scalar (sfi.Scalar)
  • SFIToolkit (sfi.SFIToolkit)
  • StrLConnector (sfi.StrLConnector)
  • ValueLabel (sfi.ValueLabel)

Exception Summary

  • FrameError (sfi.FrameError)
  • SFIError (sfi.SFIError)

4.2 常用 sfi.Data 函数实示例

%stata sysuse auto, clear

price = Data.get(var='price')
price

price1 = pd.Series(price)
price1

Data.renameVar('mpg''MileagePerGallon')
%stata list

Data.dropVar("make")
%stata list

Data.keepVar("MileagePerGallon")

%stata list

5. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh 交互, m
安装最新版 lianxh 命令:
ssc install lianxh, replace

  • 专题:计量专题
    • 主成分分析-交互固定效应基础:协方差矩阵的几何意义
  • 专题:Stata教程
    • Stata-Python交互-9:将python数据导入Stata
    • Stata-Python交互-8:将Stata数据导入Python
    • Stata-Python交互-7:在Stata中实现机器学习-支持向量机
    • Stata-Python交互-6:调用APIs和JSON数据
    • Stata-Python交互-5:边际效应三维立体图示
    • Stata-Python交互-4:如何调用Python宏包
    • Stata-Python交互-3:如何安装Python宏包
    • Stata-Python交互-2:在Stata中调用Python的三种方式
    • Stata-Python交互-1:二者配合的基本设定
  • 专题:Stata命令
    • Stata-Mata系列 (二):Mata与Stata的交互
  • 专题:面板数据
    • regife:面板交互固定效应模型-Interactive Fixed Effect
  • 专题:交乘项-调节
    • med4way:中介效应和交互效应分析
    • interactplot:图示交乘项-交互项-调节效应
    • Stata:图示交互效应-调节效应
  • 专题:Probit-Logit
    • Logit-Probit:非线性模型中交互项的边际效应解读
  • 专题:Python-R-Matlab
    • Stata交互:Python-与-Stata-对比

课程推荐:因果推断实用计量方法
主讲老师:丘嘉平教授
🍓 课程主页https://gitee.com/lianxh/YGqjp

New! Stata 搜索神器:lianxhsongbl  GIF 动图介绍
搜: 推文、数据分享、期刊论文、重现代码 ……
👉 安装:
. ssc install lianxh
. ssc install songbl
👉  使用:
. lianxh DID 倍分法
. songbl all

🍏 关于我们

  • 连享会 ( www.lianxh.cn,推文列表) 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 直通车: 👉【百度一下: 连享会】即可直达连享会主页。亦可进一步添加 「知乎」,「b 站」,「面板数据」,「公开课」 等关键词细化搜索。


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存