Vorbemerkungen

Dieses Dokument beschreibt die Vorprozessierung und explorative Analyse des Datensatzes, der unter srf.ch interaktiv visualisiert und unter diesem Link als CSV-Datei zum Download angeboten wird.

SRF Data legt Wert darauf, dass die Datenvorprozessierung und -Analyse nachvollzogen und überprüft werden kann. SRF Data glaubt an das Prinzip offener Daten, aber auch offener und nachvollziehbarer Methoden. Zum anderen soll es Dritten ermöglicht werden, auf dieser Vorarbeit aufzubauen und damit weitere Auswertungen oder Applikationen zu generieren.

Die Vorprozessierung und Analyse wurde im Statistikprogramm R vorgenommen. Die Endprodukte des verwendeten Scripts sind:

R-Script & Daten

Das zugrunde liegende Script sowie die prozessierten Daten können unter diesem Link heruntergeladen werden. Durch Ausführen von preprocessing.Rmd kann der hier beschriebene Prozess nachvollzogen und dieses Dokument generiert werden. Dabei werden Daten aus dem Ordner input eingelesen und Ergebnisse in den Ordner output geschrieben.

GitHub

Der Code für die vorliegende Datenprozessierung und die Visualisierung ist unter http://github.com/srfdata/2015-05-notrecht-ruestungsexporte zur freien Verwendung verfügbar.

Weitere Projekte

Code & Daten von SRF Data sind unter http://srfdata.github.io verfügbar.

Haftungsausschluss

Die veröffentlichten Informationen sind sorgfältig zusammengestellt, erheben aber keinen Anspruch auf Aktualität, Vollständigkeit oder Richtigkeit. Es wird keine Haftung übernommen für Schäden, die durch die Verwendung dieses Scripts oder der daraus gezogenen Informationen entstehen. Dies gilt ebenfalls für Inhalte Dritter, die über dieses Angebot zugänglich sind.

Datenbeschreibung

Es folgt eine Beschreibung des unter diesem Link vom Staatssekretariat für Wirtschaft (SECO) publizierten Datensatzes:

Attribut Typ Beschreibung
(Erste Spalte, keine Bezeichnung) Integer Identifikator, eindeutig.
GN Integer Geschäftsnummer in der Seco-Datenbank, zwei unterschiedliche Formate je nach Herkunfstdatei.
UnterGN Integer Durchnummerierung von Geschäften mit gleicher GN.
Datum Date Datum der Bewilligung im Format YYYY-MM-DD.
Land String Land, in das die Güter exportiert werden.
Wert Float Wert der Güter in Schweizer Franken.
Verzeichnis String Kürzel für Verzeichnis, siehe unten.
Signatur String Code, der die Kategorie/Art der gehandelten Güter kodiert, aufgeschlüsselt in Haupttyp, Untertyp, Zusatz, siehe Beispiel unten. Achtung: Es kann sein, dass ein Geschäft zwei Signaturen aufweist. Dann wird nur die erste zur Ermittelung der Teilsignaturen verwendet.
Haupttyp String Erste Hierarchiestufe der Signatur, entspricht Überkategorien in den einzelnen Verzeichnissen.
Untertyp String Zweite Hierarchiestufe der Signatur, entspricht Unterkategorien in den einzelnen Verzeichnissen.
Zusatz String Rest der Signatur.
Herkunftsdatei String Originaldatei auf der Website des SECO

Attribut Verzeichnis

Folgende Werte sind möglich:

  • 5.1: Güter die dem Waffengesetz unterliegen
  • 5.2: Zivile Sprengstoffe
  • ChKV: Chemikalien der Chemikalienkontrollverordnung
  • GKV: Güter des Anhangs 1 + 2 der Güterkontrollverordnung, sogenannte “Dual-Use-Güter”
  • ML (GKV): “Besondere militärische Güter”, ebenfalls Teil der GKV
  • unbekannt

Die in der Visualisierung mit hochgestellten Buchstaben referenzierte Zusammenfassung der Verzeichnisse (“Dual-Use-Güter”, “Besondere militärische Güter” und “Andere Güter”) wurde von SRF Data vorgenommen und ist unter output/verzeichnis_beschreibung.csv einsehbar.

Attribut Haupttyp

Die in der Visualisierung dargestellte “Kategorie” entspricht dem Haupttyp. Die Übersetzung von Haupttyp wurde von SRF Data basierend auf amtlichen Dokumenten (Verordnungen, Verzeichnisse) vorgenommen und ist unter output/signatures_verzeichnis_haupttyp_beschreibung.csv einsehbar.

Beispiel Signaturaufschlüsselung

GKV 6A002.c1 ergibt…

  • Haupttyp: 6 (“Sensoren und Laser”)
  • Untertyp: A (“Ausrüstungen, Baugruppen, Bestandteile”)
  • Zusatz: 002.c1

In der Gesamtheit: “Ausrüstung zur ‘direkten Bildwandlung’ mit eingebauten Bildverstärkerröhren” (gemäss Anhang 1 + 2 GKV, 2012).

Hinweis zu Mehrfachbewilligungen

Laut Aussage des SECO kann die veröffentlichte Bewilligungs-Datenbank Mehrfachbewilligungen enthalten. Gewisse Aufträge sind so umfassend, dass ihre Ausführung mehrere Jahre dauert. Weil eine Exportbewilligung aber nur ein Jahr gültig ist, tauchen in den Daten vereinzelt auch Geschäfte auf, die schon vor 2012 bewilligt wurden. Solche Mehrfachbewilligungen führen dazu, dass Aufträge in der Statistik mehrfach vorkommen können.

Vom SECO wurde SRF Data eine Liste mit Geschäften übergeben, die schon vor 2012 erstmals bewilligt wurden und ihren Weg wiederum in die Datenbank fanden. Es handelt sich um folgende Geschäftsnummern:

