stata

Simple wrappers for pystata/sfi functionality

sfi is Stata’s python API, originally intended for interacting with Stata from python within Stata. As such, it can only be imported with Stata running. pystata.stata.run enables running Stata code from python.

For one thing, using wrappers removes the need to constantly import pystata and/or sfi within functions elsewhere to avoid running afoul of CI tests in an environment without Stata installed.

Simple wrappers


source

get_local

 get_local (name)

https://www.stata.com/python/api17/Macro.html#sfi.Macro.getLocal


source

set_local

 set_local (name, value)

https://www.stata.com/python/api17/Macro.html#sfi.Macro.setLocal


source

get_global

 get_global (name)

https://www.stata.com/python/api17/Macro.html#sfi.Macro.getGlobal


source

get_scalar

 get_scalar (name)

https://www.stata.com/python/api17/Scalar.html?highlight=scalar#sfi.Scalar.getValue


source

stata_formatted

 stata_formatted (value, s_format)

https://www.stata.com/python/api17/SFIToolkit.html#sfi.SFIToolkit.formatValue


source

variable_names

 variable_names ()

variable_names uses ‘getVarCount’ and ‘getVarName’: https://www.stata.com/python/api17/Data.html

sfi.SFIToolkit.stata("quietly gen var1 = 1")
variable_names()
['var1']

source

drop_var

 drop_var (name)

https://www.stata.com/python/api17/Data.html#sfi.Data.dropVar

drop_var('var1')
variable_names()
[]

source

obs_count

 obs_count ()

Count the number of observations

https://www.stata.com/python/api17/Data.html#sfi.Data.getObsTotal

obs_count()
0

source

pwd

 pwd ()

https://www.stata.com/python/api17/SFIToolkit.html#sfi.SFIToolkit.getWorkingDir

pwd()[-12:]
'\\nbstata\\nbs'

source

macro_expand

 macro_expand (s)

https://www.stata.com/python/api17/SFIToolkit.html#sfi.SFIToolkit.macroExpand

Running arbitrary Stata code


source

run_direct

 run_direct (cmds, quietly=False, echo=False, inline=True)

run_direct wraps the most flexible utility Stata provides to run Stata commands: pystata.stata.run

run_direct("""\
disp 1
disp 2""", echo=True)

. disp 1
1

. disp 2
2

. 

source

run_single

 run_single (cmd, echo=False)

run_single uses an sfi function for running a single command that is notably faster than pystata.stata.run but is less versatile and appears less resilient to errors: https://www.stata.com/python/api17/SFIToolkit.html#sfi.SFIToolkit.stata

import sfi, pystata
with Timer():
    sfi.SFIToolkit.stata("disp 0")
with Timer():
    pystata.stata.run("disp 0")
0
Elapsed time: 0.0001 seconds
0
Elapsed time: 0.0585 seconds

For example, it cannot display graphs, silently quashing them instead:

sfi.SFIToolkit.stata("sysuse lifeexp, clear")
sfi.SFIToolkit.stata("scatter gnppc lexp")
(Life expectancy, 1998)
run_direct("scatter gnppc lexp", echo=True)
. scatter gnppc lexp

Even worse, a subsequent run of sfi.SFIToolkit.stata can be affected by a previous error:

try:
    sfi.SFIToolkit.stata("disp 1 \n disp 2")
except Exception as e:
    print(repr(e))
SyntaxError('failed to execute the specified Stata command')
sfi.SFIToolkit.stata('disp "1b"')
1
 invalid name
1b

But an intervening blank run seems to set things right:

try:
    sfi.SFIToolkit.stata("disp 1 \n disp 2")
except Exception:
    sfi.SFIToolkit.stata("")
1
 invalid name
sfi.SFIToolkit.stata('disp "1b"')
1b

So run_single should only be used with care. For when it is used, in case of error-causing input code, it executes sfi.SFIToolkit.stata again (with stdout redirected) to prevent the effects of the error from persisting.

with ExceptionExpected(ex=SyntaxError):
    run_single("disp 1 \n disp 2")
run_single('disp "1b"')
1b