Øvingsdata
I dette kapitlet bruker vi data fra gapminder. Gapminder ble grunnlagt i Stockholm i 2005 og samler global statistikk om blant annet helse, økonomisk utvikling og befolkningsutvikling. Du kan få tilgang til data fra Gapminder med følgende kommandoer:
install.packages("gapminder")
library(gapminder)
gapminderI Gapminder finnes variablene country, continent, year, lifeExp (levealder), pop (befolkningsstørrelse) og gdpPercap (BNP per innbygger). Disse dataene er våre øvingsdata.
| 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 én overordnet funksjon: ggplot(). Vi begynner med å skrive ggplot() og angi argumentet data. Når denne koden kjøres, får vi følgende figur.
ggplot(data=gapminder)
Over ser vi bare et tomt grått rektangel, noe som skyldes at grafen mangler to komponenter:
- Estetisk mapping:
aes() - Geometriske komponenter:
geom()
Vi fortsetter ved å legge til aes(), der vi angir at x er year og y er pop. Resultatet er fortsatt en tom graf, men nå med x-akse og y-akse spesifisert:
ggplot(data=gapminder,
aes(x=year,
y=pop))
Grafen er tom fordi den mangler geom(), som definerer geometriske komponenter. Vi legger til geom_points(), som spesifiserer at vi vil se punkter i grafen:
ggplot(data=gapminder,
aes(x=year,
y=pop)) +
geom_point()
Det betyr at man i ggplot() spesifiserer en datakilde, estetisk mapping (aes()) med blant annet x-akse og y-akse, og deretter legger til lag med geometriske komponenter (for eksempel geom_point()). Dermed har geom_point() arvet den estetiske mappingen fra ggplot()!
Labels (etiketter)
Etiketter tydeliggjør grafens innhold. Den engelske termen er labels, som heretter også brukes her. Labels angis med funksjonen labs(). Du kan angi labels for x-akse, y-akse, tittel, undertittel, 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 begynner å bli en del kodelinjer nå. For at det skal være tydelig hva som er nytt i hver kodeboks, vil det heretter markeres med kommentaren #NYTT.
Deaktiver scientific notation
Legg merke til y-aksen i forrige graf. Verdiene er presentert med scientific notation, som aktiveres for svært store eller svært små tall. Du kan deaktivere dette med kommandoen:
options(scipen=999)
Som nevnt over arver geom_point() den estetiske mappingen (aes()) fra ggplot(). Vi kan imidlertid overstyre denne mappingen ved å angi aes() i geom_point(). Da vil geom_point() ikke arve mappingen. Følgende graf er altså identisk med den forrige:
ggplot(data=gapminder) +
# NYTT
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.")
Å definere den estetiske mappingen øverst er en fordel, fordi man slipper å gjenta mappingen i hver geom().
La oss fargelegge punktene basert på kontinentet de tilhører. Dette gjøres i aes() ved å spesifisere at color=continent:
ggplot(data=gapminder, aes(x=year,
y=pop,
# NYTT
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øyre for grafen finnes fargekodingen, der labelen "continent" må justeres. Man kan angi 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.",
# NYTT
color="Kontinent")
I gapminder finnes det flere rader for hvert land. I neste trinn skal vi summere befolkningsstørrelsen på hvert kontinent for hvert kalenderår. For å gjøre dette bruker vi dplyr slik:
gapminder_summary <- gapminder |>
# Grupper på continent og year
group_by(continent, year) |>
# Beregn summen av 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 |
La oss beregne den totale befolkningen på hvert kontinent for hvert kalenderår:
ggplot(gapminder_summary,
aes(x=year,
y=population,
color=continent)) +
geom_point()
Vi legger til en linje mellom punktene for å se trenden tydeligere:
ggplot(gapminder_summary,
aes(x=year, y=population, color=continent)) +
geom_point() +
# NYTT
geom_line()
Med geom_text() kan du legge til tekst. Nå legger vi til geom_text() for å vise befolkningsstørrelsen ved hvert datapunkt. Også geom_text() har estetisk mapping. Her angir vi bare argumentet label, som vi definerer som variabelen population. X-verdien og y-verdien for geom_text() vil arves fra ggplot().
ggplot(gapminder_summary,
aes(x=year, y=population, color=continent)) +
geom_point() +
geom_line() +
# NYTT
geom_text(aes(label=population))
Vi gjentar nøyaktig samme prosedyre, men med geom_label() i stedet for geom_text(). Med geom_label() får teksten en bakgrunn som gjør den mer synlig:

Begge grafene over er suboptimale fordi labels er plassert for nær hverandre. Vi trenger en funksjon som automatisk kan skille labels fra hverandre. Dette finnes i ggrepel-pakken, der funksjonen geom_text_repel() automatisk skiller tekst fra hverandre. Pakken fjerner datapunkter som ikke kan visualiseres på en rimelig måte. Resultatet er som regel tilfredsstillende:
install.packages("ggrepel")
library(ggrepel)ggplot(gapminder_summary,
aes(x=year, y=population, color=continent)) +
geom_point() +
geom_line() +
# NYTT
geom_text_repel(aes(label=population))
Det er fortsatt utydelig. Muligens blir det tilstrekkelig informativt å bare rapportere tallene for første og siste år. Dette kan gjøres ved å beregne henholdsvis maksimalt og minimalt antall mennesker på hvert kontinent. Disse beregningene gjøres og sendes til objektene max_population og min_population, som deretter også brukes i ggplot():
## Beregner hvert kontinents største befolkning
max_population <- gapminder_summary %>%
group_by(continent) %>%
arrange(continent, desc(population)) %>%
distinct(continent, .keep_all = T)
## Beregner hvert kontinents minste befolkning
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() +
# NYTT
# Tekst for maksverdier
geom_label_repel(data=max_population,
aes(x=year, y=population, color=continent, label=population)) +
# NYTT
# Tekst for minimumsverdier
geom_label_repel(data=min_population,
aes(x=year, y=population, color=continent, label=population))
Vi skal nå bruke geom_hline() og geom_vline() for å legge til horisontale og vertikale referanselinjer. Disse plasseres gjerne bak datapunktene, noe som innebærer at de må deklareres før datapunktene (geom_point()) i koden. Vi plasserer linjer på to nivåer på y-aksen (spesifiseres med argumentet yintercept) slik:
ggplot(data=gapminder, aes(x=year,
y=pop,
color=continent)) +
geom_point() +
# NYTT
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, slik:
ggplot(data=gapminder, aes(x=year,
y=pop,
color=continent)) +
# NYTT
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ærlig interessante punkter. Funksjonen har argumentet arrow for å tegne piler.
Legg merke til at y-aksen viser et svært stort intervall med stor forskjell mellom datapunktene. I slike scenarioer er det en fordel å logaritmere variabelen. Vi logaritmerer y-aksen ved å legge til funksjonen scale_y_log10(), som logaritmerer alle y-verdier. Det innebærer at du kan gjøre matematiske beregninger i forbindelse med visualiseringen (datakilden endres ikke).
ggplot(data=gapminder, aes(x=year,
y=pop,
color=continent)) +
geom_point() +
# NYTT
scale_y_log10()