Back to site
Since 2004, our University project has become the Internet's most widespread web hosting directory. Here we like to talk a lot about web development, networking and server security. It is, after all, our expertise. To make things better we've launched this science section with the free access to educational resources and important scientific material translated to different languages.

Data Princeton - Programiranje u Stata-i

Programiranje u Stata-i

Оvа sekcija je nežan uvod u programiranje u Stata-i. Mi razgovaramo ovde o macros i loops, , i pokazaćemo kako da napišete svoje (jednostavne) programe. Ovo je velika tema i jedino što mi možemo da se nadamo ovde, jeste da damo nekoliko saveta, koji će nadamo se upaliti iskru vašeg interesovanja za dalje istraživanje. Međutim, materijal obrađen ovde će vam pomoći da koristite Stata-u efikasnije.

Stata 9 je uveo novi i moćni programski jezik koji se zove Mata. Ovo proširuje alate programera i van makro zamenskih alata o kojima se raspravlja ovde, ali Mata je tema koja zaslužuje poseban tretman. Vaši napori ovde neće biti izgubljeni, međutim zato što je Mata komplementarna, i nije potpuna zamena za klasično Stata programiranje.

Da biste saznali više o programiranju Stata-e treba da pročitate poglavlje 18 u Vodiču za korisnike a zatim da pregledate Programming poglavlje i/ili online pomoć ako je potrebno. Redovna kolumna Nick Cox-a u Stata Journal su divan resurs za učenje o Stata-i. Ostali izvori su navedeni u Članu 1 ovog tutorijala.

4.1 Маkroi

Маkro je jednostavno ime povezano sa određenim tekstom. Makroi mogu biti lokalni ili globalni u obimu programa.

4.1.1 Čuvanje teksta u lokalnim Makroima

Lokalni makroi imaju imena do 31 znak, a poznati su samo u trenutnom kontekstu (konzola, fajl, ili program).

Vi definišete lokalni makro koristeći local name [=] text , a procenjujete ga koristeći `name'. (Оbratite pažnju na korišćenje backtick ili levog navoda).

Prva varijanta, bez znaka jednakosti, se koristi za skladištenje proizvoljnog teksta i do ~ 64к znakova (do milion u State SE). Tekst je često zatvoren u navodnicima, ali to ne mora da bude.

Primer: Kontrola varijabli u regresji

Morate da pokrenete gomilu regresivnih jednačina koje uključuju standardni set kontrole varijabli, recimo age, agesq, education, i income. Vi možete, naravno da upišete njihova imena u svaku jednačinu, ili biste mogli da cut i paste imena, ali ove alternative su dosadne i sklone greškama. Pametan način je da se definiše makro

local controls age agesq education income

Tada kucate komande kao što su

regress outcome treatment `controls'

u ovom slučaju potpuno jednake kucanju regress outcome treatment age agesq education income.

Ako postoji samo jedna regresija za pokretanje, niste sačuvali ništa, ali ako morate da pokrenete nekoliko modela sa različitim ishodima ili tretmana, makro štedi rad i obezbeđuje doslednost.

Ovaj pristup ima tu prednost, da ako kasnije vaš savetnik insistira da ste trebali da koristite log-income pre nego income kontrolu, sve što treba je da promenite makro definiciju na vrhu datoteke, kažete mu da pročita logincome umesto income i svi ostali modeli će se pokrenuti sa pravilno prijavljenim prihodima (pod pretpostavkom da ove varijable postoje).

Upozorenje: Procenjivanje makroa koji ne postoji nije greška, samo vraćanje prazne linije. Zato budite oprezni da pravilno ispišete makro imena. Ako ste ukucali regress outcome treatment `contrls', Stata će pročitati regress outcome treatment, jer makro contrls ne postoji. Isto će se desiti ako otkucate `control' jer makro imena ne mogu da se skraćuju kao što imena varijabli može. U svakom slučaju, regresija će biti pokrenuta bez ikakvih kontrola. Ali vi uvek proveravate vaš output, zar ne?

Primer: Upravljanje veštačkih varijabli

Pretpostavimo da radite sa demografskim istraživanjima u kojima je starost grupisana po petogodišnjim grupama i završava se predstavljajući sedam lutaka, recimo age15to19 do age45to49, od kojih će šest da se koristi u vašoj regresiji. Definišite makro

local age "age20to24 age25to29 age30to34 age35to39 age40to44 age45to49"

i onda u svojim regresivnim modelima koristite nešto kao

