Stata的流入/流出计数

时间:2015-10-12 15:58:52

标签: loops stata

我有以下数据

 id   pair_id   id_in     id_out       date
  1      1        2          3          1/1/2010
  2      1        2          3          1/2/2010
  3      1        3          2          1/3/2010
  4      1        3          2          1/5/2010
  5      1        3          2          1/7/2010
  6      2        2          1          1/2/2010
  7      3        1          3          1/5/2010
  8      2        1          2          1/7/2010

在任何给定的一行,我想知道从id_in角度看唯一对id_outid_in之间的流入/流出差异

例如,对于id_in == 2id_out == 3,它看起来如下(从id_in == 2的角度来看)

 id   pair_id   id_in     id_out       date            inflow_outflow
  1     1         2          3          1/1/2010             1
  2     1         2          3          1/2/2010             2
  3     1         3          2          1/3/2010             1
  4     1         3          2          1/5/2010             0
  5     1         3          2          1/7/2010            -1

解释。首先收到id_in == 2,然后他们获得+1,然后他们再次收到+2。然后他们放弃了所以它被-1缩小,使总数达到1等等。

这就是我试过的

sort pair_id id_in date 
gen count = 0
qui forval i = 2/`=_N' { 
    local I = `i' - 1 
    count if id_in == id_out[`i'] in 1/`I' 
    replace count = r(N) in `i' 
} 

2 个答案:

答案 0 :(得分:0)

我没有遵循这里的所有逻辑,特别是从一个成员的角度来呈现交易似乎很随意。但是来自松散相似问题的广泛印象是你不应该在这里考虑循环。使用by:和累计金额就足够了。有人试图在http://www.stata-journal.com/sjpdf.html?articlenum=dm0043处理如何处理对偶的系统讨论,但这只是一个开始。

请注意,根据某种显示格式显示日期是一个很小的痛苦,因为它们需要进行逆向工程。来自SSC的dataex可用于创建易于复制和粘贴的示例。

此代码可能会提示一些技巧:

clear 
input id   pair_id   id_in     id_out str8 sdate
  1      1        2          3          "1/1/2010"
  2      1        2          3          "1/2/2010"
  3      1        3          2          "1/3/2010"
  4      1        3          2          "1/5/2010"
  5      1        3          2          "1/7/2010"
  6      2        2          1          "1/2/2010"
  7      3        1          3          "1/5/2010"
  8      2        1          2          "1/7/2010" 
 end 
 gen date = daily(sdate, "MDY") 
 format date %td 
 assert id_in != id_out 
 gen pair1 = cond(id_in < id_out, id_in, id_out) 
 gen pair2 = cond(id_in < id_out, id_out, id_in) 
 bysort pair_id (date): gen sum1 = sum(id_in == pair1) - sum(id_out == pair1) 
 bysort pair_id (date): gen sum2 = sum(id_in == pair2) - sum(id_out == pair2) 

 list date id_* pair? sum?, sepby(pair_id) 

     +----------------------------------------------------------+
     |      date   id_in   id_out   pair1   pair2   sum1   sum2 |
     |----------------------------------------------------------|
  1. | 01jan2010       2        3       2       3      1     -1 |
  2. | 02jan2010       2        3       2       3      2     -2 |
  3. | 03jan2010       3        2       2       3      1     -1 |
  4. | 05jan2010       3        2       2       3      0      0 |
  5. | 07jan2010       3        2       2       3     -1      1 |
     |----------------------------------------------------------|
  6. | 02jan2010       2        1       1       2     -1      1 |
  7. | 07jan2010       1        2       1       2      0      0 |
     |----------------------------------------------------------|
  8. | 05jan2010       1        3       1       3      1     -1 |
     +----------------------------------------------------------+

答案 1 :(得分:0)

特定对(由pair_id定义)始终由两个实体组成,这两个实体可以以两种方式之一进行排序。例如,实体5与实体8,实体8与实体5.如果一个正在接收,另一个正在发出,必然

可以在下面找到两种略有不同的解决问题的方法。

clear all
set more off

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

input id   pair_id   id_in     id_out str8 sdate
1      1        2          3          "1/1/2010"
2      1        2          3          "1/2/2010"
3      1        3          2          "1/3/2010"
4      1        3          2          "1/5/2010"
5      1        3          2          "1/7/2010"
6      2        2          1          "1/2/2010"
7      3        1          3          "1/5/2010"
8      2        1          2          "1/7/2010" 
end 
gen date = daily(sdate, "MDY") 
format date %td 
drop sdate

sort pair_id date id
list, sepby(pair_id)

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

// approach 1
bysort pair_id (date id) : gen sum1 = sum(cond(id_in == id_in[1], 1, -1))
gen sum2 = -1 * sum1

// approach 2
bysort pair_id (id_in date id) : gen temp = cond(id_in == id_in[1], 1, -1)
bysort pair_id (date id) : gen sum100 = sum(temp)
gen sum200 = -1 * sum100

// list
drop temp
sort pair_id date
list, sepby(pair_id)

第一种方法涉及创建一个变量,该变量保存根据date变量首先接收的实体的差异。 sum1就是这么做的。变量sum2保存另一个实体的差异。

第二种方法创建一个变量,用于保存具有最小识别号的实体的差异。我把它命名为sum100。变量sum200保存另一个实体的信息。

请注意,如果id无法唯一标识观察结果,我会将pair_id date添加到排序列表中。

第二种方法相当于@NickCox提供的代码,或者我相信。

结果:

. list, sepby(pair_id)

     +---------------------------------------------------------------------------+
     | id   pair_id   id_in   id_out        date   sum1   sum2   sum100   sum200 |
     |---------------------------------------------------------------------------|
  1. |  1         1       2        3   01jan2010      1     -1        1       -1 |
  2. |  2         1       2        3   02jan2010      2     -2        2       -2 |
  3. |  3         1       3        2   03jan2010      1     -1        1       -1 |
  4. |  4         1       3        2   05jan2010      0      0        0        0 |
  5. |  5         1       3        2   07jan2010     -1      1       -1        1 |
     |---------------------------------------------------------------------------|
  6. |  6         2       2        1   02jan2010      1     -1       -1        1 |
  7. |  8         2       1        2   07jan2010      0      0        0        0 |
     |---------------------------------------------------------------------------|
  8. |  7         3       1        3   05jan2010      1     -1        1       -1 |
     +---------------------------------------------------------------------------+

仔细检查它们,因为两种方法之间的差异是微妙的,至少在最初阶段。