Spaß mit Daten: Fahrradzählung in Bochum

Das Open Data-Portal der Stadt Bochum bietet die Ergebnisse von Radverkehrszählungen zum Download an, die an der Fahrradzählstelle Herner Straße / Poststraße / Vierhausstraße im Jahr 2017 durchgeführt wurden.

Problem: Die Ergebnistabellen werden pro Fahrrichtung (Richtung Herne sowie Richtung Innenstadt) monatsweise veröffentlicht, so dass man zunächst 24 Tabellen verbinden muss. Diese Schritte werde ich hier darstellen.

Ich beginne mit der Fahrrichtung Innenstadt und kopiere zunächst die URLs aller zwölf Tabellen in eine Variable; das geht leider nur per Handarbeit:

fahrrad2017_Innenstadt <- c("https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_12_Radverkehr_HernerStr_FR_Bochum.csv","https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_11_Radverkehr_HernerStr_FR_Bochum.csv","https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_10_Radverkehr_HernerStr_FR_Bochum.csv","https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_09_Radverkehr_HernerStr_FR_Bochum.csv","https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_08_Radverkehr_HernerStr_FR_Bochum.csv","https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_07_Radverkehr_HernerStr_FR_Bochum.csv","https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_06_Radverkehr_HernerStr_FR_Bochum.csv","https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_05_Radverkehr_HernerStr_FR_Bochum.csv","https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_04_Radverkehr_HernerStr_FR_Bochum.csv","https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_03_Radverkehr_HernerStr_FR_Bochum.csv","https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_02_Radverkehr_HernerStr_FR_Bochum.csv","https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_01_Radverkehr_HernerStr_FR_Bochum.csv")

Anschließend wird der Reihe nach per for-Loop jede Tabelle heruntergeladen und in eine Variable eingelesen bzw. an diese drangehängt, so dass am Ende die Tabelle df_Innenstadt die Zählungen des gesamten Jahres für diese Fahrrichtung enthält:

df_Innenstadt <- data.frame(matrix(ncol = 3,nrow = 0))
for (i in c(1:12)) {
  download.file(url = fahrrad2017_Innenstadt[i], destfile = as.character(i))
  a <- read.csv(file = as.character(i), skip = 4, sep = ";", col.names = c("Datum","Zeit","Anzahl.Innenstadt"))
  df_Innenstadt <- rbind(df_Innenstadt, a)
}
head(df_Innenstadt)
##        Datum     Zeit Anzahl.Innenstadt
## 1 01.12.2017 00:01:00                 0
## 2 01.12.2017 00:02:00                 0
## 3 01.12.2017 00:03:00                 0
## 4 01.12.2017 00:04:00                 0
## 5 01.12.2017 00:05:00                 0
## 6 01.12.2017 00:06:00                 0

Diese Schritte werden mit den Tabellen für die Fahrrichtung Herne wiederholt:

fahrrad2017_Herne <- c(
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_12_Radverkehr_HernerStr_FR_Herne.csv",
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_11_Radverkehr_HernerStr_FR_Herne.csv",
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_10_Radverkehr_HernerStr_FR_Herne.csv",
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_09_Radverkehr_HernerStr_FR_Herne.csv",
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_08_Radverkehr_HernerStr_FR_Herne.csv",
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_07_Radverkehr_HernerStr_FR_Herne.csv",
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_06_Radverkehr_HernerStr_FR_Herne.csv",
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_05_Radverkehr_HernerStr_FR_Herne.csv",
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_04_Radverkehr_HernerStr_FR_Herne.csv",
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_03_Radverkehr_HernerStr_FR_Herne.csv",
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_02_Radverkehr_HernerStr_FR_Herne.csv",
  "https://www.bochum.de/C12571A3001D56CE/vwContentByKey/W2AVQCSN710BOCMDE/$FILE/2017_01_Radverkehr_HernerStr_FR_Herne.csv")

df_Herne <- data.frame(matrix(ncol = 3,nrow = 0))
for (i in c(1:12)) {
  download.file(url = fahrrad2017_Herne[i], destfile = as.character(i))
  a <- read.csv(file = as.character(i), skip = 4, sep = ";", col.names = c("Datum","Zeit","Anzahl.Herne"))
  df_Herne <- rbind(df_Herne, a)
}

