可以试试这个 Stata 17 官方推出的 pystata 包,亲测方便好用!
pystata
Jupyter 目前已经成为最流行的DS数据平台,比Stata的do直观(多了),比 RMarkdown 简洁(多了),优点多多。
对于经常同时使用Python+Stata的我来说,一直在思考着怎么把计量结果展现在 Jupyter 中。这样就可以,更好地利用Stata和Jupyter各自的长处。
这就是Python和Stata协同的经典问题了。注意,这里我们关注的是在 Jupyter中集成Stata ,至于Stata中调用Python,一直都没啥问题 -- 毕竟Python体量小,开源免费,怎么折腾都行。
而Jupyter 中融合 Stata,虽然实现的方案虽然多,比如 Jupyter中的 stata_kernel ,但效果都不是很好。
stata_kernel
直到最新的 17,Stata 官方终于出手了,并交出了一个令人还算比较满意的方案: pystata 包。
这里我们进行简单演示一下。想要顺利的在Jupyter中使用Stata,需要有2个关键前提:
第一步,在 Jupyter 中安装 pystata 包:
pip install stata_setup ## 为啥不叫 pystata?
第二步,在 Jupyter 中进行简单设置。这里我用的是Mac,并附上Windows版本的说明。
且注释默认写到了命令的下方,#号标记。
Mac:
import os os.chdir('/Applications/Stata/utilities') ## 指定 Stata 的安装文件夹下面的 utilities 文件夹 from pystata import config config.init('mp') ## 这两句就相当于告诉 Jupyter,去哪里找Stata
Windows(仅以下命令和 Mac 版有区别):
import stata_setup stata_setup.config("C:/Program Files/Stata17", "mp") ## 指定 Stata 安装所在的文件夹,告诉 Jupyter 去哪里找Stata
运行之后,看到以下界面就算是成功了。
第二步,在Jupyter中尝试运行Stata命令:
%%stata ##多行魔法命令 sysuse auto, clear reg price mpg rep78 trunk weight length
第四步,试试跑个回归,画个图:
第五步,和Python pandas 协同:
## 和 pandas 协同 ## 以下是纯 Python 代码 import pandas as pd import io import requests data = requests.get("https://www.stata.com/python/pystata/misc/nhanes2.csv").content nhanes2 = pd.read_csv(io.StringIO(data.decode("utf-8"))) nhanes2
%%stata -d nhanes2 -eret myeret ##上面 -d 定义了data;-eret 定义了 ereturn list的保存变量 logistic highbp c.age##c.weight ereturn list
用 Python 代码查看返回的数据框结果:
## Python语法进行返回 myeret ['e(b)'] [Out: ] array([[ 1.03035513e-01, 7.83537342e-02, -7.21492384e-04, -8.50485078e+00]]) %%stata quietly margins, at(age=(20(10)80)) marginsplot ## 画出逻辑回归的面积效应图
%%stata -doutd preddata ## 以上命令声明导出数据为 preddta,保存预测的结果(来自 predictions.dta) quietly margins, at(age=(20(5)80) weight=(40(5)180)) saving(predictions, replace) use predictions, clear list _at1 _at2 _margin in 1/5 rename _at1 age rename _at2 weight rename _margin pr_highbp
用Python命令查看预测结果:
在Python中将结果可视化,画图3D图形:
## 导入画图包 import matplotlib.pyplot as plt from mpl_toolkits import mplot3d import numpy as np %matplotlib inline %config InlineBackend.figure_format='retina' ## 实例化图片和坐标系 fig = plt.figure(1, figsize=(10, 8)) ax = plt.axes(projection='3d') ## 画出三角形的3D平面图 ax.plot_trisurf(preddata['age'], preddata['weight'], preddata['pr_highbp'],cmap=plt.cm.Spectral_r) ## 设置刻度和坐标轴标签 ax.set_xticks(np.arange(20, 90, step=10)) ax.set_yticks(np.arange(40, 200, step=40)) ax.set_zticks(np.arange( 0, 1.2, step=0.2)) ax.set_xlabel("Age (years)") ax.set_ylabel("Weight (kg)") ax.set_zlabel("Probability of Hypertension")