根据数据值有条件地计算总和

时间:2019-05-07 09:11:04

标签: loops if-statement sum stata

我有一个很大的冲突数据集(7100万个观测值),其中包含许多变量和日期(每天)。

这是来自GDELT项目的。每天都有一个目标国和一个进攻国。例如,在1 January 2000上,许多国家/地区对他人或自己进行了侵略行为。

它看起来像这样:

clear

input long date_01 str18 source_01 str19 target_01 str4 cameocode_01
20000101 "AFG"    "AFGGOV" "2" 
20000101 "AFG"    "AFGGOV" "8"
20000101 "AFG"    "ARE"    "3" 
20000101 "AFG"    "CVL"    "4" 
20000101 "AFG"    "GOV"    "10" 
20000101 "AFG"    "GOV"    "4" 
20000101 "AFGGOV" "kasUAF" "3"
20000101 "FRA"    "kasUAF" "8" 
20000101 "AFG"    "IGOUNO" "3" 
20000101 "AFG"    "IND"    "4" 
20000101 "AFG"    "IND"    "12"
20000102 "AFG"    "IND"    "19"  
end

变量date_01是一天,source_01是发起侵略的国家,target_01是受害者,cameocode_01是关注变量,它说明了敌对或合作。如果数字在1020之间,则表示是敌对事件,其中20更具敌意。如果数字介于09之间,则表示合作(好事件),其中9是最友好的。

我设法with help from this platform隔离每个国家的事件,即隔离涉及一定数量国家(我对30感兴趣)的客串代码,以跟踪其随着时间的冲突演变。

我做了以下事情:

foreach c in AFG IND ARE {
    generate ind_`c' = cameocode_01 if strmatch(source_01, "`c'") |  ///
                                       strmatch(target_01, "`c'")
}

这将产生所需的结果:

        date      source      target    cameocode   ind_AFG   ind_IND   ind_ARE

1.  20000101         AFG      AFGGOV            2         2                    
2.  20000101         AFG         IND            4         4         4           
3.  20000101         AFG      AFGGOV            8         8                     
4.  20000101         AFG         ARE            3         3        36       
5.  20000101         AFG         CVL            4         4                     
6.  20000101         AFG         GOV           10        10                      
7.  20000101         AFG         GOV            4         4                      
8.  20000101      AFGGOV      kasUAF            3                               
9.  20000101      AFGGOV      kasUAF            8                                
10. 20000101        AFG         IRQ            12        12                     
11. 20000102        AFG         IND            19        19        19           

无论何时以给定国家作为接受者或发起者,我都会创建一个新变量,以隔离特定事件及其在给定日期的强度。

我现在想做的是能够创建一个标准化的度量或比率,其中每个日期的冲突度量的 sum (从10到{{1}的数字})除以每个国家的合作措施的 sum (从201的数字)。

因此,我在上述表格中9(第5列)的期望输出为:

AFG 20000101

我想针对每个变量(12+19) / (2+4+8+3+4+4) 在每个日期重复此操作,以使每个国家/地区每天有一个数字。

有没有办法做到这一点?

1 个答案:

答案 0 :(得分:2)

这似乎是您寻求的关键技巧。

clear
input long date str6 source float cameocode
20000101 "AFG"     2
20000101 "AFG"     4
20000101 "AFG"     8
20000101 "AFG"     3
20000101 "AFG"     4
20000101 "AFG"    10
20000101 "AFG"     4
20000101 "AFGGOV"  3
20000101 "AFGGOV"  8
20000101 "AFG"    12
end

egen num = total(cond(cameocode >= 10, cameocode, .)), by(date source)

egen den = total(cond(cameocode < 10, cameocode, .)), by(date source)

generate wanted = num / den

sort date source

list, sepby(source)

     +------------------------------------------------------------+
     |     date   source   target   cameoc~e   num   den   wanted |
     |------------------------------------------------------------|
  1. | 20000101      AFG      IND          4    22    25      .88 |
  2. | 20000101      AFG      GOV          4    22    25      .88 |
  3. | 20000101      AFG   AFGGOV          2    22    25      .88 |
  4. | 20000101      AFG   AFGGOV          8    22    25      .88 |
  5. | 20000101      AFG      IRQ         12    22    25      .88 |
  6. | 20000101      AFG      GOV         10    22    25      .88 |
  7. | 20000101      AFG      CVL          4    22    25      .88 |
  8. | 20000101      AFG      ARE          3    22    25      .88 |
     |------------------------------------------------------------|
  9. | 20000101   AFGGOV   kasUAF          8     0    11        0 |
 10. | 20000101   AFGGOV   kasUAF          3     0    11        0 |
     +------------------------------------------------------------+

有关技术,请参见sections 9 and 10 in this paper。基本思想是,许多egen函数都允许将表达式作为参数,这比仅变量名更为复杂。在这里,我们使用cond()来指定应仅对特定时间间隔内的值求和。

在创建变量方面透明度较低但浪费较少的配方将运行

egen wanted =!分子代码!

egen den =!分母代码!

replace wanted = wanted / den

drop den