Jetzt möchte ich gerne beide Tabellen (also Fahrtrichtungen) verbinden. Ihrer Struktur nach sollten beide für jede Minute jeden Tages des gesamten Jahres eine Messung enthalten, also die gleiche Länge aufweisen. Sind sie aber nicht, was zur Folge hat, dass ich sie nicht einfach per cbind verbinden kann (was aber wahrscheinlich aus vielen Gründen riskant)! Mit den möglichen Gründen halte ich mich nicht weiter auf, sondern entscheide mich dafür, sie per merge so zu verbinden, dass nur Zeitpunkte (Datum und Uhrzeit), die in beiden Tabellen vorkommen, in der neuen Tabelle enthalten sind. Dafür muss ich diesen Zeitstempel aber zunächst schaffen – heißt: Die Einträge der Spalten Datum und Zeit in eine neue Spalte namens ID zu schreiben:

df_Herne <- within(df_Herne, { ID = paste(Datum, Zeit) })
df_Innenstadt <- within(df_Innenstadt, { ID = paste(Datum, Zeit) })
head(df_Herne)
##        Datum     Zeit Anzahl.Herne                  ID
## 1 01.12.2017 00:01:00            0 01.12.2017 00:01:00
## 2 01.12.2017 00:02:00            0 01.12.2017 00:02:00
## 3 01.12.2017 00:03:00            0 01.12.2017 00:03:00
## 4 01.12.2017 00:04:00            0 01.12.2017 00:04:00
## 5 01.12.2017 00:05:00            0 01.12.2017 00:05:00
## 6 01.12.2017 00:06:00            0 01.12.2017 00:06:00
head(df_Innenstadt)
##        Datum     Zeit Anzahl.Innenstadt                  ID
## 1 01.12.2017 00:01:00                 0 01.12.2017 00:01:00
## 2 01.12.2017 00:02:00                 0 01.12.2017 00:02:00
## 3 01.12.2017 00:03:00                 0 01.12.2017 00:03:00
## 4 01.12.2017 00:04:00                 0 01.12.2017 00:04:00
## 5 01.12.2017 00:05:00                 0 01.12.2017 00:05:00
## 6 01.12.2017 00:06:00                 0 01.12.2017 00:06:00

Jetzt haben beide Tabellen jeweils eine (so hoffe ich) eindeutige ID und ich erzeuge die neue Tabelle Fahrrad_2017, die für jeden Zeitstempel die Zählergebnisse beider Fahrrichtungen enthält. Zusätzlich lese ich Datum und Uhrzeit per strptime korrekt (also gwm. maschinenlesbar) in die neue Spalte Zeitpunkt ein:

Fahrrad_2017 <- merge(df_Herne, df_Innenstadt, by="ID")
Fahrrad_2017 <- within(Fahrrad_2017, { Zeitpunkt = strptime(paste(Datum.x, Zeit.x), "%d.%m.%Y%H:%M:%S") })
head(Fahrrad_2017)
##                    ID    Datum.x   Zeit.x Anzahl.Herne    Datum.y   Zeit.y
## 1 01.01.2017 00:01:00 01.01.2017 00:01:00            0 01.01.2017 00:01:00
## 2 01.01.2017 00:02:00 01.01.2017 00:02:00            0 01.01.2017 00:02:00
## 3 01.01.2017 00:03:00 01.01.2017 00:03:00            0 01.01.2017 00:03:00
## 4 01.01.2017 00:04:00 01.01.2017 00:04:00            0 01.01.2017 00:04:00
## 5 01.01.2017 00:05:00 01.01.2017 00:05:00            0 01.01.2017 00:05:00
## 6 01.01.2017 00:06:00 01.01.2017 00:06:00            0 01.01.2017 00:06:00
##   Anzahl.Innenstadt           Zeitpunkt
## 1                 0 2017-01-01 00:01:00
## 2                 0 2017-01-01 00:02:00
## 3                 0 2017-01-01 00:03:00
## 4                 0 2017-01-01 00:04:00
## 5                 0 2017-01-01 00:05:00
## 6                 0 2017-01-01 00:06:00

Die Tabelle enthält jetzt gleich mehrfach Datum und Uhrzeit. Per select-Befehl aus dem dplyr-Package werden nur die drei Spalten ausgewählt, die ich wirklich benötige, nämlich Zeitpunkt, Anzahl in Richtung Herne und Anzahl in Richtung Innenstadt:

