如何查找组内观察是否具有特定值

How to find if observation within group has certain values

说我有这个MWE:

clear all
input str2 person enr_year enr_term
"a" 2000 1     
"a" 2000 2   
"a" 2000 2 
"a" 2000 3   
"a" 2000 3 
"a" 2001 1   
"a" 2001 2   
"a" 2001 3   
"a" 2002 2
"a" 2002 2    
"a" 2003 2      
"a" 2006 1
"a" 2006 2
"a" 2008 2  
"b" 2000 2
"b" 2001 3
end

label define term 1 "Summer" 2 "Fall" 3 "Spring"
label values enr_term term

一些解释是为了。这是学校招生数据。 person是一个人,凡事都要在人之内完成。

enr_year 是一个学年。 enr_term 是一个学术术语。夏季和秋季在Spring之前的原因是因为这一年是学年,而不是日历年。

数据中的每一行都隐含地表示在给定年份和学期注册的人。

我的任务是创建两个指标变量:enr_this_springenr_next_fall。我可以成功获得enr_this_spring。我已经包含了这样做的代码,以防逻辑有助于弄清楚如何获得 enr_next_fall

*这些指标变量应该只为秋季入学的观察结果创建。

enr_this_spring表示此人报名了以下spring。因为我们只为秋季学期制作这个变量,所以如果同一年有 spring 观察,这将为 1。否则它将为 0,即使下一年有 spring 观察。

如果下一年有秋季观测,

enr_next_fall 将为 1。如下所述,如果学生在 x 的秋季入学,而不是在 x+1 的秋季入学,而是在 x+n 的秋季入学,那么我不确定如何克服的问题就会出现, 其中 n>1。

如果同一年内有两次秋季观察(多个入学时期,可能学生同时被两所学校录取),它们将取相同的值。

这是我想要得到的:

clear all
input str2 person enr_year enr_term enr_this_spring enr_next_fall
"a" 2000 1  .   . // missing because not Fall    
"a" 2000 2  1   1 // 1 b/c a/2000/3; 1 b/c a/2001/2   
"a" 2000 2  1   1 // same reasons as line directly above 
"a" 2000 3  .   . // missing because not Fall  
"a" 2000 3  .   . // missing because not Fall 
"a" 2001 1  .   . // missing because not Fall   
"a" 2001 2  1   1 // 1 b/c a/2001/3; 1 b/c a/2002/2   
"a" 2001 3  .   . // missing because not Fall   
"a" 2002 2  0   1 // 0 b/c no a/2002/3; 1 b/c a/2003/2  
"a" 2002 2  0   1 // same reasons as line directly above    
"a" 2003 2  0   0 // 0 b/c no a/2003/2; 0 b/c no a/2004/2       
"a" 2006 1  .   . // missing because not Fall  
"a" 2006 2  0   0 // 0 b/c no a/2006/3; 0 b/c no a/2007/2  
"a" 2008 2  0   0 // 0 b/c no a/2008/3; 0 b/c no a/2009/2  
"b" 2000 2  0   0 // 0 b/c no a/2000/3; 0 b/c no a/2001/2
"b" 2001 3  .   . // missing because not Fall
end
label define term 1 "Summer" 2 "Fall" 3 "Spring"
label values enr_term term

从原始数据入手,我首先可以成功得到enr_this_spring如下:

*Create indicators for if the term is spring and if term is fall
gen is_spring = enr_term == 3
gen is_fall = enr_term ==2
*Get the maximum value, within person and year
bys person enr_year: egen enr_this_spring = max(is_spring)
replace enr_this_spring=. if is_fall!=1

我不确定如何创建一个指标来判断此人是否在明年秋季入学。

这是我尝试过的方法,并解释了为什么它按照代码不起作用:

*Preserve the data. We are going to process it and merge back on
preserve
*We only are concerned about fall attendance for this part
keep if enr_term==2
*We only want one observation per term, as duplicates mess up the code
bys person enr_year enr_term: keep if _n==1 
*Make a variable that is a constant 1
gen one = 1
*Make a variable, enr_next_fall that is 1 if the person enrolled in the fall
* in the following observation. Note that we do this within group and sort
* by enr_year
bys person (enr_year): gen enr_next_fall = one[_n+1]
* Replace missing with 0. This only affects the final observation within group
replace enr_next_fall = 0 if missing(enr_next_fall)
*Create temporary file, to be merged on
tempfile a
save `a'
restore
*Merge on the temporary file
merge m:1 person enr_year enr_term using `a'
drop is_spring is_fall one _merge

如果此人没有在第二年秋季注册但又回来了,这并不能满足我的要求。也许他们生病了,错过了整个学年。我应该如何解决这个问题?

我想我已经弄明白了:

clear all
input str2 person enr_year enr_term
"a" 2000 1     
"a" 2000 2   
"a" 2000 2 
"a" 2000 3   
"a" 2000 3 
"a" 2001 1   
"a" 2001 2   
"a" 2001 3   
"a" 2002 2
"a" 2002 2    
"a" 2003 2      
"a" 2006 1
"a" 2006 2
"a" 2008 2  
"b" 2000 2
"b" 2001 3
end

label define term 1 "Summer" 2 "Fall" 3 "Spring"
label values enr_term term

*Create indicators for if the term is spring and if term is fall
gen is_spring = enr_term == 3
gen is_fall = enr_term ==2
*Get the maximum value, within person and year
bys person enr_year: egen enr_this_spring = max(is_spring)
replace enr_this_spring=. if is_fall!=1

*Create enr_next_fall variable. Merge back on
preserve
keep if enr_term==2
bys person enr_year: keep if _n==1
bys person (enr_year): gen next = enr_year[_n+1]
replace next = next - 1
gen enr_next_fall = enr_year==next
drop next
tempfile fall
save `fall'
restore
merge m:1 person enr_year using `fall'
drop _merge
replace enr_next_fall = . if enr_term!=2