regress ceb `age' urban

što je ne samo kraće i čitljivije, već i bliže onome što nameravate, a to je da povuče ceb na ‘age’, koja se definiše gomilom lutaka. Ovo takođe olakšava da promenite zastupljenost starosti, ako kasnije odlučite da koristite linearne i kvadratne usluge, umesto šest lutaka sve što treba da uradite je da definišete local age "age agesq" i ponovo pokrenite svoje modele. Imajte na umu da je prva pojava age ovde ime makroa, a druga je ime varijable. Koristio sam navode da bi bilo jasnije. Stata nikad nije zbunjujuća.

Napomena o Ugnežđenom makrou: Ako makro sadrži makro procene, one se rešavaju u vreme kada je makro stvoren, a ne kada se vrednuje. Na primer, ako ste definisali local controls `age' income education. Stata vidi da ona obuhvata age i zamenjuje za tekuću vrednost age. Promena sadržaja makro age kasnije ne menja sadržaj makroa controls.

Postoji, međutim način da se postigne taj određeni efekat. Trik je da izbegnete makro karakter procene kada definišete makro, kucanjem local controls \`age' income education. Sada Stata ne procenjuje makro (ali jede karakter za bekstvo), tako da sadržaj controls postaje `age' income education. Kada se procenjuje controls makro, Stata vidi da on obuhvata makro age i zamenjuje aktuelne sadržaje.

U nekim slučajevima, zamena se javlja kad je makro definisan, u drugim kada je procenjen.

4.1.2 Čuvanje rezultata u lokalnim makroima

Druga vrsta makro definicije local name = text, sa znakom jednakosti se koristi za čuvanje rezultata. To govori Stata-i da tretira tekst na desnoj strani kao izraz, proceni ga, i sačuva tekst o rezultatima pod datim imenom.

Pretpostavimo da ste upravo izvršili regresiju i želite da sačuvate rezultat za poređenje sa kasnijom regresijom. Vi znate da regress čuva R-kvadratne u e(r2), i onda mislite local rsq e(r2) će učiniti trik, ali to nije slučaj.

Vaš makro je sačuvao e(r2), i kao što možete videti po kucanju display "`rsq'". Ono što je vama potrebno da sačuvate je vrednost. Rešenje je da se upiše local rsq = e(r2), sa znakom jednakosti. To izaziva Stata-u da proceni izraz i sačuva rezultate.

Da biste videli razliku probajte ovo

sysuse auto, clear
regress mpg weight
local rsqf e(r2)
local rsqv = e(r2)
di `rsqf'		// this has the current R-squared
di `rsqv'		// as does this
regress mpg weight foreign
di `rsqf'		// the formula has the new R-squared
di `rsqv'		// this guy has the old one

Još jedan način da pokrenete procenu je da priložite e(r2) u navodima kada definišete lokalni makro. Ovo se zove makro izraz, a takođe je korisno kada želite da prikažete rezultate. To nam omogućava da kucamo display "R-squared=`rsqv'" umesto display "R-squared=" `rsq'. (Šta mislite da će se desiti ako otkucate display "``rsqf''"?)

Alternativni način za čuvanje rezultata za kasniju upotrebu je da koristite skalare (kucajte help scalars da biste naučili više). Ovo ima prednost kada Stata skladišti rezultate u binarnom obliku, bez gubitka preciznosti. Makro skladišti prezentaciju teksta koja je dobra samo za oko 8 cifara. Loša strana je da su skalari u globalnom imenskom prostoru, tako da postoji potencijal za sukob imena, naročito u programima (osim ako koristite privremene nazive, o kojima ćemo raspravljati kasnije).

Možete da koristite znak jednakosti kada skladištite tekst, ali dozvolite mi da vam kažem zašto to nije uvek dobra ideja. Mogli bismo reći local controls = "age agesq education income" i ovo bi radilo. Obratite pažnju na upotrebu navodnika kako bi se osigurali da je desna strana izraz, u ovom slučaju žica. I tu leži problem: žice su ograničene na 244 znakova (obično je bilo 80 u Intercooled Stata pre 9.1 Verzije), dok makro tekst može biti mnogo veći kao što je gore navedeno (kucajte help limits da biste se podsetili).

4.1.3 Mapiranje globalnih makroa na tastaturi

Globalni makroi imaju imena do 32 znaka, a kao što ime ukazuje, imaju globalni obim.

Vi definišete globalni makro koristeći global name [=] text i procenjujete ga korišćenjem $name. (Možda ćete morati da koristite ${name} da biste pojasnili gde se ime završava).

Predlažem da izbegnete globalne makroe zbog potencijala za sukob imena. Korisna aplikacija, međutim, je da mapirate ključne funkcije na tastaturi. Ako radite na zajedničkom mrežnom folderu sa dugim imenom pokušajte nešto slično ovom

global F5 \\server\shared\research\project\subproject\ 

Оnda kada kliknete F5 Stata će zameniti puno ime. A vaši Uradi fajlovi mogu koristiti komande kao što je do ${F5}dofile. (Korišćenje velike zagrade ukazuje na to da se makro zove F5, ne F5dofile.)

Logično vi ne želite da kucate ovaj makro svaki put kada koristite State. Rešenje? Unesite ga u svoj profile.do fajl, skup komandi koje se izvršavaju svaki put kada pokrenete Stata. Vaš profil je najbolje čuvati u start up direktorijumu Stata-e, obično C:\data. Ukucajte help profilew da biste saznali više.

4.1.4 Više o makroima

Маkroi takođe mogu da se koriste za dobijanje i skladištenje informacija o sistemu ili varijabli u vašem sistemu podataka koristeći produžene makro funkcije. Na primer, možete da preuzmete i vrednost oznake varijabli, što je funkcija koja može da dođe pri ruci u programiranju.

Tu se nalaze komande za upravljanje kolekcije makroa, uključujući macro list i macro drop. Ukucajte help macro da biste saznali više.

4.2 Looping (petlje)

Petlje se koriste za zadatke koji se ponavljaju. Stata ima komande koje dozvoljavaju petlje preko nizova brojeva i razne vrste lista, uključujući liste varijabli.

Pre nego što počnemo, imajte na umu da Stata mnogo petlji obavlja sama. Ako želite da izračunate dnevnik prihoda, možete da uradite to u Stata-i sa jedne linije:

gen logincome = log(income)

Ova petlja implicitno obuhvata sva zapažanja, izračunavajući evidenciju svakog prihoda, u ono što se ponekad zove vektorizovana operacija. Možete i sami da kodirate petlju, ali ne treba jer (1) nema potrebe, i (2) vaš kod će biti mnogo sporiji od Stata-inog ugrađenog u petlju.

4.2.1 Looping preko nizova brojeva

Klasična forma komande za petlje uzima oblik

forvalues number = sequence {
    ... body of loop using `number' ...
}

