Стартирайте Stata do файл от Python

Имам скрипт Python, който почиства и извършва основни статистически изчисления върху набор от данни с голям панел (2,000,000+ observations).

Намирам, че някои от тези задачи са по-подходящи за Stata, и написах do файл с необходимите команди. По този начин искам да стартирам .do файл в моя Python код. Как да извикам файл .do от Python?


person svenkatesh    schedule 21.01.2014    source източник
comment
Как обикновено стартирате такива файлове? Използвате ли интерфейс на командния ред? Ако е така, какво въвеждате?   -  person wnnmaw    schedule 21.01.2014
comment
Обикновено изпълнявам do файлове, като отварям stata и написвам do ‹filename›.do в командния ред. Имам обаче много do файлове за обработка и би било по-лесно, ако мога да ги консолидирам и стартирам от Python файла.   -  person svenkatesh    schedule 21.01.2014
comment
На каква платформа работите?   -  person wnnmaw    schedule 21.01.2014
comment
Разгледайте коментарите на Андрю под моя въпрос stackoverflow.com/questions/18532440/ - може би от някаква помощ.   -  person radek    schedule 22.01.2014
comment
@ wnnmaw Използвам Windows 7 на работа и Mac OS X 10.8 у дома. @radek Благодаря! Това беше много полезен въпрос за разглеждане.   -  person svenkatesh    schedule 22.01.2014


Отговори (3)


Мисля, че @user229552 сочи в правилната посока. Може да се използва модулът subprocess на Python. По-долу има пример, който работи за мен с Linux OS.

Да предположим, че имате файл на Python, наречен pydo.py със следното:

import subprocess

## Do some processing in Python

## Set do-file information
dofile = "/home/roberto/Desktop/pyexample3.do"
cmd = ["stata", "do", dofile, "mpg", "weight", "foreign"]

## Run do-file
subprocess.call(cmd) 

и Stata do-файл с име pyexample3.do, със следното:

clear all
set more off

local y `1'
local x1 `2'
local x2 `3'

display `"first parameter: `y'"'
display `"second parameter: `x1'"'
display `"third parameter: `x2'"'

sysuse auto
regress `y' `x1' `x2'

exit, STATA clear

След това изпълнението на pydo.py в прозорец на терминал работи според очакванията.

Можете също така да дефинирате функция на Python и да я използвате:

## Define a Python function to launch a do-file 
def dostata(dofile, *params):
    ## Launch a do-file, given the fullpath to the do-file
    ## and a list of parameters.
    import subprocess    
    cmd = ["stata", "do", dofile]
    for param in params:
        cmd.append(param)
    return subprocess.call(cmd) 

## Do some processing in Python

## Run a do-file
dostata("/home/roberto/Desktop/pyexample3.do", "mpg", "weight", "foreign")

Пълното обаждане от терминал с резултати:

roberto@roberto-mint ~/Desktop
$ python pydo.py

  ___  ____  ____  ____  ____ (R)
 /__    /   ____/   /   ____/
___/   /   /___/   /   /___/   12.1   Copyright 1985-2011 StataCorp LP
  Statistics/Data Analysis            StataCorp
                                      4905 Lakeway Drive
                                      College Station, Texas 77845 USA
                                      800-STATA-PC        http://www.stata.com
                                      979-696-4600        [email protected]
                                      979-696-4601 (fax)


Notes:
      1.  Command line editing enabled

. do /home/roberto/Desktop/pyexample3.do mpg weight foreign 

. clear all

. set more off

. 
. local y `1'

. local x1 `2'

. local x2 `3'

. 
. display `"first parameter: `y'"'
first parameter: mpg

. display `"second parameter: `x1'"'
second parameter: weight

. display `"third parameter: `x2'"'
third parameter: foreign

. 
. sysuse auto
(1978 Automobile Data)

. regress `y' `x1' `x2'

      Source |       SS       df       MS              Number of obs =      74
-------------+------------------------------           F(  2,    71) =   69.75
       Model |   1619.2877     2  809.643849           Prob > F      =  0.0000
    Residual |  824.171761    71   11.608053           R-squared     =  0.6627