Geschäftsnummer Beschreibung Auftragsvolumen
8001226 (ELIC) Flugzeuge und Simulatoren nach Indien rund 155 Mio. CHF
14476 Flugzeuge nach Indien rund 165 Mio. CHF
16043 Flugzeuge nach Indien rund 80 Mio. CHF
12332 Flugzeuge nach Saudi-Arabien rund 1 Mia. CHF
8001302 (ELIC) Simulatoren nach Katar rund 345 Mio. CHF

Vorbereitungen

Packages installieren

if(!require(dplyr)) {
  install.packages("dplyr", repos="http://cran.us.r-project.org")
  require(dplyr)
}
## Loading required package: dplyr
## 
## Attaching package: 'dplyr'
## 
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## 
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
if(!require(tidyr)) {
  install.packages("tidyr", repos="http://cran.us.r-project.org")
  require(tidyr)
}
## Loading required package: tidyr
if(!require(ggplot2)) {
  install.packages("ggplot2", repos="http://cran.us.r-project.org")
  require(ggplot2)
}
## Loading required package: ggplot2
if(!require(xlsx)) {
  install.packages("xlsx", repos="http://cran.us.r-project.org")
  require(xlsx)
}
## Loading required package: xlsx
## Loading required package: rJava
## Loading required package: xlsxjars

Sonstige Optionen und eigene Sourcen (Hilfsdateien)

require(scales)
## Loading required package: scales
options(scipen = 999)
# Funktion zur Klassifikation von Signaturen
source("classify.r")
# Funktion zum Formatieren von Zahlen
source("numberFormatter.r")

Datenquellen

Im folgenden werden zwei Rohdatensätze verwendet, die ursprünglich als XLS vorliegen .

Eine Datenbeschreibung der Rohdaten findet sich hier.

Vorprozessierung

Daten reinladen und typisieren

# Die Dateien können leider nicht automatisch heruntergeladen werden. Es wird vorausgesetzt, dass sich die beiden Files tracker.xlsx und elic.xlsx im Ordner input befinden. Die beiden Dateien können über die Links oben bezogen werden.
# ACHTUNG: Das Reinladen der XLSX-Dateien dauert seine Zeit...
tracker_raw <- read.xlsx(file = "input/tracker.xlsx", sheetIndex = 1, colClasses = "character", stringsAsFactors = F)
# Spaltentypen setzen und umbenennen
tracker_raw <- tracker_raw %>%
  mutate(Bewilligungsdatum = as.Date(Bewilligungsdatum, "%Y-%m-%d"), Geschäftsnummer = as.integer(Geschäftsnummer), Wert = as.numeric(Wert)) %>%
  rename(GN = Geschäftsnummer, Datum = Bewilligungsdatum, Land = Endverbraucherland)

# überprüfen
str(tracker_raw)
## 'data.frame':    4718 obs. of  14 variables:
##  $ GN         : int  11738 11746 11747 11747 11747 11747 11748 11693 11710 11749 ...
##  $ Datum      : Date, format: "2012-01-04" "2012-01-04" ...
##  $ Land       : chr  "China" "China" "Thailand" "Thailand" ...
##  $ AG..GKV.   : chr  NA NA NA NA ...
##  $ MTCR..GKV. : chr  NA NA NA NA ...
##  $ NSGI..GKV. : chr  NA NA NA NA ...
##  $ NSGII..GKV.: chr  "2B201b" "2B201a1" NA NA ...
##  $ WA..GKV.   : chr  "2B001c" "2B001b2" NA NA ...
##  $ ML..GKV.   : chr  NA NA NA NA ...
##  $ Anhang.5.1 : num  NA NA 5.1 5.1 5.1 5.1 NA NA NA NA ...
##  $ Anhang.5.2 : num  NA NA NA NA NA NA NA NA NA NA ...
##  $ Anhang.5.3 : logi  NA NA NA NA NA NA ...
##  $ ChKV       : chr  NA NA NA NA ...
##  $ Wert       : num  492552 341164 7616 6241 1174 ...
elic_raw <- read.xlsx(file = "input/elic.xlsx", sheetIndex = 1, colClasses = "character", stringsAsFactors = F)
# Spaltentypen setzen und umbenennen
elic_raw <- elic_raw %>%
  mutate(Ausstellungsdatum = as.Date(Ausstellungsdatum, "%d.%m.%Y"), Geschäftsnummer = as.integer(Geschäftsnummer), Position...Wert..CHF. = as.numeric(Position...Wert..CHF.)) %>%
  rename(GN = Geschäftsnummer, Datum = Ausstellungsdatum, Land = Bestimmungs..Lieferland, Wert = Position...Wert..CHF.)

# überprüfen
str(elic_raw)
## 'data.frame':    873 obs. of  6 variables:
##  $ GN                 : int  8000002 8000004 8000009 8000012 8000010 8000013 8000016 8000015 8000026 8000024 ...
##  $ Datum              : Date, format: "2014-02-07" "2014-02-11" ...
##  $ Land               : chr  "China, Volksrepublik" "Russische Föderation" "Singapur" "Slowenien" ...
##  $ Position...Güterart: chr  "Dual Use Güter" "Dual Use Güter" "Dual Use Güter\nDual Use Güter" "Besondere militärische Güter" ...
##  $ Position...EKN     : chr  "2B120" "6A002.c1" "2B001.b1\n2B201.a1" "ML15" ...
##  $ Wert               : num  1950000 2098305 209609 128000 43188 ...

Duplikate

Duplikate: Mehrere Einträge unter der gleichen Geschäftsnummer

Wie viele “Duplikate” gibt es?

dim(tracker_raw)[1] - dim(distinct(select(tracker_raw, GN)))[1]
## [1] 374
dim(elic_raw)[1] - dim(distinct(select(elic_raw, GN)))[1]
## [1] 238

Diese werden nicht aggregiert sondern so belassen, jedoch durchnummiert (Generierung neue Spalte UnterGN)

tracker_summarized <- tracker_raw %>%
  group_by(GN, Datum, Land) %>%
  mutate(UnterGN = row_number())
