Øvelsesdata
I dette kapitel bruger vi data fra gapminder. Gapminder blev grundlagt i Stockholm i 2005 og indsamler global statistik om blandt andet sundhed, økonomisk udvikling og befolkningsudvikling. Du kan få adgang til data fra Gapminder med følgende kommandoer:
install.packages("gapminder")
library(gapminder)
gapminderI Gapminder findes variablerne country, continent, year, lifeExp (levetid), pop (befolkningsstørrelse) og gdpPercap (BNP per indbygger). Disse data er vores øvelsesdata.
| country | continent | year | lifeExp | pop | gdpPercap |
|---|---|---|---|---|---|
| Afghanistan | Asia | 1952 | 28.80100 | 8425333 | 779.4453 |
| Afghanistan | Asia | 1957 | 30.33200 | 9240934 | 820.8530 |
| Afghanistan | Asia | 1962 | 31.99700 | 10267083 | 853.1007 |
| Afghanistan | Asia | 1967 | 34.02000 | 11537966 | 836.1971 |
| Afghanistan | Asia | 1972 | 36.08800 | 13079460 | 739.9811 |
| Afghanistan | Asia | 1977 | 38.43800 | 14880372 | 786.1134 |
| Afghanistan | Asia | 1982 | 39.85400 | 12881816 | 978.0114 |
| Afghanistan | Asia | 1987 | 40.82200 | 13867957 | 852.3959 |
| Afghanistan | Asia | 1992 | 41.67400 | 16317921 | 649.3414 |
| Afghanistan | Asia | 1997 | 41.76300 | 22227415 | 635.3414 |
| Afghanistan | Asia | 2002 | 42.12900 | 25268405 | 726.7341 |
| Afghanistan | Asia | 2007 | 43.82800 | 31889923 | 974.5803 |
| Albania | Europe | 1952 | 55.23000 | 1282697 | 1601.0561 |
| Albania | Europe | 1957 | 59.28000 | 1476505 | 1942.2842 |
| Albania | Europe | 1962 | 64.82000 | 1728137 | 2312.8890 |
| Albania | Europe | 1967 | 66.22000 | 1984060 | 2760.1969 |
| Albania | Europe | 1972 | 67.69000 | 2263554 | 3313.4222 |
| Albania | Europe | 1977 | 68.93000 | 2509048 | 3533.0039 |
| Albania | Europe | 1982 | 70.42000 | 2780097 | 3630.8807 |
| Albania | Europe | 1987 | 72.00000 | 3075321 | 3738.9327 |
| Albania | Europe | 1992 | 71.58100 | 3326498 | 2497.4379 |
| Albania | Europe | 1997 | 72.95000 | 3428038 | 3193.0546 |
| Albania | Europe | 2002 | 75.65100 | 3508512 | 4604.2117 |
| Albania | Europe | 2007 | 76.42300 | 3600523 | 5937.0295 |
Pakken ggplot2 har en overordnet funktion: ggplot(). Vi begynder med at skrive ggplot() og angive argumentet data. Når den kode køres, får vi følgende figur.
ggplot(data=gapminder)
Ovenfor ser vi kun et tomt gråt rektangel, hvilket skyldes, at grafen mangler to komponenter:
- Æstetisk mapping:
aes() - Geometriske komponenter:
geom()
Vi fortsætter ved at tilføje aes(), hvor vi angiver, at x er year og y er pop. Resultatet er fortsat en tom graf, men nu med x-akse og y-akse specificeret:
ggplot(data=gapminder,
aes(x=year,
y=pop))
Grafen er tom, fordi den mangler geom(), som definerer geometriske komponenter. Vi tilføjer geom_points(), som specificerer, at vi vil se punkter på grafen:
ggplot(data=gapminder,
aes(x=year,
y=pop)) +
geom_point()
Det betyder, at man i ggplot() specificerer en datakilde, en æstetisk mapping (aes()) med blandt andet x-akse og y-akse, og derefter tilføjer lag med geometriske komponenter (eksempelvis geom_point()). Således har geom_point() arvet den æstetiske mapping fra ggplot()!
Labels (etiketter)
Etiketter tydeliggør grafens indhold. Den engelske betegnelse er labels, som herefter også bruges her. Labels angives med funktionen labs(). Du kan angive labels for x-akse, y-akse, titel, undertitel, figurforklaring osv. Eksempel følger:
ggplot(data=gapminder,
aes(x=year,
y=pop)) +
geom_point() +
labs(x="Year",
y="Population",
tag="A",
title="Titeln på grafen",
subtitle="Undertiteln på grafen",
caption="Figurförklaring hamnar här.")
Det begynder at blive en del linjer kode nu. For at det skal være tydeligt, hvad der er nyt i hver kodeboks, vil det herefter blive markeret med kommentaren #NYT.
Deaktiver Scientific notation
Bemærk y-aksen på den foregående graf. Værdierne er præsenteret med scientific notation, som aktiveres ved meget store eller meget små tal. Du kan deaktivere dette med kommandoen:
options(scipen=999)
Som nævnt ovenfor arver geom_point() den æstetiske mapping (aes()) fra ggplot(). Vi kan dog tilsidesætte denne mapping ved at angive aes() i geom_point(). Så vil geom_point() ikke arve mappingen. Følgende graf er altså identisk med den foregående:
ggplot(data=gapminder) +
# NYT
geom_point(aes(x=year,
y=pop)) +
labs(x="Year",
y="Population",
tag="A",
title="Titeln på grafen",
subtitle="Undertiteln på grafen",
caption="Figurförklaring hamnar här.")
Det er en fordel at definere den æstetiske mapping øverst, fordi man så slipper for at gentage mappingen i hver geom().
Lad os farve punkterne efter det kontinent, de tilhører. Det gøres i aes() ved at specificere color=continent:
ggplot(data=gapminder, aes(x=year,
y=pop,
# NYT
color=continent)) +
geom_point() +
labs(x="Year",
y="Population",
tag="A",
title="Titeln på grafen",
subtitle="Undertiteln på grafen",
caption="Figurförklaring hamnar här.")
Til højre for grafen findes farvekodningen, hvis label "continent" skal justeres. Man kan angive en label i labs() med argumentet color.
ggplot(data=gapminder, aes(x=year,
y=pop,
color=continent)) +
geom_point() +
labs(x="Year",
y="Population",
tag="A",
title="Titeln på grafen",
subtitle="Undertiteln på grafen",
caption="Figurförklaring hamnar här.",
# NYT
color="Kontinent")
I gapminder findes flere rækker for hvert land. I næste trin skal vi summere befolkningsstørrelsen på hvert kontinent for hvert kalenderår. Til det bruger vi dplyr på følgende måde:
gapminder_summary <- gapminder |>
# Gruppér efter continent og year
group_by(continent, year) |>
# Beregn summen af pop (for hvert kontinent og år)
summarise(population = sum(pop)) |>
# Deaktiver grupperingen i data framen
ungroup()
## Se data
gapminder_summary| continent | year | population |
|---|---|---|
| Africa | 1952 | 237640501 |
| Africa | 1957 | 264837738 |
| Africa | 1962 | 296516865 |
| Africa | 1967 | 335289489 |
| Africa | 1972 | 379879541 |
| Africa | 1977 | 433061021 |
| Africa | 1982 | 499348587 |
| Africa | 1987 | 574834110 |
| Africa | 1992 | 659081517 |
| Africa | 1997 | 743832984 |
| Africa | 2002 | 833723916 |
| Africa | 2007 | 929539692 |
| Americas | 1952 | 345152446 |
| Americas | 1957 | 386953916 |
| Americas | 1962 | 433270254 |
| Americas | 1967 | 480746623 |
| Americas | 1972 | 529384210 |
Lad os beregne den samlede befolkning på hvert kontinent for hvert kalenderår:
ggplot(gapminder_summary,
aes(x=year,
y=population,
color=continent)) +
geom_point()
Vi tilføjer en linje mellem punkterne for at se tendensen tydeligere:
ggplot(gapminder_summary,
aes(x=year, y=population, color=continent)) +
geom_point() +
# NYT
geom_line()
Med geom_text() kan du tilføje tekst. Nu tilføjer vi geom_text() for at vise befolkningsstørrelsen ved hvert datapunkt. Også geom_text() har æstetisk mapping. Her angiver vi kun argumentet label, som vi definerer som variablen population. X-værdien og y-værdien for geom_text() vil blive arvet fra ggplot().
ggplot(gapminder_summary,
aes(x=year, y=population, color=continent)) +
geom_point() +
geom_line() +
# NYT
geom_text(aes(label=population))
Vi gentager nøjagtig samme procedure, men med geom_label() i stedet for geom_text(). Med geom_label() får teksten en baggrund, der gør den mere synlig:

Begge ovenstående grafer er suboptimale, fordi labels er placeret for tæt på hinanden. Vi har brug for en funktion, der automatisk kan adskille labels. Det findes i ggrepel-pakken, hvis funktion geom_text_repel() automatisk adskiller tekst. Pakken fjerner datapunkter, som ikke kan visualiseres på en rimelig måde. Resultatet er som regel tilfredsstillende:
install.packages("ggrepel")
library(ggrepel)ggplot(gapminder_summary,
aes(x=year, y=population, color=continent)) +
geom_point() +
geom_line() +
# NYT
geom_text_repel(aes(label=population))
Det er stadig utydeligt. Muligvis bliver det tilstrækkeligt informativt kun at angive tallene for det første og det sidste år. Det kan gøres ved at beregne det maksimale henholdsvis minimale antal mennesker på hvert kontinent. Disse beregninger udføres og gemmes i objekterne max_population og min_population, som derefter også bruges i ggplot():
## Beregner hvert kontinents største population
max_population <- gapminder_summary %>%
group_by(continent) %>%
arrange(continent, desc(population)) %>%
distinct(continent, .keep_all = T)
## Beregner hvert kontinents mindste population
min_population <- gapminder_summary %>%
group_by(continent) %>%
arrange(continent, population) %>%
distinct(continent, .keep_all = T)
## Visualiserer
ggplot(gapminder_summary,
aes(x=year, y=population, color=continent)) +
geom_point() +
# NYT
# Tekst for maksimumværdier
geom_label_repel(data=max_population,
aes(x=year, y=population, color=continent, label=population)) +
# NYT
# Tekst for minimumværdier
geom_label_repel(data=min_population,
aes(x=year, y=population, color=continent, label=population))
Vi skal nu bruge geom_hline() og geom_vline() til at tilføje vandrette og lodrette referencelinjer. De placeres som regel bag datapunkterne, hvilket betyder, at de skal deklareres før datapunkterne (geom_point()) i koden. Vi placerer linjer på to niveauer på y-aksen (specificeres med argumentet yintercept) som vist nedenfor:
ggplot(data=gapminder, aes(x=year,
y=pop,
color=continent)) +
geom_point() +
# NYT
geom_hline(aes(yintercept=1000000000)) +
geom_hline(aes(yintercept=500000000)) +
labs(x="Year",
y="Population",
tag="A",
title="Titeln på grafen",
subtitle="Undertiteln på grafen",
caption="Figurförklaring hamnar här.")
Med geom_rect() kan et felt defineres på følgende måde:
ggplot(data=gapminder, aes(x=year,
y=pop,
color=continent)) +
# NYT
geom_rect(aes(xmin=1960, xmax=1990, ymin=500000000, ymax=100000000)) +
geom_point() +
labs(x="Year",
y="Population",
tag="A",
title="Titeln på grafen",
subtitle="Undertiteln på grafen",
caption="Figurförklaring hamnar här.")
Med geom_segment() kan du markere særligt interessante punkter. Funktionen har argumentet arrow til at tegne pile.
Bemærk, at y-aksen udviser et meget stort interval med stor forskel mellem datapunkterne. I sådanne scenarier er det en fordel at logaritmere variablen. Vi logaritmerer y-aksen ved at tilføje funktionen scale_y_log10(), som logaritmerer alle y-værdier. Det betyder, at du kan udføre matematiske beregninger i forbindelse med visualiseringen (datakilden ændres ikke).
ggplot(data=gapminder, aes(x=year,
y=pop,
color=continent)) +
geom_point() +
# NYT
scale_y_log10()