-------------+------------------------------           Adj R-squared =  0.6532
       Total |  2443.45946    73  33.4720474           Root MSE      =  3.4071

------------------------------------------------------------------------------
         mpg |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
      weight |  -.0065879   .0006371   -10.34   0.000    -.0078583   -.0053175
     foreign |  -1.650029   1.075994    -1.53   0.130      -3.7955    .4954422
       _cons |    41.6797   2.165547    19.25   0.000     37.36172    45.99768
------------------------------------------------------------------------------

. 
. exit, STATA clear

Източници:

http://www.reddmetrics.com/2011/07/15/calling-stata-from-python.html

http://docs.python.org/2/library/subprocess.html

http://www.stata.com/support/faqs/unix/batch-mode/

Различен маршрут за използване на Python и Stata заедно може да бъде намерен на

http://ideas.repec.org/c/boc/bocode/s457688.html

http://www.stata.com/statalist/archive/2013-08/msg01304.html

person Roberto Ferrer    schedule 22.01.2014
comment
Благодаря, това беше много полезно. Получавам обаче друга грешка, когато прилагам това решение в Windows. Получавам следното съобщение: WindowsError: [Error 2] The system cannot find the file specified - person svenkatesh; 22.01.2014
comment
А, разбрах какво правя погрешно - първо, тъй като работя от Windows XP, трябва да подавам аргумента shell = 'true' в метода subprocess.call(). Второ, моят код на Python не беше в същата работна директория, както е моето копие на Stata. След като поправих тези два проблема, всичко вървеше гладко. Благодаря ви много за помощта. - person svenkatesh; 23.01.2014

Този отговор разширява отговора на @Roberto Ferrer, решавайки няколко проблема, с които се сблъсках.

Състояние в системния път

За да може stata да изпълнява код, той трябва да бъде правилно настроен в системния път (поне в Windows). Поне за мен това не беше автоматично настроено при инсталиране на Stata и открих, че най-простата корекция е да се постави пълният път (който за мен беше "C:\Program Files (x86)\Stata12\Stata-64), т.е.:

cmd = ["C:\Program Files (x86)\Stata12\Stata-64","do", dofile]`

Как тихо да стартирате кода във фонов режим

Възможно е да накарате кода да работи тихо във фонов режим (т.е. да не отваря Stata всеки път), като добавите командата /e т.е.

cmd = ["C:\Program Files (x86)\Stata12\Stata-64,"/e","do", dofile]

Място за съхранение на регистрационни файлове

И накрая, ако работите тихо във фонов режим, Stata ще иска да запази лог файлове. Ще направи това в работната директория на cmd. Това трябва да варира в зависимост от това откъде се изпълнява кодът, но за мен, тъй като изпълнявах Python от Notepad++, той искаше да запише регистрационните файлове в C:\Program Files (x86)\Notepad++, до които Stata нямаше достъп за запис. Това може да се промени чрез посочване на работната директория, когато се извиква подпроцесът.

Тези модификации на кода на Roberto Ferrer водят до:

def dostata(dofile, *params):
    cmd = ["C:\Program Files (x86)\Stata12\Stata-64","/e","do", dofile]         
    for param in params:
        cmd.append(param)
    return (subprocess.call(cmd, cwd=r'C:\location_to_save_log_files'))
person kyrenia    schedule 27.02.2017
comment
Прекарах толкова време в опити да разбера, че "stata" няма да работи и вместо това трябваше да дефинирам пълния път до изпълнимия файл на Stata, както направихте вие. - person ALollz; 29.10.2018

Ако изпълнявате това в настройка на командния ред, трябва да можете да извикате Stata от командния ред от python (не знам как да извикам команда на shell от Python, но не би трябвало да е твърде трудно , вижте тук: Извикване на външна команда в Python). За да стартирате Stata от командния ред (известен още като пакетен режим), вижте тук: http://www.stata.com/support/faqs/unix/batch-mode/

person maxliving    schedule 21.01.2014