elic_summarized <- elic_raw %>%
  group_by(GN, Datum, Land) %>%
  mutate(UnterGN = row_number())

Wie viele Einträge haben in der Tracker-Applikation zwei Signaturen?

dim(filter(tracker_summarized, NSGII..GKV. != "", WA..GKV. != ""))[1]
## [1] 757

Wie viele davon sind solche, die mit der gleichen Obersignatur (sprich: dem gleichen Haupt- und Untertyp, siehe unten) beginnen?

dim(filter(tracker_summarized, NSGII..GKV. != "", WA..GKV. != "", substr(NSGII..GKV.,1,2) == substr(WA..GKV.,1,2)))[1]
## [1] 757

Wie viele Geschäfte haben keine Signatur?

tracker_without_signature <- tracker_summarized %>% 
  gather(Variable, Value, AG..GKV.:ChKV) %>% 
  group_by(GN, Datum, Land, UnterGN) %>%
  filter(all(is.na(Value) | Value == "NA")) %>% 
  slice(1)
dim(tracker_without_signature)[1]
## [1] 99

ELIC?

dim(elic_summarized[elic_summarized$Position...EKN == "",])[1]
## [1] 0

Restrukturieren

# ELIC: Umbenennen und Spalte hinzufügen
elic_restructured <- elic_summarized %>%
  rename(Signatur = Position...EKN, "Verordnung/Typ ELIC" = Position...Güterart) %>%
  mutate("Verordnung/Typ" = NA)

# Tracker: Kondensieren (breit nach lang)
tracker_restructured <- tracker_summarized %>% 
  gather(Variable, Value, AG..GKV.:ChKV) %>%                          # breit nach lang
  group_by(GN, Datum, Land, UnterGN) %>% 
  filter(if(all(is.na(Value) | Value == "NA")) row_number() == 1 else (!is.na(Value) | Value == "NA")) %>% # wenn Geschäft gar keine Signatur hat, dann nur den ersten nehmen, sonst alle nehmen, die einen Wert haben (für solche, die mehr als eine Signatur haben)
  summarise_each(funs(paste(unique(.), collapse = "\n")))  %>%        # alle eindeutigen Werte pro Gruppe mit einem newline-Operator zusammenfügen
  mutate(Wert = as.numeric(Wert))                                     # Wert muss numerisch sein

# Tracker: Einträge, für die keine Signatur bekannt ist, umbenennen, und eine leere Spalte für Kombination mit ELIC hinzufügen, sowie Spalten umbennenen
tracker_restructured <- tracker_restructured %>%
  mutate(Variable = ifelse(is.na(Value) | Value == "NA","unbekannt", Variable), Value = ifelse(is.na(Value) | Value == "NA","unbekannt", Value), "Verordnung/Typ ELIC" = NA) %>%
  rename("Verordnung/Typ" = Variable, "Signatur" = Value)

Zwischenbilanz

str(as.data.frame(elic_restructured))
## 'data.frame':    873 obs. of  8 variables:
##  $ GN                 : int  8000002 8000004 8000009 8000012 8000010 8000013 8000016 8000015 8000026 8000024 ...
##  $ Datum              : Date, format: "2014-02-07" "2014-02-11" ...
##  $ Land               : chr  "China, Volksrepublik" "Russische Föderation" "Singapur" "Slowenien" ...
##  $ Verordnung/Typ ELIC: chr  "Dual Use Güter" "Dual Use Güter" "Dual Use Güter\nDual Use Güter" "Besondere militärische Güter" ...
##  $ Signatur           : chr  "2B120" "6A002.c1" "2B001.b1\n2B201.a1" "ML15" ...
##  $ Wert               : num  1950000 2098305 209609 128000 43188 ...
##  $ UnterGN            : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Verordnung/Typ     : logi  NA NA NA NA NA NA ...
str(as.data.frame(tracker_restructured))
## 'data.frame':    4718 obs. of  8 variables:
##  $ GN                 : int  10263 11180 11435 11435 11663 11666 11667 11671 11693 11710 ...
##  $ Datum              : Date, format: "2012-03-22" "2012-05-25" ...
##  $ Land               : chr  "Iran, Islamische Republik (SG)" "China" "Gabun" "Gabun" ...
##  $ UnterGN            : int  1 1 1 2 1 1 1 1 1 1 ...
##  $ Wert               : num  1790 550000 650 4200 158000 ...
##  $ Verordnung/Typ     : chr  "unbekannt" "NSGI..GKV." "Anhang.5.1" "Anhang.5.1" ...
##  $ Signatur           : chr  "unbekannt" "0B001b14" "5.1" "5.1" ...
##  $ Verordnung/Typ ELIC: logi  NA NA NA NA NA NA ...

Beide Datensätze kombinieren

seco_dual_use <- rbind(as.data.frame(elic_restructured), as.data.frame(tracker_restructured))
str(seco_dual_use)
## 'data.frame':    5591 obs. of  8 variables:
##  $ GN                 : int  8000002 8000004 8000009 8000012 8000010 8000013 8000016 8000015 8000026 8000024 ...
##  $ Datum              : Date, format: "2014-02-07" "2014-02-11" ...
##  $ Land               : chr  "China, Volksrepublik" "Russische Föderation" "Singapur" "Slowenien" ...
##  $ Verordnung/Typ ELIC: chr  "Dual Use Güter" "Dual Use Güter" "Dual Use Güter\nDual Use Güter" "Besondere militärische Güter" ...
##  $ Signatur           : chr  "2B120" "6A002.c1" "2B001.b1\n2B201.a1" "ML15" ...
##  $ Wert               : num  1950000 2098305 209609 128000 43188 ...
##  $ UnterGN            : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ Verordnung/Typ     : chr  NA NA NA NA ...

Länder-Duplikate entfernen

Wie viele Länder gibt es?

laender <- arrange(seco_dual_use, Land)
# unique(laender$Land) # der Lesbarkeit halber auskommentiert
length(unique(laender$Land))
## [1] 150

