158 lines
5.5 KiB
R
158 lines
5.5 KiB
R
library(rjson)
|
|
library(shiny)
|
|
library(bslib)
|
|
library(leaflet)
|
|
library(sf)
|
|
library(htmltools)
|
|
library(dplyr)
|
|
library(tidyr)
|
|
library(purrr)
|
|
library(ggplot2)
|
|
library(ggthemes)
|
|
library(stringr)
|
|
library(plotly)
|
|
|
|
#große JSON Datei lesen
|
|
crime_json <- fromJSON(file="data.json")
|
|
get_bezirk_by_stadtteil <- function(name) {
|
|
parents <- names(crime_json)[sapply(crime_json, function(item) name %in% names(item))]
|
|
|
|
if (length(parents) == 0) return(NULL)
|
|
parents
|
|
}
|
|
|
|
#Wichtige Informationen aus passender Ebene/Row von der JSON Datei holen, um sie für das tibble zu nutzen
|
|
#trimws steht für trim whitespace, sorgt für sauberen string beim Jahr
|
|
#map_df steht für map dataframe
|
|
#aufgekärte Fälle sind auch im tibble drin, hätten wir also bei mehr Zeit oder für ,ehr Funktionen auch direkt nutzen können
|
|
map_data_to_table <- function(bezirk, stadtteil, year) {
|
|
year <- as.character(trimws(year))
|
|
map_df(names(crime_json[[bezirk]][[stadtteil]]), function(crime) {
|
|
row <- crime_json[[bezirk]][[stadtteil]][[crime]][[year]]
|
|
|
|
tibble(
|
|
Name = crime,
|
|
`Erfasste Fälle` = as.integer(row[["Erfasste Fälle"]]),
|
|
`Aufgeklärte Fälle` = as.integer(row[["Aufgeklärte Fälle"]]),
|
|
`Aufklärung relativ` = paste(row[["Aufklärung relativ"]], "%", sep=""),
|
|
)
|
|
})
|
|
}
|
|
|
|
#Vorbereitung für Balkendiagram top3 Straftaten
|
|
#Sortieren und Beschränken auf die Ränge 2, 3 und 4
|
|
#Sortieren: Absteigend nach "Erfasste Fälle". Der höchste Wert ist nun in Zeile 1.
|
|
#mit slice sind explizit die Ränge 2, 3 und 4 gemeint
|
|
map_data_to_top3_plot <- function(bezirk, stadtteil, year) {
|
|
year <- as.character(trimws(year))
|
|
req(bezirk)
|
|
req(stadtteil)
|
|
req(year)
|
|
komplettes_tibble <- map_df(names(crime_json[[bezirk]][[stadtteil]]), function(crime) {
|
|
row <- crime_json[[bezirk]][[stadtteil]][[crime]][[year]]
|
|
tibble(
|
|
Name = str_wrap(crime, width = 25),
|
|
Erfasst = as.integer(row[["Erfasste Fälle"]]),
|
|
)
|
|
})
|
|
top_3_tibble <- komplettes_tibble %>%
|
|
arrange(desc(Erfasst)) %>%
|
|
slice(2:4)
|
|
return(top_3_tibble)
|
|
}
|
|
|
|
#Vorbereitung für Balkendiagramm auf Vergleichs-tab
|
|
#Location beinhaltet Stadtteile und Bezirke, um alle Auswahlmöglichkeiten in einem drop down zu haben
|
|
#die App weiß, wann es sich um einen Bezirk handelt, wenn die ersten 7 Stellen mit dem Wort "Bezirk" übereinstimmen?
|
|
#Erfasste Fälle als Zahl (integer) angeben, die Straftaten (crimes) mit Zeilenumbruch bei bestimmter Breite angeben
|
|
#Sortierung nach Anzhal der erfassten Fälle absteigend
|
|
map_data_to_plot <- function(locations, crimes, year) {
|
|
year <- as.character(trimws(year))
|
|
req(locations)
|
|
req(crimes)
|
|
req(year)
|
|
|
|
return(map_df(locations, function(loc) {
|
|
bezirk <- ""
|
|
stadtteil <- ""
|
|
if (substring(loc, 1, 6) == "Bezirk") {
|
|
bezirk <- substring(loc, 8, nchar(loc))
|
|
stadtteil <- loc
|
|
}
|
|
else {
|
|
bezirk <- get_bezirk_by_stadtteil(loc)
|
|
stadtteil <- loc
|
|
}
|
|
|
|
komplettes_tibble <- map_df(crimes, function(crime) {
|
|
row <- crime_json[[bezirk]][[stadtteil]][[crime]][[year]]
|
|
tibble(
|
|
Name = str_wrap(crime, width = 25),
|
|
Erfasst = as.integer(row[["Erfasste Fälle"]]),
|
|
Location = loc
|
|
)
|
|
})
|
|
}) %>%
|
|
arrange(desc(Erfasst))
|
|
)
|
|
}
|
|
|
|
#lass mal hier statt delikt crime nehmen oder eben die anderen crimes delikt, oder gibt es einen Grund dass es anders heißt/auf deutsch ist?
|
|
#Mit dieser Funktion entnehmen wir die gewünschten Einträge, Straftat, Jahr, Erfasste Fälle direkt aus der JSON Datei und erhalten so unseren dataframe, den wir wofür nutzen können?
|
|
#sicherer Zugriff (verhindert Fehler bei fehlenden Einträgen)
|
|
get_intensity_df <- function(crime_json, delikt, jahr = "2024", feld = "Erfasste Fälle") {
|
|
do.call(rbind, lapply(names(crime_json), function(bezirk) {
|
|
stadtteile <- crime_json[[bezirk]]
|
|
data.frame(
|
|
bezirk = bezirk,
|
|
stadtteil = names(stadtteile),
|
|
intensity = sapply(stadtteile, function(st) {
|
|
|
|
|
|
val <- st[[delikt]][[jahr]][[feld]]
|
|
|
|
if (is.null(val)) NA else val
|
|
}),
|
|
row.names = NULL
|
|
)
|
|
}))
|
|
}
|
|
|
|
#GeoJson für Bezirke
|
|
#st_transform sorgt für die Umwandlung der Geo-Daten in das Standard-Koordinatensystem WGS 84, csr bedeutet Koordinatenreferenzsystem
|
|
#mit paste("bez_") bilden wir die jeweiligen Präfixe für Stadtteil und Bezirk, damit aufgrund dieses Merkmals die app die beiden Typen voneinander unterscheiden kann
|
|
geo_bezirke <- st_read("geobezirke-parsed.json")
|
|
geo_bezirke <- st_transform(geo_bezirke, crs = 4326)
|
|
geo_bezirke$leaflet_id <- paste("bez_", geo_bezirke$bezirk, sep="")
|
|
|
|
#GeoJson für Stadtteile
|
|
geo_stadtteile <- st_read("geostadtteile-parsed.json")
|
|
geo_stadtteile <- st_transform(geo_stadtteile, crs = 4326)
|
|
geo_stadtteile$leaflet_id <- paste("std_", geo_stadtteile$stadtteil, sep="")
|
|
bezirke <- sort(names(crime_json))
|
|
|
|
list_of_crimes <- sort(c(unique(unlist(
|
|
lapply(crime_json, function(a) {
|
|
unlist(
|
|
lapply(a, function(b) {
|
|
names(b)
|
|
}),
|
|
use.names = FALSE
|
|
)
|
|
}),
|
|
use.names = FALSE
|
|
)), ""))
|
|
|
|
|
|
#map(names) wendet names() auf jedes Element der ersten Ebene, wie Bezirke ("A", "B", "C") an.
|
|
#Ergebnis: Eine Liste von Vektoren (z.B. list(c("aa1", "aa2"), c("bb1", "bb2"), c("cc1"))), hier: Stadtteile
|
|
#unlist() vereint alle diese Vektoren zu einem einzigen Vektor.
|
|
#Ergebnis: c("aa1", "aa2", "bb1", "bb2", "cc1")
|
|
#unique(): auf Nummer sicher gehen, dass die Stadtteile alle eindeutig sind.
|
|
auswahlmöglichkeiten <- crime_json %>%
|
|
|
|
map(names) %>%
|
|
unlist() %>%
|
|
unique() %>%
|
|
sort() %>%
|
|
setdiff("Alle") |