1<!DOCTYPE html> 2<html lang="" xml:lang=""> 3 <head> 4 <title>Visualing Time Series</title> 5 <meta charset="utf-8" /> 6 <meta name="author" content="Tatjana Kecojevic" /> 7 <meta name="date" content="2020-05-07" /> 8 <link href="libs/remark-css/default.css" rel="stylesheet" /> 9 <link href="libs/font-awesome/css/fontawesome-all.min.css" rel="stylesheet" /> 10 <link rel="stylesheet" href="assets/css/my-theme.css" type="text/css" /> 11 <link rel="stylesheet" href="assets/css/my-fonts.css" type="text/css" /> 12 <link rel="stylesheet" href="columns.css" type="text/css" /> 13 </head> 14 <body> 15 <textarea id="source"> 16 17 18 19 20layout: true 21 22<a class="footer-link" href="https://sisteranalyst.org">sisteranalyst.org</a> 23 24--- 25 26class: title-slide, center, bottom 27 28# Visualing Time Series 29 30## Data Literacy in R 31 32### Tatjana Kecojevic 33 34--- 35 36class: freight-slide, center, middle, inverse 37 38# .shadow-text[ecdc's covid-19 data] 39 40**Covid-19 data** is a set of deily observations on the number of newly infected and death cases in different countries around the world. 41 42## .emphasis[<https://www.ecdc.europa.eu/en/publications-data>] 43 44--- 45# .shadow-text[Grammar of Graphics] 46 47The [grammar of graphics](http://vita.had.co.nz/papers/layered-grammar.html) enables a structured way of creating a plot by adding the components as layers, making it look effective and attractive. 48 49- data 50- aesthetic mapping 51- geometric object 52- statistical transformations 53- scales 54- coordinate system 55- position adjustments 56- faceting 57 58Imagine talking about baking a cake and adding a cherry on the top. ðð This philosophy has been built into the [`ggplot`](https://ggplot2.tidyverse.org/reference/) package by [Hadley Wickham](http://hadley.nz) for creating elegant and complex plots in R. 59 60--- 61# .shadow-text[Build a plot layer by layer] 62 63Built up on the 'Grammar of Graphics' philosophy the [`ggplot2`](https://cran.r-project.org/web/packages/ggplot2/index.html) package enables you to construct complex plot by iteration of discrete layers. It allows for the layers with different data sets and aesthetic mapping to be put together to create sophisticated plots at a high level of abstraction that encapsulate data from multiple sources. 64 65All **ggplot2 plots** begin with a call to `ggplot()`, supplying default data and aesthethic mappings, specified by aes(). You then add layers, scales, coords and facets with `+`. 66 67To explore and learn more: 68 69- [ggplot cheatsheet](https://rstudio.com/wp-content/uploads/2015/03/ggplot2-cheatsheet.pdf) 70- [reference: layers](https://ggplot2.tidyverse.org/reference/) 71 72.footnote[ 73ð¡ [ggplot2](https://ggplot2.tidyverse.org/) is a part of the [tidyverse](https://www.tidyverse.org/), an ecosystem of packages designed with common APIs and a shared philosophy. 74] 75 76--- 77# What we need to do 78 79The best way to master it is by practising. So let us create an awesome `ggplot`. ð 80What we need to do is the following: 81 82**i.** Read [covid-19](https://en.wikipedia.org/wiki/COVID-19_pandemic) [ecdc](https://www.ecdc.europa.eu/en/publications-data) data 83 84**ii.** Wrangle the data in the format suitable for visualisation. 85 86**iii.** "Initialise" a plot with `ggplot()`: 87 88**ggplot(<span style="color:blue">dataframe</span>, aes(<span style="color:orangered">x = explanatory variable</span>, <span style="color:green">y = response variable</span>))** 89 90and add a few layers to make it informative and captivating. 91 92--- 93name: astroboy 94background-image: url(images/astro_boy.jpg) 95background-size: contain 96background-color: #f6f6f6 97 98 99# .emphasis[packages to install and upload] 100 101##### `install.packages("readxl")` 102##### `install.packages("httr")` 103##### `install.packages("lubridate")` 104##### `install.packages("tidyr")` 105##### `install.packages("ggplot2")` 106##### `install.packages("dplyr")` 107 108.footnote[ 109ð¡ Check the list of the packages assembeld into the [tidyverse](https://www.tidyverse.org/packages/). 110] 111--- 112## **Task 1:** Get **ecdc** data 113 114 115```r 116library(readxl) 117library(httr) 118library(lubridate) 119library(tidyr) 120library(ggplot2) 121library(dplyr) 122# access ecdc data 123url2 <- "https://www.ecdc.europa.eu/sites/default/files/documents/COVID-19-geographic-disbtribution-worldwide-2020-05-06.xlsx" 124GET(url2, write_disk(tf <- tempfile(fileext = ".xlsx"))) 125covid_ecdc <- read_excel(tf) 126``` 127.footnote[ 128ð¡ Check <https://importdata2r.netlify.app> to learn how to read data in R. 129] 130 131--- 132## Create ex-YU data subset 133 134 135```r 136covid_yu <- covid_ecdc %>% 137 filter(countriesAndTerritories %in% c("Bosnia_and_Herzegovina", 138 "Croatia", 139 "Montenegro", 140 "North_Macedonia", 141 "Serbia", 142 "Slovenia")) 143# remove unneeded columns 144covid_yu <- covid_yu[, -c(2:4, 8)] 145``` 146--- 147## **Task 2:** Data Wrangling 148 149 150```r 151covid_yu <- covid_yu %>% 152 separate(dateRep, c("dateRep"), sep = "T") %>% 153 group_by(countriesAndTerritories) %>% 154 arrange(dateRep) %>% 155 mutate(total_cases = cumsum(cases), 156 total_deaths = cumsum(deaths)) %>% # cumulative data 157 mutate(Diff_cases = total_cases - lag(total_cases), 158 Rate_pc_cases = round(Diff_cases/lag(total_cases) * 100, 2)) %>% # growt rate 159 mutate(second_der = Diff_cases - lag(Diff_cases)) %>% # 2nd derivative 160 rename(country = countriesAndTerritories) %>% 161 rename(country_code = countryterritoryCode) 162covid_yu$dateRep <- as.Date(covid_yu$dateRep) # set `dateRep` as date type 163covid_sr <- covid_yu %>% 164 filter(country_code == "SRB") # subset SRB data 165``` 166 167 168--- 169## **Task 3:** ggplot: `\(F^{''}(x)\)` vs date of recording 170 171.pull-left[ 172 173```r 174covid_sr %>% 175 filter(!is.na(second_der)) %>% 176* ggplot(aes(x = dateRep, y = second_der)) 177 178``` 179 180] 181 182.pull-right[ 183<img src="images/ggplot1.png" width="726" /> 184 185] 186 187--- 188## add the time serie 189 190.pull-left[ 191 192```r 193covid_sr %>% 194 filter(!is.na(second_der)) %>% 195 ggplot(aes(x = dateRep, y = second_der)) + 196* geom_line() 197``` 198 199] 200 201.pull-right[ 202<img src="images/ggplot2.png" width="726" /> 203 204] 205 206--- 207## add data points 208 209.pull-left[ 210 211```r 212covid_sr %>% 213 filter(!is.na(second_der)) %>% 214 ggplot(aes(x = dateRep, y = second_der)) + 215* geom_line() + geom_point(col = "#00688B") 216 217``` 218 219] 220 221.pull-right[ 222<img src="images/ggplot3.png" width="726" /> 223 224] 225 226--- 227## remove axes labels 228 229.pull-left[ 230 231```r 232covid_sr %>% 233 filter(!is.na(second_der)) %>% 234 ggplot(aes(x = dateRep, y = second_der)) + 235 geom_line() + geom_point(col = "#00688B") + 236* xlab("") + ylab("") 237 238``` 239 240] 241 242.pull-right[ 243<img src="images/ggplot4.png" width="726" /> 244 245] 246 247--- 248## add title and caption 249 250.pull-left[ 251 252```r 253covid_sr %>% 254 filter(!is.na(second_der)) %>% 255 ggplot(aes(x = dateRep, y = second_der)) + 256 geom_line() + geom_point(col = "#00688B") + 257 xlab("") + ylab("") +
258 labs (title = "2nd derivative of F(x)", 259* caption = "Data from: https://www.ecdc.europa.eu") 260 261``` 262 263] 264 265.pull-right[ 266<img src="images/ggplot5.png" width="726" /> 267 268] 269 270--- 271## use built-in [theme](https://ggplot2.tidyverse.org/reference/ggtheme.html) 272 273.pull-left[ 274 275```r 276covid_sr %>% 277 filter(!is.na(second_der)) %>% 278 ggplot(aes(x = dateRep, y = second_der)) + 279 geom_line() + geom_point(col = "#00688B") + 280 xlab("") + ylab("") + 281 labs (title = "2nd derivative of F(x)", 282 caption = "Data from: https://www.ecdc.europa.eu") + 283* theme_minimal() 284 285``` 286 287] 288 289.pull-right[ 290<img src="images/ggplot6.png" width="726" /> 291 292] 293 294--- 295 296## align title and remove grid lines 297 298.pull-left[ 299 300```r 301covid_sr %>% 302 filter(!is.na(second_der)) %>% 303 ggplot(aes(x = dateRep, y = second_der)) + 304 geom_line() + geom_point(col = "#00688B") + 305 xlab("") + ylab("") + 306 labs (title = "2nd derivative of F(x)", 307 caption = "Data from: https://www.ecdc.europa.eu") + 308 theme_minimal() + 309* theme(plot.title = element_text(size = 14, vjust = 2, hjust=0.5), 310* panel.grid.major.x = element_blank(), 311* panel.grid.minor.x = element_blank()) 312 313``` 314 315] 316 317.pull-right[ 318<img src="images/ggplot7.png" width="726" /> 319 320] 321 322 323--- 324 325## add vertical reference lines 326 327.pull-left[ 328 329```r 330covid_sr %>% 331 filter(!is.na(second_der)) %>% 332 ggplot(aes(x = dateRep, y = second_der)) + 333 geom_line() + geom_point(col = "#00688B") + 334 xlab("") + ylab("") +
335 labs (title = "2nd derivative of F(x)", 336 caption = "Data from: https://www.ecdc.europa.eu") + 337 theme_minimal() + 338 theme(plot.title = element_text(size = 14, vjust = 2, hjust=0.5), 339 panel.grid.major.x = element_blank(), 340 panel.grid.minor.x = element_blank()) + 341* geom_vline(xintercept = as.numeric(as.Date(c("2020-03-16", "2020-03-22", "2020-03-28", "2020-04-04", "2020-04-10", "2020-04-17", "2020-04-24", "2020-04-30"))), linetype=4, colour="red", alpha = 0.5) 342 343``` 344 345] 346 347.pull-right[ 348<img src="images/ggplot8.png" width="660" /> 349 350] 351 352--- 353## anotate refrence lines with text 354 355.pull-left[ 356 357```r 358ts_plot + 359*annotate(geom="text", x=as.Date("2020-03-16"), y = 150, label="state of\nemergency", col = "dodgerblue4") + 360* annotate(geom="text", x=as.Date("2020-03-22"), y = 70, label="curfew\n5pm-5am", col = "dodgerblue4") + 361* annotate(geom="text", x=as.Date("2020-03-28"), y = -140, label="weekend curfew\n3pm-5am", col = "dodgerblue4") + 362* annotate(geom="text", x=as.Date("2020-04-04"), y = 220, label="weekend curfew\n1pm Sat-5am Mon ", col = "dodgerblue4") + 363* annotate(geom="text", x=as.Date("2020-04-10"), y = -90, label="Easter curfew\n5pm Fri-5am Mon ", col = "dodgerblue4") + 364* annotate(geom="text", x=as.Date("2020-04-17"), y = 200, label="Easter curfew\n5pm Fri-5am Tue ", col = "dodgerblue4") + 365* annotate(geom="text", x=as.Date("2020-04-24"), y = -120, label="weekend curfew\n5pm Fri-5am Mon ", col = "dodgerblue4") + 366* annotate(geom="text", x=as.Date("2020-04-30"), y = 160, label="May Day curfew\n6pm Thu-5am Sat ", col = "dodgerblue4") 367``` 368] 369 370.pull-right[ 371<img src="images/ggplot9.png" width="726" /> 372 373] 374 375 376.footnote[ 377ð¡ Note that the plot from the previous slide has been saved as `ts_plot`! 378] 379--- 380name: astroboy 381background-image: url(images/ggplot9.png) 382background-size: contain 383background-color: #f6f6f6 384 385# .shadow-text[Nice... ð] 386 387--- 388class: freight-slide, center, middle, inverse 389 390# .shadow-text[To learn more visit: <https://dataliteracy.rbind.io>] 391 392.emphasis[To see it in action visit: <http://covid19sr.rbind.io>] 393 394[<i class="fab fa-twitter "></i> @Tatjana_Kec](https://twitter.com/Tatjana_Kec) 395 396[<i class="fab fa-github "></i> @TanjaKec](https://github.com/TanjaKec) 397 </textarea> 398<style data-target="print-only">@media screen {.remark-slide-container{display:block;}.remark-slide-scaler{box-shadow:none;}}</style>
399<script src="https://remarkjs.com/downloads/remark-latest.min.js"></script>
vendor: 1 bytes, line 399
399
400<script>var slideshow = remark.create({ 401"highlightStyle": "solarized-light", 402"highlightLanguage": ["r", "css", "yaml"], 403"slideNumberFormat": "", 404"highlightLines": true, 405"countIncrementalSlides": false, 406"ratio": "16:9" 407}); 408if (window.HTMLWidgets) slideshow.on('afterShowSlide', function (slide) { 409 window.dispatchEvent(new Event('resize')); 410}); 411(function(d) { 412 var s = d.createElement("style"), r = d.querySelector(".remark-slide-scaler"); 413 if (!r) return; 414 s.type = "text/css"; s.innerHTML = "@page {size: " + r.style.width + " " + r.style.height +"; }"; 415 d.head.appendChild(s); 416})(document); 417 418(function(d) { 419 var el = d.getElementsByClassName("remark-slides-area"); 420 if (!el) return; 421 var slide, slides = slideshow.getSlides(), els = el[0].children; 422 for (var i = 1; i < slides.length; i++) { 423 slide = slides[i]; 424 if (slide.properties.continued === "true" || slide.properties.count === "false") { 425 els[i - 1].className += ' has-continuation'; 426 } 427 } 428 var s = d.createElement("style"); 429 s.type = "text/css"; s.innerHTML = "@media print { .has-continuation { display: none; } }"; 430 d.head.appendChild(s); 431})(document); 432// delete the temporary CSS (for displaying all slides initially) when the user 433// starts to view slides 434(function() { 435 var deleted = false; 436 slideshow.on('beforeShowSlide', function(slide) { 437 if (deleted) return; 438 var sheets = document.styleSheets, node; 439 for (var i = 0; i < sheets.length; i++) { 440 node = sheets[i].ownerNode; 441 if (node.dataset["target"] !== "print-only") continue; 442 node.parentNode.removeChild(node); 443 } 444 deleted = true; 445 }); 446})(); 447(function() { 448 "use strict" 449 // Replace
449<script> tags in slides area to make them executable 450 var scripts = document.querySelectorAll( 451 '.remark-slides-area .remark-slide-container script' 452 ); 453 if (!scripts.length) return; 454 for (var i = 0; i < scripts.length; i++) { 455 var s = document.createElement('script'); 456 var code = document.createTextNode(scripts[i].textContent); 457 s.appendChild(code); 458 var scriptAttrs = scripts[i].attributes; 459 for (var j = 0; j < scriptAttrs.length; j++) { 460 s.setAttribute(scriptAttrs[j].name, scriptAttrs[j].value); 461 } 462 scripts[i].parentElement.replaceChild(s, scripts[i]); 463 } 464})(); 465(function() { 466 var links = document.getElementsByTagName('a'); 467 for (var i = 0; i < links.length; i++) { 468 if (/^(https?:)?\/\//.test(links[i].getAttribute('href'))) { 469 links[i].target = '_blank'; 470 } 471 } 472})(); 473// adds .remark-code-has-line-highlighted class to <pre> parent elements 474// of code chunks containing highlighted lines with class .remark-code-line-highlighted 475(function(d) { 476 const hlines = d.querySelectorAll('.remark-code-line-highlighted'); 477 const preParents = []; 478 const findPreParent = function(line, p = 0) { 479 if (p > 1) return null; // traverse up no further than grandparent 480 const el = line.parentElement; 481 return el.tagName === "PRE" ? el : findPreParent(el, ++p); 482 }; 483 484 for (let line of hlines) { 485 let pre = findPreParent(line); 486 if (pre && !preParents.includes(pre)) preParents.push(pre); 487 } 488 preParents.forEach(p => p.classList.add("remark-code-has-line-highlighted")); 489})(document);</script>
489 490
491<script> 492slideshow._releaseMath = function(el) { 493 var i, text, code, codes = el.getElementsByTagName('code'); 494 for (i = 0; i < codes.length;) { 495 code = codes[i]; 496 if (code.parentNode.tagName !== 'PRE' && code.childElementCount === 0) { 497 text = code.textContent; 498 if (/^\\\((.|\s)+\\\)$/.test(text) || /^\\\[(.|\s)+\\\]$/.test(text) || 499 /^\$\$(.|\s)+\$\$$/.test(text) || 500 /^\\begin\{([^}]+)\}(.|\s)+\\end\{[^}]+\}$/.test(text)) { 501 code.outerHTML = code.innerHTML; // remove <code></code> 502 continue; 503 } 504 } 505 i++; 506 } 507}; 508slideshow._releaseMath(document); 509</script>
509 510<!-- dynamically load mathjax for compatibility with self-contained -->
511<script> 512(function () { 513 var script = document.createElement('script'); 514 script.type = 'text/javascript'; 515 script.src = 'https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-MML-AM_CHTML'; 516 if (location.protocol !== 'file:' && /^https?:/.test(script.src)) 517 script.src = script.src.replace(/^https?:/, ''); 518 document.getElementsByTagName('head')[0].appendChild(script); 519})(); 520</script>
520 521 </body> 522</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.