Ovde je forvalues ključna reč, number je ime lokalnog makroa koji će biti postavljen na svaki broj u nizu, i sequence je opseg vrednosti koje mogu imati oblik

  • min/max da ukaže na sekvence brojeva iz min do max u jednom koraku, na primer 1/3 prenosi 1,2 i 3, ili
  • first(step)last koji daje niz od first do last koraka u veličini step. Na primer 15(5)50 daje niz od 15,20,25,30,35,40,45 i 50.

(Postoje dva načina specificiranja druge vrste niza, ali mislim da je ovaj naveden najjasniji, pogledajte help forvalues za alternativama).

Otvaranje leve zagrade mora da bude poslednja stvar na prvoj liniji (osim komentara), i petlja mora biti zatvorena sa odgovarajućim desnim stegnutim na liniji sama od sebe. Petlja se izvršava jedanput za svaku vrednost u nizu sa svojim lokalnim makroom number (ili kako god to zvali), sadrži vrednost.

Kreiranje lutke varijabli

Evo ga moj omiljeni način za stvaranje lutki varijabli koje predstavljaju starosne grupe. Možete naravno, grupisati starost u petogodišnjim intervalima, a zatim koristite tabulage ageg, gen(ageg) da bi Stata generisala lutke, ali brzo, šta je ageg3? Evo alternative koja vodi do boljih imena za varijable:

forvalues bot = 20(5)45 {
	local top = `bot' + 4
	gen age`bot'to`top' = age >= `bot' & age <= `top'
}

Оvo će stvoriti lutku varijable age20to24 do age45to49. (Uzgred age25to29 je isto kao i ageg3. Koji je jasniji?) Način na koji petlja radi je da lokalni makro bot uzima vrednost između 20 i 45 u razmacima od 5 (dakle 20, 25, 30, 35, 40 i 45), donja granicu ovih starosnih grupa.

Unutar petlje pravimo lokalni makro top koji predstavlja gornju granicu starosnih grupa, što je jednako donjoj granici plus 4. Prvi put kroz petlju bot je 20, pa je top 24. Koristimo znak jednakosti za skladištenje rezultata dodavanjem 4 u bot.

Sledeća linija je jednostavno generisana izjava. Prvi put će kroz petlju linija reći gen age20to24 = age >= 20 & age <= 24, kao što možete videti tako što ćete uraditi makro substituciju sami. Ovo će stvoriti prvu lutku, a Stata će se zatim vratiti na vrh da bi stvorila drugu.

4.2.2 Looping preko elemenata u listi

Druga komanda za petlje je foreach i dolazi u šest ukusa, koji se bave različitim tipovima listi. Počeću sa generičkom listom:

foreach item in a-list-of-things {
	... body of loop using `item' ...
}

Evo foreach je ključna reč, item je lokalni makro sa imenom po vašem izboru, in je druga ključna reč, i ono što dolazi posle je spisak praznih razdvojenih reči. Probajte ovaj primer:

foreach animal in cats and dogs {
	display "`animal'"
}

