Inflow/Outflow 在 Stata 中计数

Inflow/Outflow Count in 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_inid_out 之间的 inflow/outflow 差异是什么

例如,对于 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' 
} 

我没有遵循这里的所有逻辑,特别是从一个成员的角度呈现交易似乎很武断。但是从松散相似的问题中得出的一个普遍印象是,您不应该在这里考虑循环。使用 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 |
     +----------------------------------------------------------+

特定对(由 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 |
     +---------------------------------------------------------------------------+

仔细检查它们,因为这两种方法之间的区别很细微,至少在最初是这样。