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:
和累计总和就足够了。有人试图对如何处理二元关系进行一些系统的讨论,但这只是一个开始
请注意,根据某些显示格式显示日期是一个小麻烦,因为它们需要反向工程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更新,我只知道这很不对劲