Ova petlja će odštampati "cats", "and", i "dogs", zato što je lokalni makro animal postavljen na svakoj reči u listi. Stata ne zna da “and” nije životinja, ali čak i da zna, ne bi je bilo briga, jer je lista generisana.

Ako ste hteli da petlja ide preko nepravilnog niza brojeva na primer je potrebno da uradite nešto sa Coale-Demeny regionalnim modelom životnih tabela za nivoe 2, 6 i 12 - možete da pišete:

foreach level in 2 6 12 {
	... do something with `level' ...
}

То је то. Оvо је verovatno sve što treba da znate o looping-u.

4.2.3 Looping preko specijalizovanih listi

Stata ima pet drugih varijanti foreach čije petlje prelaze preko određenih listi koje ću sad kratko opisati.

Liste varijabli

Мožda najkorisnija varijanta je:

foreach varname of varlist list-of-variables {
	... body of loop using `varname' ...
}

Ovde su foreach, of i varlist ključne reči i moraju biti otkucane tačno onako kako i jesu. list-of-variables je samo to, spisak postojećih imena varijabli kucane korišćenjem standardnim Stata konvencijama, tako da možete da skratite imena (na sopstveni rizik), koristići var* da bi se odnosilo na sve varijable koje počinju sa “var”, ili kucajte var1-var3 da bi se odnosilo na varijable var1 do var3.

Prednosti ove petlje preko generičkog ekvivalenta foreach varname in list-of-variables je da Stata proverava svako ime na listi da je zaista postojeće ime varijable, i omogućava vam da skratite ili proširite imena.

Ako vam je potrebna da petlja preko novih nasuprot postojećim varijabli koristite foreach varname of newlist list-of-new-variables. Newlist ključna reč zamenjuje varlist i govori Stata-i da proveri da su svi elementi liste prava imena varijabli koja već ne postoje.

Reči u makrou

Dve druge varijante petlje preko reči u lokalnom ili globalnom makrou; oni koriste ključne reči global ili local praćeno imenom makroa (umesto listi). Na primer, ovde je način da se navede varijabla kontrole iz odeljka o lokalnim makroima:

foreach control of local controls {
	display "`control'"
}

Pretpostavljam da ćete učiniti nešto više zanimljivo nego samo spisak imena varijabli. Zato što smo koristili petlje preko varijabli u datasetu mogli bismo postići isti cilj pomoćuforeach sa varlist; ovde smo sačuvali proveravanje.

Liste brojeva

Stata takođe imaforeach varijantu koja je specijalizovana za liste brojeva (ili numlists u Stataspeak) koja ne može da se rešava sa forvalues.

Pretpostavimo da anketa ima osnove u 1980, pa slede usponi u 1985 i 1995. (Zapravo je planirano istraživanje u 1990, ali nije bilo finansirano.) Za petlju preko njih možete da:

foreach year of numlist 1980 1985 1995 {
	display "`year'"
}

Naravno, vi ćete učiniti nešto zanimljivije nego samo štampanje godina. Numlist može biti naveden kao 1 2 3, ili 1/5 (značeći 1 2 3 4 5), ili 1(2)7 (računajući od 1 do 7 u razmacima po 2, dobijajući 1 3 5 7); kucajte help numlist za više primera.

Prednost ove komande nad generičkim foreach je da će Stata proveriti da svaki od elemenata liste brojeva je zaista broj.

4.2.4 Looping za neko vreme

Ono što je zajedničko za mnoge programske jezike, Stata takođe ima while petlju, koja ima sledeću strukturu:

while condition {
	... do something ...
}

u kojoj je uslov izraz. Petlja se izvršava sve dok je uslov istinit (različit od nule). Obično se desi nešto unutar petlje da bi uslov bio lažan, inače bi kod bio pokrenut zauvek.

Tipična upotreba while je iterativan postupak procenjivanja, gde napravite petlju, dok je razlika u uzastopnim procenama premašena unapred definisanu. Obično se broj iteracije koristi za detekciju nedostatka konvergencije.

continue [,break] komanda omogućava izlaženje iz bilo koje petlje, uključujući i while, forvalues i foreach. Komanda zaustavlja trenutnu iteraciju i nastavlja sa sledećom, ukoliko break nije navedena u tom slučaju izlazi iz petlje.

4.2.5 Uslovno izvršenje

Stata takođe poseduje if programsku komandu, koju ne treba mešati sa ifkvalifikatorom koji se može koristiti za ograničavanje komande na podskup podataka, kao u summarize mpg if foreign. The ifkomanda ima sledeću strukturu:

if expression {
	... commands to be executed if expression is true ...
}
else {
	... optional block to be executed if expression is false ...
}