Manuell umschreiben gemäss SRF-Länderliste, und falls dort nicht spezifiziert, gemäss NZZ-Vademecum

seco_dual_use$Land[seco_dual_use$Land == "Bosnien und Herzegowina"] <- "Bosnien-Herzegowina"
seco_dual_use$Land[seco_dual_use$Land == "Pakistan (CA)"] <- "Pakistan"
seco_dual_use$Land[seco_dual_use$Land == "Indien (CA)"] <- "Indien"
seco_dual_use$Land[seco_dual_use$Land == "China, Taiwan"] <- "Taiwan"
seco_dual_use$Land[seco_dual_use$Land == "China, Volksrepublik"] <- "China"
seco_dual_use$Land[seco_dual_use$Land == "Ekuador"] <- "Ecuador"
seco_dual_use$Land[seco_dual_use$Land == "Großbritannien (Vereinigtes Königreich)"] <- "Grossbritannien"
seco_dual_use$Land[seco_dual_use$Land == "Hongkong"] <- "Hong Kong"
seco_dual_use$Land[seco_dual_use$Land == "Iran, Islamische Republik"] <- "Iran"
seco_dual_use$Land[seco_dual_use$Land == "Iran, Islamische Republik (SG)"] <- "Iran"
seco_dual_use$Land[seco_dual_use$Land == "Myanmar (Union)"] <- "Myanmar (Birma)"
seco_dual_use$Land[seco_dual_use$Land == "Qatar"] <- "Katar"
seco_dual_use$Land[seco_dual_use$Land == "Serbia"] <- "Serbien"
seco_dual_use$Land[seco_dual_use$Land == "Slowakei, Slowakische Republik"] <- "Slowakische Republik"
seco_dual_use$Land[seco_dual_use$Land == "Taiwan, Provinz von China"] <- "Taiwan"
seco_dual_use$Land[seco_dual_use$Land == "Vereinigte Staaten"] <- "Vereinigte Staaten von Amerika"
seco_dual_use$Land[seco_dual_use$Land == "Libysch-Arabische Dschamahirija"] <- "Libyen"
seco_dual_use$Land[seco_dual_use$Land == "Russische Föderation"] <- "Russland"
seco_dual_use$Land[seco_dual_use$Land == "Belarus"] <- "Weissrussland"
seco_dual_use$Land[seco_dual_use$Land == "Bangladesch"] <- "Bangladesh"
seco_dual_use$Land[seco_dual_use$Land == "Bermuda"] <- "Bermudas"
seco_dual_use$Land[seco_dual_use$Land == "Brunei Darussalam"] <- "Brunei"
seco_dual_use$Land[seco_dual_use$Land == "Demokratische Republik Kongo"] <- "Kongo-Kinshasa"
seco_dual_use$Land[seco_dual_use$Land == "Kongo, Demokratische Republik (ex-Zaire)"] <- "Kongo-Kinshasa"
seco_dual_use$Land[seco_dual_use$Land == "Cayman-Inseln"] <- "Kaiman-Inseln"
seco_dual_use$Land[seco_dual_use$Land == "Korea, Republik"] <- "Südkorea"
seco_dual_use$Land[seco_dual_use$Land == "Kroatien (Hrvatska)"] <- "Kroatien"
seco_dual_use$Land[seco_dual_use$Land == "Laos, Demokratische Volksrepublik"] <- "Laos"
seco_dual_use$Land[seco_dual_use$Land == "Macao"] <- "Macau"
seco_dual_use$Land[seco_dual_use$Land == "Mazedonien, die ehemalige jugoslawische Republik"] <- "Mazedonien"
seco_dual_use$Land[seco_dual_use$Land == "Myanmar (Birma)"] <- "Myanmar"
seco_dual_use$Land[seco_dual_use$Land == "Slowakische Republik"] <- "Slowakei"
seco_dual_use$Land[seco_dual_use$Land == "Tansania, Vereinigte Republik"] <- "Tansania"
seco_dual_use$Land[seco_dual_use$Land == "Tschechische Republik"] <- "Tschechien"
seco_dual_use$Land[seco_dual_use$Land == "Vereinigte Staaten von Amerika"] <- "USA"

Wie viele Länder gibt es jetzt noch?

length(unique(seco_dual_use$Land))
## [1] 135

Kategorisierung

Neue Spalten erstellen

# Spalte für Dateiherkunft
seco_dual_use <- seco_dual_use %>%
  mutate(Herkunftsdatei = NA, Verzeichnis = NA, Haupttyp = NA, Untertyp = NA, Zusatz = NA)

Signaturaufschlüsselung

# Verzeichnis fin
computedList <- mapply(classifyVerzeichnis, seco_dual_use[,"Verordnung/Typ"], seco_dual_use[,"Verordnung/Typ ELIC"], seco_dual_use[,"Signatur"])

seco_dual_use <- seco_dual_use  %>% 
  mutate(Verzeichnis = as.factor(t(computedList)[,1]), Herkunftsdatei = as.factor(t(computedList)[,2]))

# Verordnung/Typ (ELIC) werden nicht mehr gebraucht
seco_dual_use <- seco_dual_use  %>% 
  select(-contains("Verordnung/Typ"))

# Signatur aufschlüsseln
# nur GVK anzeigen
seco_dual_use_only_gkv <- seco_dual_use  %>% 
  filter(Verzeichnis == "GKV") %>%
  select(Signatur, Herkunftsdatei)

computedList <- mapply(classifySignatur, seco_dual_use[,"Verzeichnis"], seco_dual_use[,"Herkunftsdatei"], seco_dual_use[,"Signatur"])

seco_dual_use_cleaned <- seco_dual_use  %>% 
  mutate(Haupttyp = as.factor(t(computedList)[,1]), Untertyp = as.factor(t(computedList)[,2]), Zusatz = as.factor(t(computedList)[,3]))

# Sample nehmen, um Klassifikation zu überprüfen
seco_dual_use_cleaned  %>% 
  sample_n(40) %>%
  select(Verzeichnis, Signatur, Haupttyp, Untertyp, Zusatz)
