Расчет сумм условно по значениям данных - PullRequest
1 голос
/ 07 мая 2019

У меня довольно большой набор данных о конфликтах (71 миллион наблюдений) со многими переменными и датой (ежедневно).

Это из проекта 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 - переменная озабоченности, которая определяет степень враждебности или сотрудничества. Если число находится между 10 и 20, это событие враждебности, а 20 - более враждебное. Если число находится между 0 и 9, это указывает на сотрудничество (хорошее событие), при этом 9 является самым дружелюбным.

Мне удалось с помощью этой платформы выделить событие для каждой страны, а именно выделить коды камеи с участием определенного количества стран (я заинтересован в 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           

Всякий раз, когда данная страна участвует в качестве получателя или инициатора, я создаю новую переменную, изолирующую это конкретное событие и его интенсивность для данной даты.

Теперь я хочу создать стандартизированную меру или коэффициент, в котором для каждой даты сумма мер конфликта (числа от 10 до 20) делятся на на сумму мер сотрудничества (цифры от 1 до 9) для каждой страны.

Таким образом, мой желаемый результат для этой таблицы выше для AFG 20000101 (5-й столбец) будет:

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

Я хотел бы повторить это для каждой даты для каждой из переменных ind_COUNTRY CODE, чтобы иметь одно число в день для каждой страны.

Есть ли способ сделать это?

1 Ответ

2 голосов
/ 07 мая 2019

Кажется, это ключевой трюк, который вы ищете.

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 |
     +------------------------------------------------------------+

См. разделы 9 и 10 в этой статье для техники.Основная идея заключается в том, что многие функции egen допускают выражения в качестве аргументов, которые могут быть более сложными, чем просто имена переменных.Здесь мы используем cond(), чтобы указать, что только значения в определенных интервалах должны быть подсчитаны.

Менее прозрачный, но менее расточительный рецепт с точки зрения создания переменных будет запускать что-то вроде

egen wanted =! Код для числителя!

egen den =! Код для знаменателя!

replace wanted = wanted / den

drop den

...