Ovde su if i opciono i else ključne reči, kucajte help exp za objašnjenje izraza. Otvarajuća velika zagrada { mora da bude poslednja stvar na liniji (osim komentara) a zatvarajuća velika zagrada } mora biti na novoj liniji po sebi.

Ako se if ili else delovi sastoje od jedne komande mogu da idu na istoj liniji bez zagrada, kao u if expression command. Ali if expression { command } izraz nije ispravan. Možete da koristite zagrade šireći kod u tri linije i to često poboljšava čitljivost koda.

Dakle, ovde imamo glupu petlju gde smo probili pet od mogućih deset iteracija:

	forvalues iter=1/10 {
		display "`iter'"
		if `iter' >= 5 continue, break
	}

I sa tim, probijamo se iz looping-a.

4.3 Pisanje komandi

Sada se okrećemo prema zabavnom delu pisanja vaših Stata komandi. Pratite nas dok razvijamo par prostih programa, jedan da potpiše vaš output, i još jedan da proceni Coale-McNeil model raspored, tako da možemo da napravimo zaplet ovako:

4.3.1 Program bez argumenata

Hajde da razvijemo komandu koja će pomoći da obeležimo output sa vašim imenom i email adresom. (Obično biste želeli vremensku oznaku, ali to je već dostupno na vrhu vašeg log fajla. Uvek prijavite svoj output, zar ne?) Najlakši način da se razvije komanda je da počnete sa uradi datotekom. Pokrenite Stata editor za uradi datoteke (Ctrl-8) i kucajte:

capture program drop sign
program define sign
	version 9.1
	display as text "German Rodriguez "
	display "{txt}{hline 62}"
end

Тo je to. Ako sada otkucate signStata će prikazati potpis pomoću teksta (obično zelene boje na vašm ekranu).

program drop izjava je potrebna za slučaj da napravite promene i treba da ponovo pokrenete uradi datoteku, jer ne možete da definišete postojeći program. capture je veoma potreban prvi put, kada nema ništa da odustane.

version izjava govori nam da je ova komanda razvijena za Stata 9.1 Verziju, i pomaže budućim verzijama da funkcionišu ispravno, čak iako se sintaksa promenila u međuvremenu.

Poslednja linija koristi malo SMCL, izgovara se “smickle” i skraćenica je za Stata Markup Control Language, što je naziv Stata-inog output procesora. SMCL koristi običan tekst u kombinaciji sa komandama zatvorenim u zagrade. Na primer, {txt} postavlja režim prikaza na tekst, a {hline 62} povlači horizontalno pravilo tačno 62 znaka dugačko. Da biste saznali više o SMCL, kucajte help smcl.

4.3.2 Program sa argumentom

Da biste napravili korisne programe, često ćete morati da dostavite informacije do njih, u obliku “argumenata” koje upisujete posle komandi. Hajde da napišemo komandu koja odjekuje ono što kažete:

capture program drop echo
program define echo
	version 9.1
	display as text "`0'"
end

Probajte da ukucate echo Programming Stata Tutorial da biste videli šta će da se desi.

Kada pozovete komandu, Stata skladišti argument u lokalni makro koji se zove 0. Mi koristimo komandu sa ekrana `0' da bi procenili makro. Rezultat je tekst, tako da smo ga stavili u navodnike. (Pretpostavimo da ste uneli echo Hi, tako da lokalni makro 0 ima Hi; komanda će pročitati display Hi i Stata će se žaliti, sa rečenicom 'Hi nije pronađeno'. Mi želimo komandu da čita display "Hi", zbog čega smo kodirali display "`0'".)

Ako ne preciziramo ništa, lokalni makro 0 će biti prazna linija, komanda će pročitati display "" i Stata će odštampati praznu liniju.

4.3.3 Složeni Navodi

Pre nego što počnemo da slavimo moramo da popravimo mali problem sa našom novom komandom. Pokušajte da kucate eho “konačne” verzije. Stata će se žaliti. Zašto? Jer posle zamene makroa sve najvažnije komande displeja će pročitati:

display "The hopefully "final" run"

Problem je u tome što je navod pre finala zatvorio početni navod, pa Stata vidi ovo kao "The hopefully " praćeno final "run", koji Stata-i izgleda kao nevažeće ime. Očigledno je da nam treba neki način da razlikujemo unutrašnji i spoljašnji navod.

Uzgred, mogli ste da vidite tačno gde su stvari pošle naopako, kucanjemset trace on i pokretanjem komande. Možete da vidite (često bolne) detaljno sve korake koje je Stata prošla, uključujući sve makro zamene. Ne zaboravite da unesete set trace off kada završite. Ukucajte help trace da biste naučili više.

Rešenje za naš problem? Stata-ini csloženi dvostruki navodnici: `" za otvaranje i "' zatvaranje navoda, kao u `"compound quotes"'. Zato što su simboli za otvaranje i zatvaranje različiti ovi navodi mogu biti ugneždeni. Složeni navodi

  • mogu biti korišćeni bilo gde, gde je dvostuki navod korišćen.
  • moraju da se iskoriste ako je tekst koji se navodi sadrži dvostruke navode.

Dakle, naš program mora display `"`0'"'. Evo je konačna verzija

program define echo
    version 9.1
    if `"`0'"' != "" display as text `"`0'"'
end

Primetićete da sam se oslobodio capture drop line. To je zato što smo sada spremni da sačuvamo program kao uradi datoteku. Ukucajte sysdir da biste našli gde je vaš lični ado direktorijum, a zatim sačuvajte datoteku tamo sa imenom echo.ado. Komanda će sada biti dostupna svaki put kada koristite Stata-u.

(Као fusnotu, želeli biste da se uverite da ne postoji zvanična Stata komanda koja se zove echo. Da biste to uradili, ja sam kucao which echo. Stata mi je odgovorila: “Komanda echo nije pronađena, ni kao built-in ili ado datoteka”. Naravno ne postoji garancija da neće napisati jednu takvu; Stata je rezervisala sve engleske reči).

4.3.4 Pozicioni Argumenti

Pored čuvanja svih argumenata u lokalnom makrou 0, Stata analizira argumente (koristi beli prostor kao razdvajanje) i skladišti sve reči koje pronalazi u lokalnim makroima 1, 2, 3, itd.

Tipično vi biste uradili nešto sa `1' a zatim prešli na sledeći. Komanda mac shift zgodno odgovara onda, jer pomera sve makroe nadole za po jedan, tako da je sadržaj 2 sada u 1, i 3 je u 2, i tako dalje. Na ovaj način ćete uvek raditi sa onim što je u 1 i samo pomerate nadole. Kada je lista iscrpljena, 1 je prazan i vi ste gotovi.

Dakle, ovde je kanonski program koji prikazuje svoje argumente:

capture program drop echo
program define echo
	version 9.1
	while "`1'" != "" {
		display `"`1'"'
		mac shift
	}
