我对Stata相对陌生,正在尝试统计员工在我的数据集中一段时间内打开的活跃案例的数量(例如,请参阅下面的链接)。我试着根据我在网上找到的一个例子,使用forvalues
编写一个循环,但一直得到
无效语法
对于每个EmpID
,我想统计当向队列中添加新案例时,员工打开的案例数。因此,如果添加了一个OpenDate
为2015年3月15日的事例,并且EmpID
同时打开了另外两个事例,则代码会将值2分配给NumActiveWhenOpened
字段。如果(1)其CCD_ 6小于新病例的CCD_;(2) 其CCD_ 8大于新病例的CCD_。
下面的链接提供了一个示例。我正试图编写一个循环来创建NumActiveWhenOpened
列。如有任何帮助,我们将不胜感激。谢谢
https://i.stack.imgur.com/z4iyR.jpg
编辑
这是不起作用的代码。我确信它有几个问题,我不知道如何将计数存储在[NumberActiveWhenOpen]字段中。
by EmpID: generate CaseNum = _n
egen group = group(EmpID)
su group, meanonly
gen NumActiveWhenOpen = 0
forvalues i = 1/ 'r(max)' {
forvalues x = 1/CaseNum if group == `i'{
count if OpenDate[_n] > OpenDate[_n-x] & CloseDate[_n-x] > OpenDate[_n]
}
}
这听起来像是中讨论的一个问题http://www.stata-journal.com/article.html?article=dm0068但让我们试着保持独立。我不确定我是否理解这些定义,但这可能会有所帮助。
我会偷罗伯托·费雷尔沙盒的一部分。
clear
set more off
input ///
caseid str15(open close) empid
1 "1/1/2010" "3/1/2010" 1
2 "2/5/2010" "" 1
3 "2/15/2010" "4/7/2010" 1
4 "3/5/2010" "" 1
5 "3/15/2010" "6/15/2010" 1
6 "3/24/2010" "3/24/2010" 1
1 "1/1/2010" "3/1/2010" 2
2 "2/5/2010" "" 2
3 "2/15/2010" "4/7/2010" 2
4 "3/5/2010" "" 2
5 "3/15/2010" "6/15/2010" 2
end
gen d1 = date(open, "MDY")
gen d2 = date(close, "MDY")
format %td d1 d2
drop open close
reshape long d, i(empid caseid) j(status)
replace status = -1 if status == 2
replace status = . if missing(d)
bysort empid (d) : gen nopen = sum(status)
bysort empid d : replace nopen = nopen[_N]
l
这个想法是reshape
,使每对日期成为两个观测值。然后,如果我们用1编码每个开盘,用-1编码每个收盘,那么活跃案例的总数就是它们的累积总和。仅此而已。结果如下:
. l, sepby(empid)
+---------------------------------------------+
| empid caseid status d nopen |
|---------------------------------------------|
1. | 1 1 1 01jan2010 1 |
2. | 1 2 1 05feb2010 2 |
3. | 1 3 1 15feb2010 3 |
4. | 1 1 -1 01mar2010 2 |
5. | 1 4 1 05mar2010 3 |
6. | 1 5 1 15mar2010 4 |
7. | 1 6 1 24mar2010 4 |
8. | 1 6 -1 24mar2010 4 |
9. | 1 3 -1 07apr2010 3 |
10. | 1 5 -1 15jun2010 2 |
11. | 1 2 . . 2 |
12. | 1 4 . . 2 |
|---------------------------------------------|
13. | 2 1 1 01jan2010 1 |
14. | 2 2 1 05feb2010 2 |
15. | 2 3 1 15feb2010 3 |
16. | 2 1 -1 01mar2010 2 |
17. | 2 4 1 05mar2010 3 |
18. | 2 5 1 15mar2010 4 |
19. | 2 3 -1 07apr2010 3 |
20. | 2 5 -1 15jun2010 2 |
21. | 2 4 . . 2 |
22. | 2 2 . . 2 |
+---------------------------------------------+
底线是不需要循环,但by:
有很大帮助。这里有用的细节是累积和函数sum()
忽略遗漏。
尝试一些类似的方法
clear
set more off
*----- example data -----
input ///
caseid str15(open close) empid numact
1 "1/1/2010" "3/1/2010" 1 0
2 "2/5/2010" "" 1 1
3 "2/15/2010" "4/7/2010" 1 2
4 "3/5/2010" "" 1 2
5 "3/15/2010" "6/15/2010" 1 3
6 "3/24/2010" "3/24/2010" 1 .
1 "1/1/2010" "3/1/2010" 2 0
2 "2/5/2010" "" 2 1
3 "2/15/2010" "4/7/2010" 2 2
4 "3/5/2010" "" 2 2
5 "3/15/2010" "6/15/2010" 2 3
end
gen opend = date(open, "MDY")
gen closed = date(close, "MDY")
format %td opend closed
drop open close
order empid
list, sepby(empid)
*----- what you want -----
gen numact2 = .
sort empid caseid
forvalues i = 1/`=_N' {
count if empid[`i'] == empid & /// a different count for each employee
opend[`i'] <= closed /// the date condition
in 1/`i' // no need to look at cases that have not yet occurred
replace numact2 = r(N) - 1 in `i'
}
list, sepby(empid)
这是资源密集型的,因此如果您有一个大型数据集,则需要一些时间。原因是它在检查条件的观察上循环。有关r(N)
的说明,请参见help stored results
和help return
。
一本好书Stata提示51:间隔中的事件,《Stata期刊》,Nicholas J.Cox著。
请注意我是如何在代码中提供示例数据集的(请参阅help input
)。这就是我建议你在以后的问题中这样做的方式。这将节省其他人的时间,并增加你得到答案的可能性。