library(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
Fahrrad_2017 <- Fahrrad_2017 %>% select(Anzahl.Herne, Anzahl.Innenstadt, Zeitpunkt)
head(Fahrrad_2017)
##   Anzahl.Herne Anzahl.Innenstadt           Zeitpunkt
## 1            0                 0 2017-01-01 00:01:00
## 2            0                 0 2017-01-01 00:02:00
## 3            0                 0 2017-01-01 00:03:00
## 4            0                 0 2017-01-01 00:04:00
## 5            0                 0 2017-01-01 00:05:00
## 6            0                 0 2017-01-01 00:06:00

Jetzt habe ich alle Ergebnisse der Fahrradzählung 2017 in einer Tabelle mit 523.419 Zeilen. Die Ergebnistabelle kann hier (ZIP, 2,6 MB) heruntergeladen werden.

In der Fortsetzung will ich mich endlich mit der Auswertung und Visualisierung der Daten beschäftigen. Dabei werden dann auch die Zählergebnisse aus dem Vorjahr 2016 berücksichtigt.

It’s striking that in Emmanuel Macron’s fuel tax rises the gilets jaunes opposed the very thing demanded by Extinction Rebellion, Britain’s newly minted leaderless movement: aggressive policies to reduce carbon emissions to net zero.

How to create a leaderless revolution and win lasting political change | Carne Ross | Opinion | The Guardian https://www.theguardian.com/commentisfree/2018/dec/13/leaderless-revolution-insurgency-gilet-jaunes-extinction-rebellion

Auch 2029 wird es keine Künstliche Intelligenz geben, die diesen Namen verdient | WIRED Germany

Bookmarked Auch 2029 wird es keine Künstliche Intelligenz geben, die diesen Namen verdient (WIRED)
Prognosen über die technische Zukunft im Allgemeinen sind immer ein riskantes Unterfangen. Prognosen über die Entwicklung der sogenannten Künstlichen Intelligenz (KI) im Besonderen spielen dabei sogar in einer ganz eigenen Liga. Denn ihre Geschichte ist eine Geschichte von grotesk überzogenen Erwartungen. Ein WIRED2029-Gastbeitrag von Florian Gallwitz, Professor für Medieninformatik an der Technischen Hochschule Nürnberg.

Aufstand der Peripherie – Republik

Bookmarked Aufstand der Peripherie (republik.ch)
Frankreich befindet sich im Ausnahmezustand. Kann Präsident Macron die Situation beruhigen? Und was bedeuten die Ausschreitungen für das Land – und für Europa?
"Gelbwesten seien das Äquivalent von Trump-Wählern, meinte Bannon in einer Ansprache vor Marine Le Pen und einem Parkett ihrer Parteikader. Er wird bei den Europawahlen alles daransetzen, den Beweis dieser Behauptung anzutreten. Nichts könnte dümmer sein, als ihm vorab recht zu geben."

Liked Raise a glass to the planet’s most stellar data visuals of 2018 — Information is Beautiful (Information is Beautiful)
Massive congratulations to the innovative, imaginative & intrepid winners of 2018’s global Information is Beautiful Awards – a celebration of the world’s best data-visualisations and infographics. Trimming down 100 world-class shortlistees to a handful of exceptional winners was a fierce challenge for our panel of expert judges & community voters. Given such unrivalled ambition & scope – graphic novels, mosaics, […]

Resonanz und Politik

In der jüngsten Sendung der Reihe Sein und Streit bei Deutschlandfunk Kultur stieß ich auf den Jenaer Soziologen Hartmut Rosa, der darin als Theoretiker der „Resonanz“ vorgestellt wird:

Resonanz, darunter versteht er eine Form der Begegnung zwischen Menschen oder zwischen einem Menschen und der Welt, die von Emotion, der Erfahrung von Selbstwirksamkeit und von Transformation geprägt ist.

Im Audiobeitrag wird das klarer, wenn er erklärt, eine Begegnung oder Diskussion sei resonant, wenn sie im Wissen um die Möglichkeit erfolgt, dass sie einen selbst, die eigenen Überzeugungen oder Meinungen ebenso verändern könne, wie man selbst das Gegenüber und dessen Überzeugungen verändern kann (und wohl auch will).

Derartige Begegnungen sind im (medialen) Alltag tatsächlich rar. In politischen Talkshows (dieses Beispiel führt Rosa selbst an) gilt als Verlierer, wer nachgibt. In den sozialen Netzwerken trifft oft das selbe zu – wobei interessant ist, warum das so ist; ist das Talkshow-Verhalten hier eingeübt? Macht die Öffentlichkeit den Unterschied – ob im TV oder im Netz? Oder die Flüchtigkeit und Anonymität der Begegnung?

Und beim eigentlichen Thema der Sendung, den Protest- und Widerstandsbewegungen kann von einem Diskurs oder argumentativen Austausch ja überhaupt nicht gesprochen werden.