end

Ne zaboravite mac shift, u suprotnom vaš program može biti pokrenut zauvek. (Ili dok ne pritisnete taster za kraj programa).

Pokušajte echo one two three testing. Sada probajte echo one "two and three" four. Obratite pažnju kako se mogu grupisati reči u jedan argument pomoću navoda.

Ovaj metod je koristan, i nekad može dati argumentima smislenija imena koristeći args, ali će preći na sledeći nivo, što je mnogo moćnije i robusnije.

(Uzgred možete proći argumente ne samo na komande, već i na uradi fajlove takođe. Ukucajte help do da biste naučili više).

4.3.5. Korišćenje Stata sintakse

Аko vaša komanda koristi standardnu Stata sintaksu, što znači da su argumenti lista varijabli, možda i težina, možda if ili in klauzula, a možda i gomila opcija, možete da iskoristite Stata-ine parser, što odlično skladišti sve ove elemente u lokalnim makroima spremni za vašu upotrebu.

Prototip komande

Dozvolite nam da napišemo komandu koja izračunava verovatnoću venčanja do određenog uzrasta u Coale-McNeil modelu sa datom sredinom, standardnom devijacijom i proporcijom venčanja. Sintaksa naše predložene komande:

pnupt age, generate(married) [ mean(25) stdev(5) pem(1)]

Tako smo zahtevali postojeću varijablu sa godištem u egzaktnim godinama i obaveznu opciju navođenja nove varijable da bude generisana sa proporcijama u braku. Takođe postoje opcije da odredite standardnu devijaciju, a procenat ikada venčanih u rasporedu, sa sve vrednosti. Evo prvog reza na komandi:

capture program drop pnupt
program define pnupt
	version  9.1
	syntax varname, Generate(name) ///
		[ Mean(real 25) Stdev(real 5) Pem(real 1) ]
	// ... we don't do anything yet ...
end

Prva stvar koju treba napomenuti jeste da syntax komande izgleda neverovatno kao naš prototip. Eto koliko je lako ovo.

Variable Lists

Prvi element u našoj sintaksi je primer listi varijable ili varlist. Možete da navedete minimum i maksim, na primer program koji zahteva tačno dve varijable napisao bih varlist(min=2 max=2). Kada imate samo jednu varijablu, kao što smo mi uradili, možete da ukucate samo varname, što je skraćeno za varlist(min=1 max=1).

Stata će se uveriti da se vaš program zove sa tačno jednim imenom postojeće varijable koja će biti smeštena u lokalnom makrou koji se zove varlist. (Makro se uvek zove varlist, čak i ako imate samo jednu promenljivu i koristi varname u svojoj izjavi sintakse). Pokušajte pnupt nonesuch i Stata će se žaliti, rekavši: “varijabla nonsuch nije pronađena”.

