Stata简单的键值对

时间:2014-09-17 16:35:07

标签: hashtable stata

我使用一组命名规则定义分类变量。我想把这些规则放在序言中作为"参数"我以后可以轻易改变。我想知道最好的方法。我觉得这里不需要一个可重复的例子,因为我要问 - 通常 - 在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*标量应用标签的正确代码。对此的任何建议也会受到欢迎。

1 个答案:

答案 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