##      Verzeichnis             Signatur Haupttyp Untertyp  Zusatz
## 697          GKV             3A001.g2        3        A   001g2
## 3663         GKV              2B350g2        2        B   350g2
## 216          GKV 2B001.b.2\n2B201.a.1        2        B   001b2
## 4920         GKV     2B201a1\n2B001b2        2        B   201a1
## 192     ML (GKV)                 ML03        3     <NA>    <NA>
## 1988         GKV             3A001a2c        3        A  001a2c
## 2913         GKV            6A005a6b2        6        A 005a6b2
## 2388         GKV             3A001a2c        3        A  001a2c
## 3103         GKV     2B201a1\n2B001b2        2        B   201a1
## 3020         GKV               5A001i        5        A    001i
## 3502         GKV     2B201a1\n2B001b2        2        B   201a1
## 1823    ML (GKV)                   3a        3        a    <NA>
## 5254         GKV              3A001g2        3        A   001g2
## 2471         GKV     2B201a1\n2B001b2        2        B   201a1
## 3595    ML (GKV)                   5d        5        d    <NA>
## 624    unbekannt           III.A1.003     <NA>     <NA>    <NA>
## 3808         GKV              6A002c1        6        A   002c1
## 2712         GKV              6A002c1        6        A   002c1
## 1627    ML (GKV)                  10g       10        g    <NA>
## 2158         GKV               2B001a        2        B    001a
## 2633    ML (GKV)                   1a        1        a    <NA>
## 436          GKV   2B001.b2\n2B201.a1        2        B   001b2
## 3950         GKV            6A005a6b2        6        A 005a6b2
## 3274         GKV               2B001a        2        B    001a
## 4866         GKV               2B350i        2        B    350i
## 1906         GKV             3A001a2c        3        A  001a2c
## 4008         GKV            6A005a6b2        6        A 005a6b2
## 4487         GKV                2B204        2        B     204
## 509          GKV             2B001.b3        2        B   001b3
## 619     ML (GKV)                 ML06        6     <NA>    <NA>
## 1211         GKV              6A002c1        6        A   002c1
## 2748         GKV             3A001a2c        3        A  001a2c
## 396          GKV              2B001.a        2        B    001a
## 2965         GKV               2B201b        2        B    201b
## 2469         GKV               3A228c        3        A    228c
## 5007         GKV              2B350g2        2        B   350g2
## 3936         GKV       2B201a\n2B001b        2        B    201a
## 2340   unbekannt            unbekannt     <NA>     <NA>    <NA>
## 4431         GKV               2B001a        2        B    001a
## 4009         GKV              3A002g2        3        A   002g2
# Faktorenlevels überprüfen
levels(seco_dual_use_cleaned$Verzeichnis)
## [1] "5.1"       "5.2"       "ChKV"      "GKV"       "ML (GKV)"  "unbekannt"
levels(seco_dual_use_cleaned$Herkunftsdatei)
## [1] "ELIC"    "Tracker"
# Hier gibt es Einträge à la 1A, 2B und 3B, dies sind keine Fehler, sondern Haupttypen der ChKV
levels(seco_dual_use_cleaned$Haupttyp)
##  [1] "0"  "1"  "10" "11" "13" "14" "15" "16" "17" "18" "1A" "2"  "21" "22"
## [15] "2B" "3"  "3B" "4"  "5"  "6"  "7"  "8"  "9"
levels(seco_dual_use_cleaned$Untertyp)
##  [1] ""    "0"   "10"  "14"  "16"  "17"  "3"   "4"   "a"   ".a"  "A"  
## [12] "a21" "b"   "B"   "b4"  "c"   "C"   "c2"  "d"   "D"   "E"   "f"  
## [23] "f1"  "g"   "h"
levels(seco_dual_use_cleaned$Zusatz)
##   [1] ""            "0"           "001"         "001a"        "001a1"      
##   [6] "001a10c"     "001a12"      "001a13b"     "001a2a"      "001a2c"     
##  [11] "001A2C"      "001a5a1"     "001a5a2"     "001A5A2"     "001a5a3"    
##  [16] "001A5A4"     "001a5a5"     "001a7a"      "001a7b"      "001b"       
##  [21] "001b1"       "001b10"      "001b14"      "001b2"       "001B2"      
##  [26] "001b3"       "001c"        "001C"        "001c1"       "001c2"      
##  [31] "001d"        "001e"        "001f"        "001g"        "001g2"      
##  [36] "001h"        "001i"        "001j"        "002"         "002a"       
##  [41] "002a1"       "002a1a"      "002a1b3"     "002a1d"      "002a2a"     
##  [46] "002a3f"      "002a3g"      "002a9"       "002a+b"      "002b1"      
##  [51] "002c1"       "002c2"       "002g"        "002g2"       "002G2"      
##  [56] "003"         "003a"        "003b4"       "003c1"       "003f2"      
##  [61] "004a"        "005"         "005a5b"      "005a6a"      "005A6A"     
##  [66] "005a6b"      "005a6b2"     "005A6B2"     "005b6a2"     "005b8b"     
##  [71] "005d1"       "005e"        "006a"        "006b"        "008c"       
##  [76] "008d"        "010b"        "012a1"       "012a2"       "101"        
##  [81] "101a"        "103a"        "103a1"       "105"         "105b1"      
##  [86] "108b2"       "110"         "111a2c"      "117"         "120"        
##  [91] "120a"        "122"         "201"         "201a"        "201a1"      
##  [96] "201a2"       "201b"        "201b1"       "201b2"       "202"        
## [101] "203b3"       "204"         "210b"        "225"         "226"        
## [106] "228"         "228c"        "230"         "231"         "231a"       
## [111] "231b"        "231b2"       "233"         "233a"        "235"        
## [116] "350"         "35009"       "35013"       "35014"       "35043"      
## [121] "35046"       "3504g"       "3509"        "350a3"       "350a4"      
## [126] "350a,b,d,g3" "350b3"       "350c"        "350c3"       "350d1"      
## [131] "350d2, 3, 9" "350d3"       "350d4"       "350d5"       "350e"       
## [136] "350e1"       "350e2"       "350e3"       "350e5"       "350e7"      
## [141] "350g"        "350G"        "350g2"       "350G2"       "350g3"      
## [146] "350g4"       "350g9c"      "350h2"       "350i"        "350i1"      
## [151] "350i3"       "350i4"       "350i7"       "351"         "351d11"     
## [156] "351d15"      "351d4"       "352"         "352b"        "352c"       
## [161] "352d"        "352d2"       "352e"        "352f"

