World map

The map_data function reads geographic data. Options include “world”, “world2” (Pacific centred), “usa”, “italy”, “nz”

library(tidyverse)
── Attaching packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.2.1 ──
✔ ggplot2 2.2.1     ✔ purrr   0.2.5
✔ tibble  1.4.2     ✔ dplyr   0.7.5
✔ tidyr   0.8.1     ✔ stringr 1.3.1
✔ readr   1.1.1     ✔ forcats 0.3.0
── Conflicts ────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
map_data("world2") %>% ggplot(aes(x=long, y=lat, group=group)) + geom_polygon()

Attaching package: ‘maps’

The following object is masked from ‘package:purrr’:

    map

head(map_data("world2"))
map_data("world") %>% 
  filter(region %in% c("Sweden", "Norway", "Finland", "Denmark")) %>%
  ggplot(aes(x=long, y=lat, group=group)) + geom_polygon()

data(world.cities)
world.cities %>% filter(country.etc=="Sweden")

When you’re overplotting two distinct layers (e.g. map polygons and text labels) it’s easier to set the data and mapping within the relevant geom_* function, otherwise things might be incorrectly inherited from one set of data to the other

# This plot with be distorted: choose the little gear icon and select "Use custom figure size" to fix this
map_data("world") %>% filter(region=="Sweden") -> sweden
world.cities %>% filter(country.etc=="Sweden") -> swedish.cities
ggplot() +
  geom_polygon(data=sweden, mapping=aes(x=long, y=lat, group=group)) +
  geom_label(data=swedish.cities, mapping=aes(x=long, y=lat, label=name))

(max(sweden$lat) - min(sweden$lat)) / (max(sweden$long) - min(sweden$long)) * 15
[1] 15.79

Those plots were with cartesian coordinates, a regular x-y grid. But maps of the world are taken from the surface of a sphere. Use coord_map() to correct the map to Mercator projection

map_data("world") %>% filter(region=="Sweden") -> sweden
world.cities %>% filter(country.etc=="Sweden") -> swedish.cities
ggplot() + coord_map() +
  geom_polygon(data=sweden, mapping=aes(x=long, y=lat, group=group)) +
  geom_label(data=swedish.cities, mapping=aes(x=long, y=lat, label=name))

A spherical map centred on Uppsala

map_data("world") %>% filter(region=="Sweden") -> sweden
world.cities %>% filter(country.etc=="Sweden") -> swedish.cities
ggplot() + coord_map("ortho", orientation=c(59, 17, 0)) +
  geom_polygon(data=sweden, mapping=aes(x=long, y=lat, group=group)) +
  geom_point(data=swedish.cities, mapping=aes(x=long, y=lat, size=pop), colour="yellow")

Let’s zoom out:

#map_data("world") %>% filter(region=="Sweden") -> sweden
world.cities %>% filter(country.etc=="Sweden") -> swedish.cities
ggplot() + coord_map("ortho", orientation=c(59, 17, 0)) +
  geom_polygon(data=map_data("world"), mapping=aes(x=long, y=lat, group=group)) +
  geom_point(data=swedish.cities, mapping=aes(x=long, y=lat), colour="yellow", size=0.3)

Eurostat library

# library(tidyverse)
library(eurostat)
toc <- get_eurostat_toc()
toc
# fixed=FALSE means "use regex", otherwise exact char match
search_eurostat("[Ll]anguage", type="dataset", fixed=FALSE)
# Number of foreign languages known (self-reported) by degree of urbanisation
dat <- get_eurostat(id="edat_aes_l26", time_format="num")
trying URL 'https://ec.europa.eu/eurostat/estat-navtree-portlet-prod/BulkDownloadListing?sort=1&file=data%2Fedat_aes_l26.tsv.gz'
Content type 'application/octet-stream;charset=UTF-8' length 5233 bytes
==================================================
downloaded 5233 bytes

