clear
input input record1 record2 value str8 sdate
1 1 0 2 "1/1/2010"
2 1 0 2 "1/1/2010"
3 1 0 3 "1/3/2010"
4 1 0 3 "1/3/2010"
5 1 0 3 "1/3/2010"
6 0 1 -3 "1/5/2010"
7 0 1 -3 "1/5/2010"
8 1 0 2 "1/5/2010"
9 0 1 1 "1/7/2010"
end
gen date = daily(sdate, "MDY")
format date %td
我所拥有的MWE是我的数据中每个人的变量recordi
,如果他们涉及该值,则为1
。我想为每个人创建一个变量,该变量累计将天数值与前一天的最终值相加。留下以下输出。
input record1 record2 value date record1dailysum record2dailysum
1 1 0 2 1/1/2010 2 .
2 1 0 2 1/1/2010 2 .
3 1 0 3 1/3/2010 5 .
4 1 0 3 1/3/2010 5 .
5 1 0 3 1/3/2010 5 .
6 0 1 -3 1/5/2010 . -3
7 0 1 -3 1/5/2010 . -3
8 1 0 2 1/5/2010 7 .
9 0 1 1 1/7/2010 . -2
我有很多记录,所以我使用了一个循环来创建这些值。这就是我尝试创建的recorddailysumi
qui forval i = 1/2
by date: egen record`i'dailysum = value + value[_n-1] if record`i' == 1
}
最后,我想将值向下移动一个日期,因此对于record1
,1/3/2010
的值将是1/1/2010
等中的值。
不能选择压缩数据以按日期创建唯一记录并记录和合并(至少这是最后的手段,因为它是一个庞大而混乱的数据集)。
答案 0 :(得分:1)
代码中的一些错误:
{
行forvalues
by date
表示您希望将每个唯一日期视为一个组。你真的不想要这个。您希望sort date
然后按record[i]
运行代码(根据您的数据结构)。 record
的字段等于1,2,......,在这种情况下,您只需编码bys record (date): ...
(稍后) sum()
(generate
)的egen
函数会给出累积总和。关于请求:通过在数据中重复观察,以及通过在观察中重复累积总和所获得的收益,您不清楚会得到什么。为什么不只是duplicates drop [varlist]
?或者,如果您需要保留所有观察结果,那么标记唯一观察结果可能会更有用,我认为。
最后,“我想为每个人创建一个变量,累计将天数值与前一天的最终值相加。留下以下输出。”与不一致“最后,我想将值向下移动一个日期,因此对于record1,2010年1月3日的值将是2010年1月1日的值,等等。”
一个解决方案,维护你的结构:
clear
input input record1 record2 value str8 sdate
1 1 0 2 "1/1/2010"
2 1 0 2 "1/1/2010"
3 1 0 3 "1/3/2010"
4 1 0 3 "1/3/2010"
5 1 0 3 "1/3/2010"
6 0 1 -3 "1/5/2010"
7 0 1 -3 "1/5/2010"
8 1 0 2 "1/5/2010"
9 0 1 1 "1/7/2010"
end
// tag unique obs (consider instead duplicates drop record1 record2 value sdate, force)
egen tag = tag(record1 record2 value sdate)
// generate stata data
gen date = daily(sdate, "MDY")
format date %td
// fixed loop
sort date
forval i = 1/2 {
gen record`i'dailysum = sum(value) if record`i' == 1 & tag == 1
}
// if you must have duplicated sums, you can replace by group
forvalues i = 1/2 {
clonevar record`i'dailysum2 = record`i'dailysum
bys record`i' value date (record`i'dailysum2): replace record`i'dailysum2 = record`i'dailysum2[1]
}
sort record2 date record1 date
li, sepby(record1) noobs
结果
+------------------------------------------------------------------------------------------------------------+
| input record1 record2 value sdate tag date record.. record.. record.. record.. |
|------------------------------------------------------------------------------------------------------------|
| 2 1 0 2 1/1/2010 0 01jan2010 . . 2 . |
| 1 1 0 2 1/1/2010 1 01jan2010 2 . 2 . |
| 3 1 0 3 1/3/2010 1 03jan2010 5 . 5 . |
| 5 1 0 3 1/3/2010 0 03jan2010 . . 5 . |
| 4 1 0 3 1/3/2010 0 03jan2010 . . 5 . |
| 8 1 0 2 1/5/2010 1 05jan2010 7 . 7 . |
|------------------------------------------------------------------------------------------------------------|
| 6 0 1 -3 1/5/2010 1 05jan2010 . -3 . -3 |
| 7 0 1 -3 1/5/2010 0 05jan2010 . . . -3 |
| 9 0 1 1 1/7/2010 1 07jan2010 . -2 . -2 |
+------------------------------------------------------------------------------------------------------------+
然而,如果这是我的项目,我肯定会看到这样的事情:
// AN ALTERNATIVE APPROACH
clear
input input record1 record2 value str8 sdate
1 1 0 2 "1/1/2010"
2 1 0 2 "1/1/2010"
3 1 0 3 "1/3/2010"
4 1 0 3 "1/3/2010"
5 1 0 3 "1/3/2010"
6 0 1 -3 "1/5/2010"
7 0 1 -3 "1/5/2010"
8 1 0 2 "1/5/2010"
9 0 1 1 "1/7/2010"
end
// recode record
gen record = .
forvalues i = 1/2 {
replace record = `i' if record`i' == 1
}
drop record?
gen date = daily(sdate, "MDY")
format date %td
// drop duplicates
duplicates drop record value date , force
// gen daily sum by record (loop not required due to single variable structure)
bysort record (date): gen dailysum = sum(value)
li, sepby(record) noobs
产生
+----------------------------------------------------------+
| input value sdate record date dailysum |
|----------------------------------------------------------|
| 1 2 1/1/2010 1 01jan2010 2 |
| 3 3 1/3/2010 1 03jan2010 5 |
| 8 2 1/5/2010 1 05jan2010 7 |
|----------------------------------------------------------|
| 6 -3 1/5/2010 2 05jan2010 -3 |
| 9 1 1/7/2010 2 07jan2010 -2 |
+----------------------------------------------------------+
在第二个示例中,将值向下移动一个日期是一项简单的任务:
// shift the values down by one date
bysort record (date): gen dailysum2 = dailysum[_n-1]
在第一个示例中,以下内容应该有效:
forvalues i = 1/2 {
bys tag record`i' (date): gen record`i'dailysumshift = record`i'dailysum[_n-1] if tag == 1
}