{"id":22966606,"url":"https://github.com/favstats/rettungsdienst_projekt","last_synced_at":"2026-01-16T01:40:37.105Z","repository":{"id":108351583,"uuid":"164438539","full_name":"favstats/rettungsdienst_projekt","owner":"favstats","description":"Getting data from German Rescue services.","archived":false,"fork":false,"pushed_at":"2019-01-08T13:26:12.000Z","size":169,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-07T19:36:10.178Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/favstats.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-01-07T13:42:42.000Z","updated_at":"2019-01-11T12:01:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"d40de1e6-436a-4e40-9f81-ee751f49bba4","html_url":"https://github.com/favstats/rettungsdienst_projekt","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/favstats%2Frettungsdienst_projekt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/favstats%2Frettungsdienst_projekt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/favstats%2Frettungsdienst_projekt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/favstats%2Frettungsdienst_projekt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/favstats","download_url":"https://codeload.github.com/favstats/rettungsdienst_projekt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246758372,"owners_count":20828919,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-14T20:44:49.801Z","updated_at":"2026-01-16T01:40:37.099Z","avatar_url":"https://github.com/favstats.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"German Rescue Services data\n================\nFabio Votta\n\nThis script is about:\n\nGetting data from German Rescue services.\n\n## Packages and Folders\n\n``` r\n# Install these packages if you don't have them yet\n# if (!require(\"pacman\")) install.packages(\"pacman\")\n# devtools::install_github(\"favstats/tidytemplate\")\n\npacman::p_load(tidyverse, tidytemplate, rvest, RSelenium, glue, crayon)\n\n# Creates folders\n# tidytemplate::data_dir()\n# tidytemplate::images_dir()\n```\n\n## Rselenium Set Up\n\n``` r\nport \u003c- sample(4000L:5000L, 1)\nrD \u003c- rsDriver(verbose = FALSE, port = port)\n\nremDr \u003c- rD$client\n\n# url \u003c- \"https://www.swr.de/swraktuell/Rettungsdienst-weiter-ueberlastet-Im-Notfall-sind-hunderte-Gemeinden-nicht-ausreichend-versorgt,rettungsdienst-bei-hilfe-im-notfall-ueberlastet-100.html?search=Aach%20(Kreis%20Trier-Saarburg)\"\n# remDr$navigate(url)\n```\n\n## Get City Names\n\n``` r\nlettercodes \u003c- bind_cols(l1 = letters, l2 = letters) %\u003e% \n  expand.grid() %\u003e% \n  mutate(lettcode = paste0(l1, l2)) %\u003e% \n  select(-l1, -l2)\n \n\nget_city_list \u003c- function(keys) {\n  \nmessage(round((which(keys == lettercodes$lettcode) / length(lettercodes$lettcode))*100, 2), \"%\\n\")  \n  \n  remDr$findElement(using = \"xpath\", '//*[(@id = \"search\")]')\n\n  remDr$sendKeysToActiveElement(list(keys))\n  \n    # remDr$sendKeysToActiveElement(list(\"aa\"))\n\n  \n  # city_list \u003c- remDr$getPageSource() %\u003e% \n  #   magrittr::extract2(1) %\u003e% \n  #   read_html() %\u003e% \n  #   # html_nodes(\"#ui-id-1\") %\u003e% \n  #   html_nodes(\".ui-menu-item\") %\u003e% \n  #   html_text()\n  \nSys.sleep(1)\n  \n  \n  remDr$sendKeysToActiveElement(list(\"\\ue003\"))\n  remDr$sendKeysToActiveElement(list(\"\\ue003\"))\n\n\n  remDr$sendKeysToActiveElement(list(keys))\n  \n    # remDr$sendKeysToActiveElement(list(\"aa\"))\n\n  \n  city_list \u003c- remDr$getPageSource() %\u003e% \n    magrittr::extract2(1) %\u003e% \n    read_html() %\u003e% \n    # html_nodes(\"#ui-id-1\") %\u003e% \n    html_nodes(\".ui-menu-item\") %\u003e% \n    html_text()\n  \nSys.sleep(1)\n  \n  \n  remDr$sendKeysToActiveElement(list(\"\\ue003\"))\n  remDr$sendKeysToActiveElement(list(\"\\ue003\"))\n\n  return(city_list)\n}\n\n# get_city_list(\"sd\")\n# get_city_list(\"\")\n\ncity_names \u003c- lettercodes$lettcode %\u003e% \n  map(get_city_list) %\u003e% \n  flatten() %\u003e% as.character()\n\ntidytemplate::save_it(city_names)\n\n## manche Städte haben nicht genug Daten und müssen geskipped werden\n\ncity_names \u003c- tidytemplate::load_it(\"data/city_names.Rdata\")\n\ncity_urls \u003c- city_names %\u003e%\n  discard(str_detect(., \"Zu Ihrer Eingabe wurden keine Ergebnisse gefunden.\")) %\u003e% \n  str_replace_all(pattern = \" \", \"%20\") %\u003e% \n  paste0(\"?search=\", .)\n```\n\n## Get Emergency Data\n\n``` r\n# rm(key)\n# key \u003c- city_urls[41]\n\nget_gemeinde \u003c- function(key) {\n  url \u003c- glue(\"https://www.swr.de/swraktuell/Rettungsdienst-weiter-ueberlastet-Im-Notfall-sind-hunderte-Gemeinden-nicht-ausreichend-versorgt,rettungsdienst-bei-hilfe-im-notfall-ueberlastet-100.html{key}\")\n\nremDr$navigate(url)\n\nSys.sleep(1.5)\n\npage_source \u003c- remDr$getPageSource() %\u003e% \n  magrittr::extract2(1) %\u003e% \n  read_html() \n\nnot_available \u003c- page_source %\u003e%\n  html_nodes(\".zitat-box:nth-child(2) .zitat-text\") %\u003e%\n  html_text() %\u003e%\n  str_detect(\"zu wenige Einsätze für eine Analyse gegeben\")\n\nif (not_available) return(NULL)\n\ncleaned_key \u003c- str_replace_all(key, pattern = \"%20\", \" \") %\u003e%\n  str_remove(\"\\\\?search=\")\n\ncurrent_case \u003c- which(key == city_urls)\n\nmessage(paste0(current_case, \" out of \", length(city_urls), \" (\", round((current_case / length(city_urls))*100, 2), \"%)\\n\")) \n\nparagraph_data \u003c- page_source %\u003e% \n  html_nodes(\"#result \u003e div \u003e p:nth-child(3)\") %\u003e% \n  html_nodes(\"strong\") %\u003e% \n  as.character() %\u003e% \n  str_remove(\"\u003cstrong\u003e\") %\u003e% \n  str_remove(\"\u003c/strong\u003e\") %\u003e% \n  str_remove(\"\\\\*\") %\u003e% \n  str_remove(\"%\") %\u003e% \n  str_trim() %\u003e% \n  tibble(time = .) %\u003e% t %\u003e% \n  as_tibble() %\u003e% \n  set_names(c(\"time\", \"10_min_mark\", \"15_min_miss\", \"status\"))\n\ntable_data \u003c- page_source %\u003e% \n  html_nodes(\".table-responsive\") %\u003e% \n  html_nodes(\"table\") %\u003e% \n  html_table() %\u003e% \n  .[[1]] %\u003e% \n  set_names(.[1,]) %\u003e% \n  .[-1,] %\u003e% \n  janitor::clean_names() %\u003e% \n  gather(key, value, -blaulicht_einsatze) %\u003e% \n  t() %\u003e% \n  as_tibble() %\u003e%\n  set_names(paste(.[1,], .[2,])) %\u003e% \n  janitor::clean_names() %\u003e% \n  # rename_if(str_detect(., \"x2016\"), function(x) x \u003c- \"rtw_17\")\n  # rename(rtw_16 = V1, rtw_17 = V3, nef_16 = V2, nef_17 = V4) %\u003e% \n  .[-1:-2,] \n\ndistance_mna \u003c- page_source %\u003e% \n  html_nodes(\"#result p:nth-child(8)\") %\u003e% \n  as.character() %\u003e% \n  str_match(\"in (.*?) km\") %\u003e% \n  .[,2] %\u003e% as.numeric()\n\nfinal_set \u003c- bind_cols(paragraph_data, table_data) %\u003e% \n  mutate(distance_mna = distance_mna) %\u003e% \n  mutate(gemeinde = cleaned_key) %\u003e% \n  select(gemeinde, everything())\n\n\ncat(glue(\"Notfälle in {red$bold(cleaned_key)} können damit rechnen, dass der Rettungsdienst innerhalb von {green$bold(final_set$time)} eintrifft.\\n\"))\n\nif (magrittr::not(current_case %% 10 \u003e 0)) cat(Sys.time() - time_now)\n  \n  \n\n\nreturn(final_set)\n}\n\n# get_gemeinde(city_urls[1553])\n\ntime_now \u003c- Sys.time() \n\n\nsafe_gemeinde \u003c- purrr::safely(get_gemeinde)\n\n\n\ngemeinde_daten \u003c- city_urls %\u003e% \n  map(safe_gemeinde)\n\n\ntidytemplate::save_it(gemeinde_daten)\n```\n\n### Fixing some Missings\n\n``` r\nindex_missing \u003c- gemeinde_daten %\u003e% \n  map(\"error\") %\u003e% \n  map(is.null)%\u003e% \n  flatten() %\u003e% as.logical() %\u003e%  magrittr::not(.) \n\n\ngemeinde_missing \u003c- city_urls[index_missing] %\u003e% \n  map(safe_gemeinde)\n\nnotfall_dat \u003c- bind_rows(\n\ngemeinde_daten %\u003e% \n  map(\"result\") %\u003e% \n  bind_rows(),\n\ngemeinde_missing %\u003e% \n  map(\"result\") %\u003e% \n  bind_rows()\n\n) %\u003e% \n  full_join(tibble(gemeinde = city_names))\n```\n\n### Data Cleaning\n\n``` r\nnotfall_dat \u003c- notfall_dat %\u003e% \n  rename(ten_min_mark = `10_min_mark`,\n         fifteen_min_miss = `15_min_miss`,\n         rtw_16 = rettungswagen_x2016,\n         rtw_17 = rettungswagen_x2017,\n         nef_16 = notarzt_x2016,\n         nef_17 = notarzt_x2017) %\u003e% \n  tidyr::separate(time, into = c(\"minutes\", \"seconds\"), sep = \":\") %\u003e% \n  mutate(minutes = parse_number(minutes)) %\u003e% \n  mutate(seconds = parse_number(seconds) / 60) %\u003e% \n  mutate(time = minutes + seconds) %\u003e%\n  mutate_at(vars(ten_min_mark, \n                 fifteen_min_miss, \n                 rtw_16, \n                 rtw_17, \n                 nef_16, \n                 nef_17), parse_number) %\u003e% \n  select(gemeinde, time, everything())\n\ntidytemplate::save_it(notfall_dat)\n```\n\n## Data Exploring and Dataviz\n\n``` r\nnotfall_dat \u003c- tidytemplate::load_it(\"data/notfall_dat.Rdata\")\n```\n\n### Fastest Regions\n\n``` r\nnotfall_dat %\u003e% \n  arrange(time)\n```\n\n    ## # A tibble: 3,435 x 12\n    ##    gemeinde  time minutes seconds ten_min_mark fifteen_min_miss status\n    ##    \u003cchr\u003e    \u003cdbl\u003e   \u003cdbl\u003e   \u003cdbl\u003e        \u003cdbl\u003e            \u003cdbl\u003e \u003cchr\u003e \n    ##  1 Helmenz~  5.02       5  0.0167           83                7 versc~\n    ##  2 Erolzhe~  5.05       5  0.05             84                5 versc~\n    ##  3 Merklin~  5.15       5  0.15             87                5 versc~\n    ##  4 Wehingen  5.17       5  0.167            81                9 versc~\n    ##  5 Arzfeld   5.22       5  0.217            70               14 versc~\n    ##  6 Horhaus~  5.27       5  0.267            77               10 versc~\n    ##  7 Adenau    5.42       5  0.417            81                8 versc~\n    ##  8 Herschb~  5.42       5  0.417            82                7 versc~\n    ##  9 Echtern~  5.43       5  0.433            76               11 versc~\n    ## 10 Speicher  5.45       5  0.45             83                7 versc~\n    ## # ... with 3,425 more rows, and 5 more variables: rtw_16 \u003cdbl\u003e,\n    ## #   nef_16 \u003cdbl\u003e, rtw_17 \u003cdbl\u003e, nef_17 \u003cdbl\u003e, distance_mna \u003cdbl\u003e\n\n### Slowest Regions\n\n``` r\nnotfall_dat %\u003e% \n  arrange(desc(time))\n```\n\n    ## # A tibble: 3,435 x 12\n    ##    gemeinde  time minutes seconds ten_min_mark fifteen_min_miss status\n    ##    \u003cchr\u003e    \u003cdbl\u003e   \u003cdbl\u003e   \u003cdbl\u003e        \u003cdbl\u003e            \u003cdbl\u003e \u003cchr\u003e \n    ##  1 Dedenba~  37.8      37  0.833             2               17 verbe~\n    ##  2 Sevenig~  33.9      33  0.933             0               87 verbe~\n    ##  3 Sauerth~  30.6      30  0.55             24               13 verbe~\n    ##  4 Lierfeld  29.0      28  0.967            21               56 verbe~\n    ##  5 Fretten~  26.5      26  0.517             2               32 verbe~\n    ##  6 Lottste~  26.4      26  0.417             0              100 verbe~\n    ##  7 Gebroth   25.4      25  0.45              0               97 verbe~\n    ##  8 Genting~  25.4      25  0.367             0              100 versc~\n    ##  9 Heiligk~  24.0      24  0.0167            0               99 versc~\n    ## 10 Kellenb~  23.9      23  0.933             2               75 verbe~\n    ## # ... with 3,425 more rows, and 5 more variables: rtw_16 \u003cdbl\u003e,\n    ## #   nef_16 \u003cdbl\u003e, rtw_17 \u003cdbl\u003e, nef_17 \u003cdbl\u003e, distance_mna \u003cdbl\u003e\n\n``` r\nnotfall_dat %\u003e% \n  ggplot(aes(distance_mna, time)) +\n  geom_point() +\n  geom_smooth()\n```\n\n    ## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = \"cs\")'\n\n    ## Warning: Removed 1128 rows containing non-finite values (stat_smooth).\n\n    ## Warning: Removed 1128 rows containing missing values (geom_point).\n\n![](save_me_files/figure-gfm/unnamed-chunk-10-1.png)\u003c!-- --\u003e\n\n``` r\n  # geom_density()\n\nnotfall_dat %\u003e% \n  arrange(time) %\u003e% \n  drop_na(status) %\u003e% \n  ggplot(aes(status, ten_min_mark)) +\n  geom_boxplot()\n```\n\n![](save_me_files/figure-gfm/unnamed-chunk-10-2.png)\u003c!-- --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffavstats%2Frettungsdienst_projekt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffavstats%2Frettungsdienst_projekt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffavstats%2Frettungsdienst_projekt/lists"}