Loops 以Stata为单位的流入/流出计数

Loops 以Stata为单位的流入/流出计数,loops,stata,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

我有以下数据

 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\u in
的角度知道唯一对
id\u in
id\u out
之间的流入/流出差是多少

 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\u in==2
id\u out==3
,它看起来如下所示(从
id\u in==2
s的角度)

解释
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:
和累计总和就足够了。有人试图对如何处理二元关系进行一些系统的讨论,但这只是一个开始

请注意,根据某些显示格式显示日期是一个小麻烦,因为它们需要反向工程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 |
     +----------------------------------------------------------+
清除
输入id对\u id\u输入id\u输出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" 
终止
发电日期=每日(sdate,“MDY”)
格式日期%td
在中断言id_!=我出去了
gen pair1=秒(id_输入
一个特定的对(如
pair\u 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)
第一种方法涉及创建一个变量,该变量根据
日期
变量保存首次接收的实体的差异
sum1
就是这样做的。变量
sum2
保存其他实体的差异

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

请注意,我在排序列表中添加了
id
,以防
pair\u 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 |
     +---------------------------------------------------------------------------+

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

这似乎不完整,因为您没有显示您尝试的Stata代码以及它产生的问题。如果您没有代码,您只需要计算一个差异和一个运行求和。请参阅
help gen
help sum()
。我同意@NickCox目前的情况,这是不完整的。@RobertoFerrer更新了,我只是知道这是非常有效的,然后这就是你所能得到的,但我个人的经验法则是,没有代码的问题越来越离题,我无法回答。否则任何人都可以在这里发布他们需要的Stata代码。我不认为这与论坛对专业和热心程序员所面临的代码问题的关注是一致的。@NickCox更新,我只知道这很不对劲