【问题标题】:Calculating sums conditionally on data values根据数据值有条件地计算总和
【发布时间】:2023-10-27 22:14:01
【问题描述】:

我有一个相当大的冲突数据集(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           

每当某个特定国家/地区作为接收者或发起者涉及时,我都会创建一个新变量来隔离该特定事件及其在给定日期的强度。

我现在想要做的是能够创建一个标准化的度量或比率,其中对于每个日期,冲突度量的总和(数字从1020)被划分以每个国家的合作措施的总和(编号从19)。

因此,对于上面的表格,我想要的 AFG 20000101(第 5 列)输出将是:

(12+19) / (2+4+8+3+4+4)

我想为每个变量ind_COUNTRY CODE 在每个日期重复此操作,以便每个国家/地区每天有一个数字。

有没有办法做到这一点?

【问题讨论】:

  • 这很有趣,但在解释您所寻求的方面可能会更短。
  • 这些日期可能对您有好处,但对于许多 Stata 目的而言,它们不适合。 generate betterdate = daily(string(date, "%8.0f"), "YMD") 后跟一个“格式”命令将为您提供更好的日期。
  • 请注意,尽管我们乐于提供帮助,但我们也希望看到您的代码尝试解决问题。
  • 我理解,但作为初学者,有时会感到沮丧。我从你那里学到了很多,为此我感谢你并感谢你的帮助。希望随着我变得更好,我需要的帮助会减少。

标签: loops if-statement sum stata


【解决方案1】:

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

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

【讨论】:

  • 我不介意。我只是在解释一个你可能会发现有用的技巧。但我认为在许多单独的变量中重复相同的信息是没有意义的。 date source target cameocode 中已经包含您想要的任何内容:我无法轻易想象 Stata 的用途,您需要将其复制到(数百个?)其他变量中。
  • 是因为我需要按国家/地区对它们进行回归,以便根据每个特定国家/地区的股票收益进行回归,但我认为这种方式将是一种将其拆分的简单方法。但是感谢您的技巧,我会进一步研究它。
  • 相同评论:您无需重复信息即可。