Stata顺序使用循环值

时间:2014-10-14 16:51:09

标签: stata

我想用循环替换这段代码:

replace var1=1 if year > 1996 & st==5
replace var1=0 if year < 1996 & st==5
replace var1=1 if year > 1998 & st==6
replace var1=0 if year < 1998 & st==6

我的数据看起来像这样

st year var
5  1993
5  1996
5  1992
6  1991
6  1999`

我写了一个像这样的循环

    foreach st in 5 6}
    foreach yr in 1996 1998 }
   replace var1=1 if year>`yr' & state==`st'
   replace var1=0 if year<`yr' & state==`st'
}
}

然而,此循环不会产生类似于手动方法的结果。我知道我犯了一个愚蠢的错误。

编辑:

为了进一步澄清我写的实际代码(不使用循环),如下所示。我想使用循环或其他更简单的方法来得到相同的结果:

gen policy=.
replace policy=1 if year>1996 & fipscode==5
replace policy=0 if year <1997 & fipscode==5

replace policy=1 if year>1995 & fipscode==6
replace policy=0 if year <1996 & fipscode==6

replace policy=1 if year>1997 & fipscode==9
replace policy=0 if year <1998 & fipscode==9

replace policy=1 if year>1997 & fipscode==15
replace policy=0 if year <1998 & fipscode==15

replace policy=1 if year>1992 & fipscode==16
replace policy=0 if year <1993 & fipscode==16

replace policy=1 if year>1996 & fipscode==31
replace policy=0 if year <1997 & fipscode==31

replace policy=1 if year>1997 & fipscode==32
replace policy=0 if year <1998 & fipscode==32

replace policy=1 if year>1996 & fipscode==39
replace policy=0 if year <1997 & fipscode==39

replace policy=1 if year>1997 & fipscode==40
replace policy=0 if year <1998 & fipscode==40

replace policy=1 if year>1992 & fipscode==54
replace policy=0 if year <1993 & fipscode==54

3 个答案:

答案 0 :(得分:0)

尝试forvalues(我认为与foreach相比,这是有效的)

forvalues st=5/6{
    forvalues yr= 1996(2)1998{
        replace var1=1 if year>`yr' & state==`st'
        replace var1=0 if year<`yr' & state==`st'
    }
}

如果你想坚持foreach

foreach st of numlist 5/6{
    foreach yr of numlist 1996(2)1998{
        replace var1=1 if year>`yr' & state==`st'
        replace var1=0 if year<`yr' & state==`st'
    }
}

答案 1 :(得分:0)

看起来你有一些预定的year与预定的st相匹配。在例子中:1996年5月和1998年7月。如果没有,那么我误解了你的问题。如果是这样,您可以循环并行列表:

clear
set more off

*----- example data -----

input ///
st year
5  1993
5  1996
5  1992
7  1991
7  1999
end

list

*----- what you want -----

gen var1 = .

local ylev 1996 1998
local slev 5 7
local n : word count `ylev'

forvalues i = 1/`n' {

    local y : word `i' of `ylev'
    local s : word `i' of `slev'

    replace var1 = 1 if year > `y' & st == `s'
    replace var1 = 0 if year < `y' & st == `s'

}

list

我很好奇为什么你的条件都不包含=,遗漏了一个案例。

答案 2 :(得分:0)

代码可能或多或少是为了学习技术而发明的任意代码,但这个例子确实很奇怪。即使这一点确实只是为了学习技术,另一个教训就是掌握。

必须事先创建变量var1才能使其生效。有经验的Stata用户会将其视为已阅读,但该声明可能有助于人们学习Stata。

1996年year和1998年year的测试需要进行一些分析。看起来有点奇怪1996和1998的值本身都被忽略了,因为><都排除==,但代码一起确实对这些值有影响。

首先将state的问题放在一边,行人分析显示

  1. year小于1996的观测值首次编码为0,并在循环周围保持0秒。

  2. 第一次忽略year等于1996的观测值,但在循环周围第二次编码。

  3. year等于1997的观测值首次编码为1,但重置为0秒。

  4. year等于1998年的观测值首次编码1次,但第二次被忽略。

  5. 大于1998的year的观测值首次编码为1并重置为1秒。 (包括year上的任何缺失值。)

  6. 引入state变量时,将忽略5或6以外的值。

    整个双循环因此折叠为单个陈述

     replace var1 = year >= 1998 & inlist(state, 5, 6) 
    

    六行成为一行。

    编辑:额外的例子似乎减少到

     gen policy = .
     replace policy = (year>1996) if inlist(fipscode, 5, 31, 39)
     replace policy = (year>1995) if fipscode==6
     replace policy = (year>1997) if inlist(fipscode, 9, 15, 32, 40) 
     replace policy = (year>1992) if inlist(fipscode, 16, 54) 
    

    但它似乎不允许以任何有用的方式循环。