2015-10-14 45 views
0
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 

的我有什么是我的数据每一个人是1如果他们参与该值的变量recordi一个MWE。我想为每个人创建一个变量,累积地将该天的价值与前一天的最终价值相加。留下以下输出。Stata的累积和重复记录

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 
} 

最后,我想用一个日期值下移所以record11/3/2010值将是值现在在1/1/2010

它不是压缩数据以根据日期和记录创建唯一记录并合并回来的选项(至少这是最后的手段,因为它是一个庞大而凌乱的数据集)。

+1

除了其他地方的详细解答之外,请注意指令“显式下标(使用_N和_n)”,它通常用于生成,不应该与egen一起使用“例如http://www.stata.com/help.cgi?egen你的语法恰好也是非法的,因为没有指定函数,但下标和'egen'不以任何方式混合。这是因为'egen'通常会临时排序,所以在计算过程中可能不会保持排序顺序。 –

回答

1

代码中的一些错误:

  • 失踪{forvalues线的末端
  • by date意味着你要正确对待每一个独特的日期为一组。你其实不需要这个。您想要sort date,然后通过record[i]运行您的代码(根据您的数据结构)。
  • (可能)更正常的方法是有一个名为record的字段等于1,2,...,在这种情况下,您只需编码bys record (date): ...(稍后)。
  • 请注意generate(不是egen)的sum()函数给出了累计和。

关于请求:通过在数据中进行重复观察而获得的结果并不清楚,也不清楚通过重复观测累计和得到的结果。为什么不只是duplicates drop [varlist]?或者,如果你需要保留所有的观察结果,我会假设标记独特的观察值可能更有用。

最后,“我想为每个人创建一个变量,累积地将该天的值与前一天的最终值相加,留下以下输出。” “不符”最后,我想将值减少一个日期,因此对于记录1,1/3/2010的值将是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 
} 
+0

这很好,但为了完整起见,您可以添加代码,以便将问题的值向下移动一个日期,如问题 – CJ12

+0

@ CJ12中所述:请参阅最终编辑。 –