#stata #postfile
#stata #postfile
Вопрос:
Я пытаюсь написать программу Stata, которая выполняет некоторые вычисления по идентификатору, и я хочу сделать это так, чтобы идентификатор мог быть либо строковым, либо целым числом.
Сильно упрощенная версия того, что я пытаюсь сделать, выглядит следующим образом:
clear all
***** test data
input str10 id1 id2 x y
a 1 20 40
a 1 140 20
a 1 0 70
b 2 50 25
b 2 25 50
b 2 40 42
end
*****
capture program drop myprog
program define myprog
version 14.2
syntax using, ID(varname) Mean(varname)
tempname postname
quietly levelsof `id', local(ids)
local idtype: type `id'
postfile `postname' `idtype' `id' `mean' `using', replace
foreach i of local ids {
quietly summarize `mean' if `id'==`i'
post `postname' (`i') (`r(mean)')
}
postclose `postname'
end
И я ожидаю, что сработают оба следующих действия:
myprog using "test1.dta", id(id1) mean(x)
myprog using "test2.dta", id(id2) mean(x)
Есть какие-нибудь советы?
Ответ №1:
Просто используйте оператор if
/ else
, чтобы различать два случая:
capture program drop myprog
program define myprog
version 14.2
syntax using, ID(varname) Mean(varname)
tempname postname
quietly levelsof `id', local(ids)
local idtype: type `id'
postfile `postname' `idtype' `id' `mean' `using', replace
if substr("`idtype'" , 1, 3) == "str" {
foreach i of local ids {
summarize `mean' if `id'=="`i'", meanonly
post `postname' ("`i'") (`r(mean)')
}
}
else {
foreach i of local ids {
summarize `mean' if `id'==`i', meanonly
post `postname' (`i') (`r(mean)')
}
}
postclose `postname'
end
Кстати, обратите внимание на использование meanonly
опции summarize
.
Комментарии:
1. Спасибо! Оказывается, мне потребовалось всего 10 минут, чтобы отойти от своего ответа в Google, и в итоге я сделал что-то похожее на то, что сделали вы.
Ответ №2:
Вот что я в итоге сделал:
capture program drop myprog
program define myprog
version 14.2
syntax using, ID(varname) Mean(varname)
tempname postname
quietly levelsof `id', local(ids)
local idtype: type `id'
postfile `postname' `idtype' `id' `mean' `using', replace
capture confirm string variable `id'
if !_rc {
foreach i of local ids {
quietly summarize `mean' if `id'=="`i'"
post `postname' ("`i'") (`r(mean)')
}
}
else {
foreach i of local ids {
quietly summarize `mean' if `id'==`i'
post `postname' (`i') (`r(mean)')
}
}
postclose `postname'
end
Два почти идентичных цикла выглядят некрасиво, но я думаю, что это нормально.
Комментарии:
1. Смотрите пересмотр ответа @ Pearly Spencer, который стал ближе к вашему. Вы также могли бы использовать
egen newid = group(id), label
, а затем опубликовать метки значенийnewid
, которые всегда являются строковыми. Таким образом, был бы только один цикл.2. Хорошее предложение. К сожалению, в моем реальном варианте использования я буду объединять результаты postfile обратно в другой «основной» набор данных, и мне придется сохранить тип данных.