我使用一组命名规则定义分类变量。我想把这些规则放在序言中作为"参数"我以后可以轻易改变。我想知道最好的方法。我觉得这里不需要一个可重复的例子,因为我要问 - 通常 - 在Stata中设置基本上具有键值结构的参数的好方法是什么?
这是我目前使用的代码,用于根据天气事件的假人对天数进行分类。
preserve
clear
input str12 key str40 val
"Clear" "!(event_thunder|event_snow|event_rain)"
"Rain" "event_rain & !(event_thunder|event_snow)"
"Snow" "event_snow & !(event_thunder|event_rain)"
"Rain & Snow" "(event_snow & event_rain) & !event_thunder"
"Thunder" "event_thunder"
end
scalar N_events = _N
forvalues i = 1/`=N_events'{
scalar event_key`i' = key[`i']
scalar event_val`i' = val[`i']
}
restore
稍后在代码中,我可以迭代我的"键"和" val"标量来定义我的分类变量。
gen byte event = 0
forvalues i = 1/`=N_events'{
local event_condition `=event_val`i''
replace event = `i' if `event_condition'
}
我仍然没有找到使用我的event_key*
标量应用标签的正确代码。对此的任何建议也会受到欢迎。
答案 0 :(得分:4)
您的代码经过一些调整,与此示例相同:
clear
set more off
sysuse auto
keep make price foreign
preserve
clear
input str12 key str40 val
"for_cheap" "foreign & price < 10000"
"hom_expen" "!foreign & price >= 10000"
end
local numkeys = _N
forvalues i = 1/`numkeys' {
local event_key`i' = key[`i']
local event_val`i' = val[`i']
}
restore
gen byte event = 0
forvalues i = 1/`numkeys' {
replace event = `i' if `event_val`i''
}
save testing, replace
但是你只想要这个,它会产生完全相同的结果:
clear
set more off
sysuse auto
keep make price foreign
gen byte event = 0
replace event = 1 if foreign & price < 10000
replace event = 2 if !foreign & price >= 10000
// to test these results with previous
cf _all using testing, verbose
例如,您仍然可以将条件放在当地人中,并使用:
<snip>
local for_cheap foreign & price < 10000
local hom_expen !foreign & price >= 10000
gen byte event = 0
replace event = 1 if `for_cheap'
replace event = 2 if `hom_expen'
此外,您可以使用循环而不是多个replace
s:
<snip>
local for_cheap "foreign & price < 10000"
local hom_expen "!foreign & price >= 10000"
local allcond for_cheap hom_expen
local n : word count `allcond'
gen byte event = 0
forvalues i = 1/`n' {
local cond `:word `i' of `allcond'' // extended macro function
replace event = `i' if ``cond''
// syntax for value labels
local lbl `lbl' `i' "`cond'"
}
label define lblevent `lbl'
label values event lblevent
list in 1/25
将每个命名条件放在另一个名为allcond
的本地中。然后使用parallel lists策略进行循环。我还为价值标签添加了代码。
另请参阅help extended_fcn
以阅读扩展宏功能(我已使用过)。
如果您只想声明一次键/值,您仍然可以仅使用本地人来执行此操作:
clear
sysuse auto
keep make price foreign
local allcond for_cheap "foreign & price < 10000" ///
hom_expen "!foreign & price >= 10000"
local n : word count `allcond'
gen byte event = 0
forvalues i = 2(2)`n' {
// get label and condition (extended macro function)
local condlbl `:word `=`i'-1' of `allcond''
local cond `:word `i' of `allcond''
// replace
replace event = `=`i'/2' if `cond'
// syntax for value labels
local lbl `lbl' `=`i'/2' "`condlbl'"
}
label define lblevent `lbl'
label values event lblevent
但是在这一点上,您使用数据库(和我的等效代码)的策略更容易阅读。
顺便说一句,根据代码的其余部分,您可能会避免使用preserve/restore
。您可以先input
键/值,然后加载工作数据库:
clear
set more off
// input key/val database
input str12 key str40 val
"for_cheap" "foreign & price < 10000"
"hom_expen" "!foreign & price >= 10000"
end
local numkeys = _N
forvalues i = 1/`numkeys' {
local event_key`i' = key[`i']
local event_val`i' = val[`i']
}
// load working database
clear
sysuse auto
keep make price foreign
gen byte event = 0
forvalues i = 1/`numkeys' {
replace event = `i' if `event_val`i''
}
list