(Ako ste radili programiranje ranije, i provodite više od 75% vremena ispravljajući input greške, a samo 25% se fokusirate na zadatak, zaista ćete ceniti syntax komandu. Radi dosta proveravanja grešaka za vas).

Opcije i Default

Elementi opcione sintakse su zatvoreni u uglastim zagradama [ i ]. U našoj komandi generate opcija je neophodna, ali su ostale tri opcione. Probajte ove komande za generisanje malog dataset testa sa varijablom starosti u rasponu od 15 do 50.

drop _all
set obs 36
gen age = 14 + _n

Sada probajte pnupt age. Ovog puta Stata je srećna sa age ali primećujete ‘opcija generiši () potrebna’. Da li sam rekao da syntax uštedi mnogo posla? Opcije koje uzimaju argumente, moraju da specifišu vrstu argumenta (integer, real, string, name) i opciono, podrazumevanu vrednost. Naš generate uzima name, i potrebno je, tako da ne postoji default. Pokušajte pnupt age, gen(2). Stata će se žaliti da 2 nije ime.

Ako je sve u redu, sadržaj opcije se čuva u lokalnom makrou sa istim imenom kao opcija ovde generate.

Argumenti

Sada moramo da uradimo malu proveru da li je ime varijable važeće, što radimo sa confirm:

confirm new variable `generate'

Stata zatim proverava da biste mogli da, u stvari, da generišete ovu varijablu, i ako ne pokazuje error 110. Probajte pnupt age, gen(age) i Stata će reći ‘starost već definisana’.

Trebalo bi da bude jasno do sad da će Stata proveriti da li ste naveli, srednju, standardnu devijaciju ili odnos ikad venčanih, skraćeno m(), s() and p(), oni će biti realni brojevi, koji će biti smešteni u lokalnim makroima po imenu mean,, stdev, i pem. Ako opcija izostavi, lokalni makro će sadržati default.

Možete da uradite više provera na inputu. Hajde da uradimo brzu proveru da su sva tri parametra ne-negativni i procenat je na više od jedan:

if (`mean' <= 0 | `stdev' <= 0 | `pem' <= 0 | `pem' > 1) {
	di as error "invalid parameters"
	exit 110
}

Možete da budete finiji prema svojim korisnicima pa da napravite odvojene provere za svaki parametar, ali za sada ovo će odgovarati.

Privremene varijable

Sada smo već spremni da izvršimo neke proračune. Iskoristićemo odnos Coale-McNeil modela i gama distribucije, kao što su objasnili Rodriguez i Trussell (1980). Ovo je radna verzija programa:

program define pnupt
*! Coale-McNeil cumulative nuptiality schedule v1 GR 24-Feb-06
	version 9.1
	syntax varname, Generate(name) [Mean(real 25) Stdev(real 5) Pem(real 1)]
	confirm new var `generate'
	if `mean' <= 0 | `stdev' <= 0 | `pem' <= 0 | `pem' > 1 {
		display as error "invalid parameters"
		exit 198
	}
	tempname z g
	gen `z' = (`varlist' - `mean')/`stdev'
	gen `g' = gammap(0.604, exp(-1.896 * (`z' + 0.805)))
	gen `generate' = `pem' * (1 - `g') 
end	

Mogli smo napisati formulu za verovatnoću u jednoj liniji ali bismo žrtvovali čitljivost. Umesto toga, prvo standardizujemo godine, oduzimanjem i deljenjem sa standardnom devijacijom. Kako možemo nazvati ovu varijablu? Možda ćete biti u iskušenju da je nazovete z, ali šta ako korisnik vašeg programa ima varijablu nazvanu z, ali šta ako korisnik vašeg programa ima varijablu nazvanu z? Kasnije ćemo oceniti gama funkciju. Šta možemo nazvati rezultatom?

Rešenje je tempname komanda, koja traži da Stata izmisli jedinstvena imena privremenih varijabli, u ovom slučaju dve koje će se čuvati u lokalnim makroima z i g. Pošto su ovi makroi lokalni, ne postoji rizik od sukoba imena. Druga karakteristika privremenih varijabli je da će one automatski nestati kada se vaš program završi, tako da Stata čisti za vas.

Linija gen `z' = (`varlist' - `mean')/`stdev' verovatno izgleda pomalo čudno na prvi pogled. Imajte na umu da su sve količine interesa sada čuvaju u lokalnim makroima i mi moramo da ih procenimo da bismo otišli bilo gde, i otuda obilje backticks-a: `z dobija ime naše privremene varijable, `varlist' dobija ime starosne varijable koju postavlja korisnik, `mean' dobija vrednost proseka, i `stdev' dobija vrednost standardne devijacije. Nakon makro zamene ova linija će pročitati nešto slično kao gen 000001 = (age-22.44)/5.28, što verovatno ima mnogo više smisla.