Table edat_aes_l26 cached at /var/folders/40/g5h19fsj5yl8_tr49ny3jqx0h1wp05/T//Rtmpp2FLxB/eurostat/edat_aes_l26_num_code_TF.rds
dat
dat <- label_eurostat(dat, lang="en")
dat
levels(dat$deg_urb)
[1] "Cities"            "Towns and suburbs" "Rural areas"       "Total"            
levels(dat$geo)
 [1] "Albania"                                          "Austria"                                         
 [3] "Bosnia and Herzegovina"                           "Belgium"                                         
 [5] "Bulgaria"                                         "Switzerland"                                     
 [7] "Cyprus"                                           "Czechia"                                         
 [9] "Germany (until 1990 former territory of the FRG)" "Denmark"                                         
[11] "Euro area (19 countries)"                         "Estonia"                                         
[13] "Greece"                                           "Spain"                                           
[15] "European Union (current composition)"             "Finland"                                         
[17] "France"                                           "Croatia"                                         
[19] "Hungary"                                          "Italy"                                           
[21] "Lithuania"                                        "Luxembourg"                                      
[23] "Latvia"                                           "Former Yugoslav Republic of Macedonia, the"      
[25] "Malta"                                            "Netherlands"                                     
[27] "Norway"                                           "Poland"                                          
[29] "Portugal"                                         "Romania"                                         
[31] "Serbia"                                           "Sweden"                                          
[33] "Slovenia"                                         "Slovakia"                                        
[35] "United Kingdom"                                   "Ireland"                                         
[37] "Turkey"                                          
scandinavia <- c("Sweden", "Finland", "Denmark", "Norway")
dat %>% 
  filter(deg_urb != "Total") %>%
  filter(geo %in% scandinavia) %>%
  ggplot(aes(x=time, y=values, colour=n_lang)) + geom_line() + facet_grid(deg_urb ~ geo)

from help(geom_bar):

There are two types of bar charts: geom_bar makes the height of the bar proportional to the number of cases in each group (or if the weight aethetic is supplied, the sum of the weights). If you want the heights of the bars to represent values in the data, use geom_col instead. geom_bar uses stat_count by default: it counts the number of cases at each x position. geom_col uses stat_identity: it leaves the data as is

dat %>% 
  filter(deg_urb != "Total") %>%
  filter(geo %in% scandinavia) %>%
  ggplot(aes(x=time, y=values, fill=n_lang)) + geom_col() + facet_grid(deg_urb ~ geo)

Try this yourself:

Foreign language learning ISCED: https://en.wikipedia.org/wiki/International_Standard_Classification_of_Education

# search_eurostat("[Ll]anguage", type="dataset", fixed=FALSE)
dat <- get_eurostat("educ_thfrlan", time_format="num")
trying URL 'https://ec.europa.eu/eurostat/estat-navtree-portlet-prod/BulkDownloadListing?sort=1&file=data%2Feduc_thfrlan.tsv.gz'
Content type 'application/octet-stream;charset=UTF-8' length 4428 bytes
==================================================
downloaded 4428 bytes

