我正在使用一组命名规则定义分类变量。我想将这些规则作为“参数”放在序言中,以后可以轻松更改。我想知道最好的方法来做到这一点。我觉得这里不需要可重现的示例,因为我在问——一般来说——在 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
在代码的后面,我可以迭代我的“key”和“val”标量来定义我的分类变量。
gen byte event = 0
forvalues i = 1/`=N_events'{
local event_condition `=event_val`i''
replace event = `i' if `event_condition'
}
我仍然没有找到使用我的 event_key*
标量应用标签的正确代码。也欢迎就此提出任何建议。
最佳答案
你的代码,经过一些调整,等同于这个例子:
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
:
<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
。您可以先输入
键/值,然后加载工作数据库:
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
关于hashtable - Stata 简单键值对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25895881/