If/In komande

Mogli biste da razmislite o omogućavanju korisnika da sam odredi if i in uslove za vašu komandu. Ovo bi trebalo da se doda u sintaksu, koja se nalazi u lokalnim makroima, koji onda mogu da se koriste u kalkulacijama, u ovom slučaju prošao pored generate.

Za detaljniju diskusiju o ovoj temi kucajte help syntax i selektujte if a onda i in. Odeljak u help mark je takođe relevantan.

4.3.6 Kreiranje novih varijabli

Ponekad sve što će vaše komande da urade jeste da naprave novu varijablu. Ovo je, u stvari, ono što naša mala komanda radi. Zar ne bi bilo lepo kad biste mogli da koristite egen tip komande ovako:

egen married = pnupt(age), mean(22.48) stdev(5.29) pem(0.858)

Pa, mi možemo! Kao što se dešava, egen je proširiv za korisnika. Da biste implementarilali funkciju zvanu pnupt morate da napravite program (ado fajl) nazvan _gpnupt, drugim rečima dodat prefiks _g. Dokumentacija o egen ekstenziji je malo oskudna, ali kada znate ovu osnovnu činjenicu sve što treba da uradite je da pogledate na izvoru egen komande i kopirate ga. (Pogledao sam u _gmean.)

Dakle, evo egen verzije naše Coale-McNeil komande:

program define _gpnupt
*! Coale-McNeil cumulative nuptiality schedule v1 GR 24-Feb-06
	version 9.1
	syntax newvarname=/exp [, Mean(real 25) Stdev(real 5) Pem(real 1)]
	if `mean' <= 0 | `stdev' <= 0 | `pem' <= 0 | `pem' > 1 {
		display as error "invalid parameters"
		exit 198
	}
	tempname z g
	gen `z' = (`exp' - `mean')/`stdev'
	gen `g' = gammap(0.604, exp(-1.896 * (`z' + 0.805)))
	gen `typlist' `varlist' = `pem' * (1 - `g') 
end	

Postoji malo razlika između ovog programa i prethodnog. Umesto input varijable, egen prihvata izraz koji biva procenjen i čuvan u privremenoj varijabli zvanoj exp. Output varijable naveden je kao varlist, u ovom slučaju newvarname. Zato z sada radi sa exp, i gen stvara varlist. Misteriozna typlist je tu zato što egen omogućava da odredite vrstu outputa varijable (float po defaultu) i da bude usvojena u našim funkcijama, koje je prenose do gen.

4.3.7 Uklapanje Coale-McNeil

Spremni smo da otkrijemo kako je početni zaplet proizveden. Podaci su dostupni u Stata datoteci na web sajtu demografija kursa, i ima tačake ikada udatih i neudatih žena po starosti. Mi smo izračunali posmatrani odnos u braku, izračunavanjem opremljene vrednosti na osnovu procene Rodriguez i Trussell (1980), kao i iscrtavanju rezutata. To je sve urađeno u nekoliko linija:

use http://data.princeton.edu/eco572/datasets/cohhnupt
gen obs = ever/total
egen fit = pnupt(age+0.5), mean(22.44) stdev(5.28) pem(.858)
gen agem = age + 0.5
twoway (scatter obs agem) (line fit agem), ///
    title(Proporcije Oženjenih Prema Starosti) subtitle(Colombia 1976) ///
	ytitle(Proporcije Oženjenih) xtitle(starost)

Stvarna procena može da se sprovede koristeći Stata-ine maksimalno verodostojne procedure, ali to je priča za neki drugi dan.

4.4 Druge teme

Zbog nedostatka vremena i prostora nismo razgovarali o vraćanju vrednosti iz vašeg programa. Ukucajte help return da biste naučili više. Za povezane teme o proceni komande ukucajte help ereturn i help _estimates. Esencijalna referenca o proceni je Maximum Likelihood Estimation with Stata od strane Gould, Pitblado i Sribney (2003).

Drugi subjekti interesovanja su matrice (počnite sa help matrix), i kako da napravite komandu "byable" (kucajte help byable). Za ozbiljan output morate da naučite više o SMCL, počnite sa help smcl. Za rad na grafici možda ćete želeti da proučite klasu programiranja (help class) i naučite o serset-ima (help serset). Da biste obezbedili grafički korisnički interfejs sa vašom komandom pokušajte help dialog programming. Moguće je da čita i piše tekst kao i binarne fajlove (pogledajte help file), ali ja mislim da je za ove zadatke bolja Mata. Možete čak i da pišete Stata ekstenziju u C, ali potreba za onim smanjenom dostupnošću Mate.

Published (Last edited): 02-04-2013 , source: http://data.princeton.edu/stata/programming.html