Plausibilitätsüberprüfungen

Was sind die kleinsten Einträge auf der Liste, das heisst: Wie viele Geschäfte im Wert von 1 Franken gibt es? Wie viele Geschäfte unter 1’000 Franken gibt es? Wie viele Geschäfte unter 10’000 Franken gibt es? Wie viele Geschäfte unter 100’000 Franken gibt es?

dim(seco_dual_use_cleaned[seco_dual_use_cleaned$Wert == 1,])[1]
## [1] 66
dim(seco_dual_use_cleaned[seco_dual_use_cleaned$Wert <= 1000,])[1]
## [1] 461
dim(seco_dual_use_cleaned[seco_dual_use_cleaned$Wert <= 10000,])[1]
## [1] 1671
dim(seco_dual_use_cleaned[seco_dual_use_cleaned$Wert <= 100000,])[1]
## [1] 3028

Output als CSV

# Spalten neu ordnen
seco_dual_use_cleaned <- seco_dual_use_cleaned %>%
  select(GN, UnterGN, Datum, Land, Wert, Verzeichnis, Signatur, Haupttyp, Untertyp, Zusatz, Herkunftsdatei)
# \n durch | ersetzen in Signatur
seco_dual_use_cleaned_for_output <- seco_dual_use_cleaned %>%
  mutate(Signatur = sub("\\n", "|", Signatur)) %>%
  mutate(Untertyp = ifelse(is.na(Untertyp), "", as.character(Untertyp))) %>%
  mutate(Haupttyp = ifelse(is.na(Haupttyp), "", as.character(Haupttyp))) %>%
  mutate(Zusatz = ifelse(is.na(Zusatz), "", as.character(Zusatz)))
write.csv(seco_dual_use_cleaned_for_output, file = "output/seco_dual_use.csv")

# Output für Visualisierung
# Benötigt: Datum, Land, Wert, Verzeichnis, Haupttyp
seco_dual_use_for_vis <- seco_dual_use_cleaned %>%
  select(Datum, Land, Wert, Verzeichnis, Haupttyp) %>%
  mutate(Haupttyp = as.character(Haupttyp))
# Chemikalien zusammenfassen
seco_dual_use_for_vis$Haupttyp[seco_dual_use_for_vis$Verzeichnis == "ChKV"] <- "0"
# NAs durch leere Strings ersetzen
seco_dual_use_for_vis$Haupttyp[is.na(seco_dual_use_for_vis$Haupttyp)] <- ""
write.csv(seco_dual_use_for_vis, file = "output/seco_dual_use_for_vis.csv", row.names = F, quote = c(1, 2, 4, 5))

Output aller unterschiedlichen Signaturen als CSV

write.csv(data.frame(signatures = unique(paste(seco_dual_use_cleaned$Verzeichnis, seco_dual_use_cleaned$Haupttyp, seco_dual_use_cleaned$Untertyp, seco_dual_use_cleaned$Zusatz))), "output/all_signatures.csv")

Output aller unterschiedlichen Verzeichnis-Haupttyp-Kategorien zur manuellen Beschreibung

only_top_category_signatures <- seco_dual_use_cleaned %>%
  select(Verzeichnis, Haupttyp) %>%
  distinct() %>%
  mutate(Beschreibung = "", Haupttyp = as.character(Haupttyp)) %>%
  arrange(Verzeichnis, Haupttyp)
write.csv(only_top_category_signatures, "output/signatures_verzeichnis_haupttyp.csv", row.names = F)

Analyse

Generelles

Wie sieht die Verteilung aus?

cdf <- ggplot(seco_dual_use_cleaned, aes(x = Wert)) + stat_ecdf() + scale_x_log10(labels = formatAsChfWithoutCHF) + scale_y_continuous(labels = percent)
cdf

Wie viel Prozent des Exportvolumens sind Kleinaufträge oder Exporte zu Testzwecken (Definition gemäss SECO: Geschäfte mit einem Wert von unter 10’000 Franken)?

seco_dual_use %>%
  group_by("Unter 10'000" = Wert < 10000, "Zwischen 10'000 und 100'000" = Wert < 100000 & Wert >= 10000, "Zwischen 100'000 und 1 Mio." = Wert >= 100000 & Wert < 1000000, "Zwischen 1 Mio. und 10 Mio." = Wert >= 1000000 & Wert < 10000000, "Über 10 Mio." = Wert >= 10000000) %>%
  summarise(Summe = sum(Wert), Anzahl = n()) %>%
  mutate(Summenanteil = Summe / sum(seco_dual_use_cleaned$Wert)) %>%
  gather(Kategorie, Value, -Summe, -Summenanteil, -Anzahl) %>%
  filter(Value == T) %>%
  select(-Value)
## Source: local data frame [5 x 4]
## 
##        Summe Anzahl Summenanteil                   Kategorie
## 1    5531952   1658   0.00138238                Unter 10'000
## 2   51901310   1364   0.01296962 Zwischen 10'000 und 100'000
## 3  805639175   2181   0.20132125 Zwischen 100'000 und 1 Mio.
## 4  820265810    358   0.20497630 Zwischen 1 Mio. und 10 Mio.
## 5 2318420939     30   0.57935044                Über 10 Mio.
# Sonstige Kennzahlen