Table educ_thfrlan cached at /var/folders/40/g5h19fsj5yl8_tr49ny3jqx0h1wp05/T//Rtmpp2FLxB/eurostat/educ_thfrlan_num_code_TF.rds
dat <- label_eurostat(dat, lang="en")
dat
LS0tCnRpdGxlOiAiOCBHZW9ncmFwaHkiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIFdvcmxkIG1hcAoKVGhlIGBtYXBfZGF0YWAgZnVuY3Rpb24gcmVhZHMgZ2VvZ3JhcGhpYyBkYXRhLiBPcHRpb25zIGluY2x1ZGUgIndvcmxkIiwgIndvcmxkMiIgKFBhY2lmaWMgY2VudHJlZCksICJ1c2EiLCAiaXRhbHkiLCAibnoiCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCm1hcF9kYXRhKCJ3b3JsZDIiKSAlPiUgZ2dwbG90KGFlcyh4PWxvbmcsIHk9bGF0LCBncm91cD1ncm91cCkpICsgZ2VvbV9wb2x5Z29uKCkKYGBgCmBgYHtyfQpoZWFkKG1hcF9kYXRhKCJ3b3JsZDIiKSkKYGBgCgpgYGB7cn0KbWFwX2RhdGEoIndvcmxkIikgJT4lIAogIGZpbHRlcihyZWdpb24gJWluJSBjKCJTd2VkZW4iLCAiTm9yd2F5IiwgIkZpbmxhbmQiLCAiRGVubWFyayIpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9bG9uZywgeT1sYXQsIGdyb3VwPWdyb3VwKSkgKyBnZW9tX3BvbHlnb24oKQpgYGAKCmBgYHtyfQpkYXRhKHdvcmxkLmNpdGllcykKd29ybGQuY2l0aWVzICU+JSBmaWx0ZXIoY291bnRyeS5ldGM9PSJTd2VkZW4iKQpgYGAKCldoZW4geW91J3JlIG92ZXJwbG90dGluZyB0d28gZGlzdGluY3QgbGF5ZXJzIChlLmcuIG1hcCBwb2x5Z29ucyBhbmQgdGV4dCBsYWJlbHMpIGl0J3MgZWFzaWVyIHRvIHNldCB0aGUgZGF0YSBhbmQgbWFwcGluZyAqd2l0aGluKiB0aGUgcmVsZXZhbnQgYGdlb21fKmAgZnVuY3Rpb24sIG90aGVyd2lzZSB0aGluZ3MgbWlnaHQgYmUgaW5jb3JyZWN0bHkgaW5oZXJpdGVkIGZyb20gb25lIHNldCBvZiBkYXRhIHRvIHRoZSBvdGhlcgoKYGBge3IgZmlnLmhlaWdodD0xNiwgZmlnLndpZHRoPTE1fQojIFRoaXMgcGxvdCB3aXRoIGJlIGRpc3RvcnRlZDogY2hvb3NlIHRoZSBsaXR0bGUgZ2VhciBpY29uIGFuZCBzZWxlY3QgIlVzZSBjdXN0b20gZmlndXJlIHNpemUiIHRvIGZpeCB0aGlzCm1hcF9kYXRhKCJ3b3JsZCIpICU+JSBmaWx0ZXIocmVnaW9uPT0iU3dlZGVuIikgLT4gc3dlZGVuCndvcmxkLmNpdGllcyAlPiUgZmlsdGVyKGNvdW50cnkuZXRjPT0iU3dlZGVuIikgLT4gc3dlZGlzaC5jaXRpZXMKZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhPXN3ZWRlbiwgbWFwcGluZz1hZXMoeD1sb25nLCB5PWxhdCwgZ3JvdXA9Z3JvdXApKSArCiAgZ2VvbV9sYWJlbChkYXRhPXN3ZWRpc2guY2l0aWVzLCBtYXBwaW5nPWFlcyh4PWxvbmcsIHk9bGF0LCBsYWJlbD1uYW1lKSkKYGBgCgpgYGB7cn0KKG1heChzd2VkZW4kbGF0KSAtIG1pbihzd2VkZW4kbGF0KSkgLyAobWF4KHN3ZWRlbiRsb25nKSAtIG1pbihzd2VkZW4kbG9uZykpICogMTUKYGBgCgpUaG9zZSBwbG90cyB3ZXJlIHdpdGggKmNhcnRlc2lhbiogY29vcmRpbmF0ZXMsIGEgcmVndWxhciB4LXkgZ3JpZC4gQnV0IG1hcHMgb2YgdGhlIHdvcmxkIGFyZSB0YWtlbiBmcm9tIHRoZSBzdXJmYWNlIG9mIGEgc3BoZXJlLiBVc2UgYGNvb3JkX21hcCgpYCB0byBjb3JyZWN0IHRoZSBtYXAgdG8gTWVyY2F0b3IgcHJvamVjdGlvbgoKYGBge3IgZmlnLmhlaWdodD0xNiwgZmlnLndpZHRoPTE1fQptYXBfZGF0YSgid29ybGQiKSAlPiUgZmlsdGVyKHJlZ2lvbj09IlN3ZWRlbiIpIC0+IHN3ZWRlbgp3b3JsZC5jaXRpZXMgJT4lIGZpbHRlcihjb3VudHJ5LmV0Yz09IlN3ZWRlbiIpIC0+IHN3ZWRpc2guY2l0aWVzCmdncGxvdCgpICsgY29vcmRfbWFwKCkgKwogIGdlb21fcG9seWdvbihkYXRhPXN3ZWRlbiwgbWFwcGluZz1hZXMoeD1sb25nLCB5PWxhdCwgZ3JvdXA9Z3JvdXApKSArCiAgZ2VvbV9sYWJlbChkYXRhPXN3ZWRpc2guY2l0aWVzLCBtYXBwaW5nPWFlcyh4PWxvbmcsIHk9bGF0LCBsYWJlbD1uYW1lKSkKYGBgCgpBIHNwaGVyaWNhbCBtYXAgY2VudHJlZCBvbiBVcHBzYWxhCgpgYGB7ciBmaWcuaGVpZ2h0PTE2LCBmaWcud2lkdGg9MTV9Cm1hcF9kYXRhKCJ3b3JsZCIpICU+JSBmaWx0ZXIocmVnaW9uPT0iU3dlZGVuIikgLT4gc3dlZGVuCndvcmxkLmNpdGllcyAlPiUgZmlsdGVyKGNvdW50cnkuZXRjPT0iU3dlZGVuIikgLT4gc3dlZGlzaC5jaXRpZXMKZ2dwbG90KCkgKyBjb29yZF9tYXAoIm9ydGhvIiwgb3JpZW50YXRpb249Yyg1OSwgMTcsIDApKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9c3dlZGVuLCBtYXBwaW5nPWFlcyh4PWxvbmcsIHk9bGF0LCBncm91cD1ncm91cCkpICsKICBnZW9tX3BvaW50KGRhdGE9c3dlZGlzaC5jaXRpZXMsIG1hcHBpbmc9YWVzKHg9bG9uZywgeT1sYXQsIHNpemU9cG9wKSwgY29sb3VyPSJ5ZWxsb3ciKQpgYGAKTGV0J3Mgem9vbSBvdXQ6CgpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTB9CiNtYXBfZGF0YSgid29ybGQiKSAlPiUgZmlsdGVyKHJlZ2lvbj09IlN3ZWRlbiIpIC0+IHN3ZWRlbgp3b3JsZC5jaXRpZXMgJT4lIGZpbHRlcihjb3VudHJ5LmV0Yz09IlN3ZWRlbiIpIC0+IHN3ZWRpc2guY2l0aWVzCmdncGxvdCgpICsgY29vcmRfbWFwKCJvcnRobyIsIG9yaWVudGF0aW9uPWMoNTksIDE3LCAwKSkgKwogIGdlb21fcG9seWdvbihkYXRhPW1hcF9kYXRhKCJ3b3JsZCIpLCBtYXBwaW5nPWFlcyh4PWxvbmcsIHk9bGF0LCBncm91cD1ncm91cCkpICsKICBnZW9tX3BvaW50KGRhdGE9c3dlZGlzaC5jaXRpZXMsIG1hcHBpbmc9YWVzKHg9bG9uZywgeT1sYXQpLCBjb2xvdXI9InllbGxvdyIsIHNpemU9MC4zKQpgYGAKCiMjIEV1cm9zdGF0IGxpYnJhcnkKCmBgYHtyfQojIGxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGV1cm9zdGF0KQp0b2MgPC0gZ2V0X2V1cm9zdGF0X3RvYygpCnRvYwpgYGAKYGBge3J9CiMgZml4ZWQ9RkFMU0UgbWVhbnMgInVzZSByZWdleCIsIG90aGVyd2lzZSBleGFjdCBjaGFyIG1hdGNoCnNlYXJjaF9ldXJvc3RhdCgiW0xsXWFuZ3VhZ2UiLCB0eXBlPSJkYXRhc2V0IiwgZml4ZWQ9RkFMU0UpCmBgYAoKCmBgYHtyfQojIE51bWJlciBvZiBmb3JlaWduIGxhbmd1YWdlcyBrbm93biAoc2VsZi1yZXBvcnRlZCkgYnkgZGVncmVlIG9mIHVyYmFuaXNhdGlvbgpkYXQgPC0gZ2V0X2V1cm9zdGF0KGlkPSJlZGF0X2Flc19sMjYiLCB0aW1lX2Zvcm1hdD0ibnVtIikKZGF0CmBgYApgYGB7cn0KZGF0IDwtIGxhYmVsX2V1cm9zdGF0KGRhdCwgbGFuZz0iZW4iKQpkYXQKYGBgCmBgYHtyfQpsZXZlbHMoZGF0JGRlZ191cmIpCmBgYApgYGB7cn0KbGV2ZWxzKGRhdCRnZW8pCmBgYAoKYGBge3J9CnNjYW5kaW5hdmlhIDwtIGMoIlN3ZWRlbiIsICJGaW5sYW5kIiwgIkRlbm1hcmsiLCAiTm9yd2F5IikKZGF0ICU+JSAKICBmaWx0ZXIoZGVnX3VyYiAhPSAiVG90YWwiKSAlPiUKICBmaWx0ZXIoZ2VvICVpbiUgc2NhbmRpbmF2aWEpICU+JQogIGdncGxvdChhZXMoeD10aW1lLCB5PXZhbHVlcywgY29sb3VyPW5fbGFuZykpICsgZ2VvbV9saW5lKCkgKyBmYWNldF9ncmlkKGRlZ191cmIgfiBnZW8pCmBgYAoKZnJvbSBgaGVscChnZW9tX2JhcilgOgoKICBUaGVyZSBhcmUgdHdvIHR5cGVzIG9mIGJhciBjaGFydHM6IGdlb21fYmFyIG1ha2VzIHRoZSBoZWlnaHQgb2YgdGhlIGJhciBwcm9wb3J0aW9uYWwgdG8gdGhlIG51bWJlciBvZiBjYXNlcyBpbiBlYWNoIGdyb3VwIChvciBpZiB0aGUgd2VpZ2h0IGFldGhldGljIGlzIHN1cHBsaWVkLCB0aGUgc3VtIG9mIHRoZSB3ZWlnaHRzKS4gSWYgeW91IHdhbnQgdGhlIGhlaWdodHMgb2YgdGhlIGJhcnMgdG8gcmVwcmVzZW50IHZhbHVlcyBpbiB0aGUgZGF0YSwgdXNlIGdlb21fY29sIGluc3RlYWQuIGdlb21fYmFyIHVzZXMgc3RhdF9jb3VudCBieSBkZWZhdWx0OiBpdCBjb3VudHMgdGhlIG51bWJlciBvZiBjYXNlcyBhdCBlYWNoIHggcG9zaXRpb24uIGdlb21fY29sIHVzZXMgc3RhdF9pZGVudGl0eTogaXQgbGVhdmVzIHRoZSBkYXRhIGFzIGlzCgpgYGB7cn0KZGF0ICU+JSAKICBmaWx0ZXIoZGVnX3VyYiAhPSAiVG90YWwiKSAlPiUKICBmaWx0ZXIoZ2VvICVpbiUgc2NhbmRpbmF2aWEpICU+JQogIGdncGxvdChhZXMoeD10aW1lLCB5PXZhbHVlcywgZmlsbD1uX2xhbmcpKSArIGdlb21fY29sKCkgKyBmYWNldF9ncmlkKGRlZ191cmIgfiBnZW8pCmBgYAoKIyMgVHJ5IHRoaXMgeW91cnNlbGY6CgoqKkZvcmVpZ24gbGFuZ3VhZ2UgbGVhcm5pbmcqKgpJU0NFRDogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSW50ZXJuYXRpb25hbF9TdGFuZGFyZF9DbGFzc2lmaWNhdGlvbl9vZl9FZHVjYXRpb24KYGBge3J9CiMgc2VhcmNoX2V1cm9zdGF0KCJbTGxdYW5ndWFnZSIsIHR5cGU9ImRhdGFzZXQiLCBmaXhlZD1GQUxTRSkKZGF0IDwtIGdldF9ldXJvc3RhdCgiZWR1Y190aGZybGFuIiwgdGltZV9mb3JtYXQ9Im51bSIpCmRhdCA8LSBsYWJlbF9ldXJvc3RhdChkYXQsIGxhbmc9ImVuIikKZGF0CmBgYAotIENoZWNrIGNvbHVtbiBuYW1lcwotIENoZWNrIGxldmVscwotIFdoYXQgcmVsYXRpb25zaGlwcyBjYW4geW91IHNob3c/Ci0gRmlsdGVyIG91dCB1bndhbnRlZC9pcnJlbGV2YW50IGxldmVscwotIFBsb3QhISEKCg==