seco_dual_use %>%
  summarise(median = formatAsChf(median(Wert)), sd = formatAsChf(sd(Wert)), mean = formatAsChf(mean(Wert)))
##         median               sd            mean
## 1 CHF 66'480.- CHF 14'371'491.- CHF 715'750.2.-

Es zeigt sich klar, dass Exporte mit kleinen Summen nur einen verschwindend kleinen Teil des gesamten Exportvolumens ausmachen (< 2 Prozent). Exporte zu Testzwecken oder temporäre Exporte fallen bei der nachfolgenden Analyse rein rechnerisch also nicht ins Gewicht. Geschäfte mit einem Handelswert von über 10 Mio. sind für rund 60 Prozent des Exportvolumens verantwortlich.

Exporte im Wert von wie vielen Franken wurden im untersuchten Zeitraum bewilligt?

formatAsChf(sum(seco_dual_use_cleaned$Wert))
## [1] "CHF 4'001'759'186.-"

Was sind die grössten Exporte auf der Liste?

arrange(seco_dual_use_cleaned, desc(Wert)) %>%
  mutate(Wert = formatAsChf(Wert)) %>%
  select(GN, Land, Verzeichnis, Datum, Wert) %>%
  slice(1:10) 
##         GN          Land Verzeichnis      Datum                   Wert
## 1    12332 Saudi-Arabien    ML (GKV) 2012-04-27 CHF 1'000'000'000.00.-
## 2  8001302         Katar    ML (GKV) 2014-12-17 CHF   275'000'000.00.-
## 3    14476        Indien    ML (GKV) 2013-07-26 CHF   165'000'000.00.-
## 4  8001226        Indien    ML (GKV) 2014-12-15 CHF   135'100'000.00.-
## 5    16043        Indien    ML (GKV) 2014-08-22 CHF    80'000'000.00.-
## 6    14466      Pakistan    ML (GKV) 2013-08-14 CHF    73'621'900.00.-
## 7  8001302         Katar    ML (GKV) 2014-12-17 CHF    70'000'000.00.-
## 8    15555     Jordanien    ML (GKV) 2014-05-06 CHF    65'000'000.00.-
## 9    15586         China         GKV 2014-05-01 CHF    51'150'000.00.-
## 10   12153        Indien   unbekannt 2012-03-21 CHF    40'000'000.00.-

Mit welchen 10 Ländern wird am meisten gehandelt?

laenderSummen10Sortiert <- seco_dual_use_cleaned %>%
  group_by(Land) %>%
  summarise(Wert = sum(Wert)) %>%
  arrange(desc(Wert)) %>%
  slice(1:10)
laenderAndere <- seco_dual_use_cleaned %>%
  group_by(Land) %>%
  summarise(Wert = sum(Wert)) %>%
  arrange(desc(Wert)) %>%
  slice(11:n()) %>%
  summarise(Land = "Andere", Wert = sum(Wert))

# Summe der sonstigen

laenderSummen10SortiertForBar <- rbind(laenderSummen10Sortiert, laenderAndere) %>%
  mutate(Land = factor(Land, levels = c(laenderSummen10Sortiert$Land, laenderAndere$Land))) # in die richtige Reihenfolge bringen

laenderSummenBar <- ggplot(data = laenderSummen10SortiertForBar, aes(x = Land, y = Wert)) + 
  geom_bar(stat = "identity") + 
  scale_y_continuous(labels = formatAsChf) + 
  xlab("Land") +
  theme(axis.text.x = element_text(angle=45, vjust=0.5))
laenderSummenBar

Wie viel Prozent des Exportvolumens fallen auf die 5 Länder mit dem grössten bewilligten Exportvolumen?

laenderSummen5Sortiert <- seco_dual_use_cleaned %>%
  group_by(Land) %>%
  summarise(Wert = sum(Wert)) %>%
  arrange(desc(Wert)) %>%
  slice(1:5)
sum(laenderSummen5Sortiert$Wert)/sum(seco_dual_use_cleaned$Wert) * 100
## [1] 75.20547

Wie verteilt sich das Exportvolumen auf die einzelnen Verzeichnisse?

verzeichnisSummen <- seco_dual_use_cleaned  %>% 
  group_by(Verzeichnis) %>%
  summarise(Wert = sum(Wert)) %>%
  arrange(desc(Wert)) %>%
  mutate(Verzeichnis = factor(Verzeichnis, levels = Verzeichnis))
verzeichnisSummenBar <- ggplot(data = verzeichnisSummen, aes(x = Verzeichnis, y = Wert)) + 
  geom_bar(stat = "identity") + 
  scale_y_continuous(labels = formatAsChf) + 
  xlab("Verzeichnis") +
  theme(axis.text.x = element_text(angle=45, vjust=0.5))
verzeichnisSummenBar

Temporale Auswertung

Summe nach Jahr
# Summe nach Jahr
exportvolumenNachJahr <- seco_dual_use_cleaned  %>% 
  group_by(Jahr = format(Datum, "%Y"), Verzeichnis) %>%
  summarise(Wert = sum(Wert)) %>%
  mutate(Verzeichnis = factor(Verzeichnis, levels = c("ML (GKV)", "GKV", "unbekannt", "ChKV", "5.1", "5.2")))

exportvolumenNachJahrBar <- ggplot(data = exportvolumenNachJahr, aes(x = Jahr, y = Wert, fill = factor(Verzeichnis), order = Verzeichnis)) + 
  geom_bar(stat = "identity") + 
  scale_y_continuous(labels = formatAsChf) + 
  xlab("Jahr") +
  scale_fill_discrete(name = "Verzeichnis")
  
exportvolumenNachJahrBar

Nur besondere militärische Güter (ML)
# Summe nach Jahr, nur Wassenaar-Güter
# zuerst brauchen wir die grössten fünf Kategorien
exportvolumenML5Groesste <- seco_dual_use_cleaned %>%
  filter(Verzeichnis == "ML (GKV)") %>%
  group_by(Haupttyp) %>%
  summarise(Wert = sum(Wert)) %>%
  arrange(desc(Wert)) %>%
  select(Haupttyp) %>%
  slice(1:5)
exportvolumenNachJahrML <- seco_dual_use_cleaned  %>% 
  filter(Verzeichnis == "ML (GKV)") %>%
  group_by(Jahr = format(Datum, "%Y"), Haupttyp) %>%
  summarise(Wert = sum(Wert)) %>%
  mutate(Haupttyp = ifelse(Haupttyp %in% as.data.frame(exportvolumenML5Groesste)[,1], as.character(Haupttyp), "andere")) %>%
  mutate(Haupttyp = factor(Haupttyp, levels = c(as.character(as.data.frame(exportvolumenML5Groesste)[,1]), "andere")))

exportvolumenNachJahrMLBar <- ggplot(data = exportvolumenNachJahrML, aes(x = Jahr, y = Wert, fill = factor(Haupttyp), order = Haupttyp)) + 
  geom_bar(stat = "identity") + 
  scale_y_continuous(labels = formatAsChf) + 
  xlab("Jahr") +
  scale_fill_discrete(name = "Haupttyp")
exportvolumenNachJahrMLBar

Nur Dual-Use (GKV)
# Summe nach Jahr, nur GKV
# zuerst brauchen wir die grössten fünf Kategorien
exportvolumenGKV5Groesste <- seco_dual_use_cleaned %>%
  filter(Verzeichnis == "GKV") %>%
  group_by(Haupttyp) %>%
  summarise(Wert = sum(Wert)) %>%
  arrange(desc(Wert)) %>%
  select(Haupttyp) %>%
  slice(1:5)
exportvolumenNachJahrGKV <- seco_dual_use_cleaned  %>% 
  filter(Verzeichnis == "GKV") %>%
  group_by(Jahr = format(Datum, "%Y"), Haupttyp) %>%
  summarise(Wert = sum(Wert)) %>%
  mutate(Haupttyp = ifelse(Haupttyp %in% as.data.frame(exportvolumenGKV5Groesste)[,1], as.character(Haupttyp), "andere")) %>%
  mutate(Haupttyp = factor(Haupttyp, levels = c(as.character(as.data.frame(exportvolumenGKV5Groesste)[,1]), "andere")))

exportvolumenNachJahrGKVBar <- ggplot(data = exportvolumenNachJahrGKV, aes(x = Jahr, y = Wert, fill = factor(Haupttyp), order = Haupttyp)) + 
  geom_bar(stat = "identity") + 
  scale_y_continuous(labels = formatAsChf) + 
  xlab("Jahr") +
  scale_fill_discrete(name = "Haupttyp")
exportvolumenNachJahrGKVBar

# Summe nach Jahr, nur GKVKat2UnterkatB
# zuerst brauchen wir die grössten fünf Kategorien
exportvolumenGKVKat2UnterkatB5Groesste <- seco_dual_use_cleaned %>%
  filter(Verzeichnis == "GKV", Haupttyp == "2") %>%
  group_by(Untertyp) %>%
  summarise(Wert = sum(Wert)) %>%
  arrange(desc(Wert)) %>%
  select(Untertyp) %>%
  slice(1:5)
exportvolumenNachJahrGKVKat2UnterkatB <- seco_dual_use_cleaned  %>% 
  filter(Verzeichnis == "GKV", Haupttyp == "2") %>%
  group_by(Jahr = format(Datum, "%Y"), Untertyp) %>%
  summarise(Wert = sum(Wert)) %>%
  mutate(Untertyp = ifelse(Untertyp %in% as.data.frame(exportvolumenGKVKat2UnterkatB5Groesste)[,1], as.character(Untertyp), "andere")) %>%
  mutate(Untertyp = factor(Untertyp, levels = c(as.character(as.data.frame(exportvolumenGKVKat2UnterkatB5Groesste)[,1]), "andere")))

exportvolumenNachJahrGKVKat2UnterkatBBar <- ggplot(data = exportvolumenNachJahrGKVKat2UnterkatB, aes(x = Jahr, y = Wert, fill = factor(Untertyp), order = Untertyp)) + 
  geom_bar(stat = "identity") + 
  scale_y_continuous(labels = formatAsChf) + 
  xlab("Jahr") +
  scale_fill_discrete(name = "Untertyp")
exportvolumenNachJahrGKVKat2UnterkatBBar

Eine noch genauere Aufschlüsselung ist angezeigt:

# Summe nach Jahr, nur GKVKat2UnterkatB
# zuerst brauchen wir die grössten fünf Kategorien
exportvolumenGKVKat25Groesste <- seco_dual_use_cleaned %>%
  filter(Verzeichnis == "GKV", Haupttyp == "2", Untertyp == "B") %>%
  group_by(Zusatz) %>%
  summarise(Wert = sum(Wert)) %>%
  arrange(desc(Wert)) %>%
  select(Zusatz) %>%
  slice(1:5)
exportvolumenNachJahrGKVKat2 <- seco_dual_use_cleaned  %>% 
  filter(Verzeichnis == "GKV", Haupttyp == "2", Untertyp == "B") %>%
  group_by(Jahr = format(Datum, "%Y"), Zusatz) %>%
  summarise(Wert = sum(Wert)) %>%
  mutate(Zusatz = ifelse(Zusatz %in% as.data.frame(exportvolumenGKVKat25Groesste)[,1], as.character(Zusatz), "andere")) %>%
  mutate(Zusatz = factor(Zusatz, levels = c(as.character(as.data.frame(exportvolumenGKVKat25Groesste)[,1]), "andere")))

exportvolumenNachJahrGKVKat2Bar <- ggplot(data = exportvolumenNachJahrGKVKat2, aes(x = Jahr, y = Wert, fill = factor(Zusatz), order = Zusatz)) + 
  geom_bar(stat = "identity") + 
  scale_y_continuous(labels = formatAsChf) + 
  xlab("Jahr") +
  scale_fill_discrete(name = "Zusatz")
exportvolumenNachJahrGKVKat2Bar