Grafieken in R

Albart Coster

John Bastiaansen

Grafieken in R

In R zijn verschillende mogelijkheden om grafieken te maken, wij gebruiken het pakket ggplot2

install.packages("ggplot2")
require(ggplot2)

Het pakket is geschreven door Hadley Wickham en wordt op dit moment veel gebruikt om grafieken in R te maken. Zie de handleiding ?ggplot2 of de website van het pakket http://ggplot2.org/.

Ophalen van gegevens

We gebruiken opnieuw de gegevens uit het bestand http://rworkshop.dairyconsult.nl/bestanden/melkproducties.dat, te vinden op http://rworkshop.dairyconsult.nl/bestanden/. Download dit en sla het op een logische plaats op. Met een werkende internet verbinding is het ook mogelijk om bestanden direct vanaf het web in te lezen:

df <- read.table("http://rworkshop.dairyconsult.nl/bestanden/melkproducties.dat", 
    header = TRUE)
df <- read.table("melkproducties.dat", header = TRUE)

Grafiek van laatste melkcontrole

Stel dat we grafieken van de melkproducties op de laatste melkcontrole willen maken. Daarvoor moeten we eerst de datum van de laatste melkcontrole weten, vervolgens kunnen we die gegevens selecteren en gebruiken:

d <- max(df$DATUM)
## Error: max not meaningful for factors

Dit levert een probleem op,we moeten R vertellen dat kolom DATUM geen factor is maar een kolom met datums:

class(df$DATUM)
## [1] "factor"
df$DATUM <- as.Date(df$DATUM, "%Y-%m-%d")
class(df$DATUM)
## [1] "Date"
d <- max(df$DATUM)
df1 <- df[df$DATUM == d, ]
p <- ggplot(data = df1, aes(x = DIL, y = PROD_KG))
p + geom_point()
## Warning: Removed 13 rows containing missing values (geom_point).
plot of chunk gr3a

plot of chunk gr3a

p is de basisgrafiek, het aes argument in functie ggplot geeft aan dat we een grafiek willen maken waar de x-as door DIL wordt gevormd en de y-as door PROD_KG. Functie geom_point vertelt dat we een puntengrafiek aan p willen toevoegen.

We krijgen een waarschuwing omdat sommige waardes van PROD_KG NA zijn, het is handig om deze regels uit de tabel te verwijderen, dan krijgen we deze melding niet meer:

df1 <- df1[!is.na(df1$PROD_KG), ]
df <- df[!is.na(df$PROD_KG), ]
p <- ggplot(data = df1, aes(x = DIL, y = PROD_KG))

Verbeterde grafiek

De vorige grafiek geeft gegevens van dieren van verschillende leeftijden weer, stel dat we nu een kleur per laktatienummer willen toekennen, opnieuw via functie geom_point:

p + geom_point(aes(colour = NLACT))
plot of chunk gr4

plot of chunk gr4

Dit is niet helemaal zoals we het willen, doordat R de laktatienummers ziet als getallen, terwijl hij ze moet zien als factoren:

p + geom_point(aes(colour = factor(NLACT)))
plot of chunk gr5

plot of chunk gr5

Net zoals in vorige onderdeel is het aantal laktatienummers te groot, we gaan dit beperken tot 3:

df$NLACTcat <- cut(df$NLACT, c(0, 1, 2, 20), labels = c(1, 2, "3+"))
df1 <- df[df$DATUM == d, ]
p <- ggplot(data = df1, aes(x = DIL, y = PROD_KG))
p + geom_point(aes(colour = NLACTcat))
plot of chunk gr6

plot of chunk gr6

Aanpassingen aan de grafiek

De x-as van de grafiek gaat van 0 tot bijna 1000 DIL, we kunnen de range van de x-as aanpassen met de xlim functie, en de range van de y-as met de ylim functie. We voegen geom_point(aes(colour = NLACTcat)) eerst permanent toe aan de grafiek:

p <- p + geom_point(aes(colour = NLACTcat))
p + xlim(c(0, 365)) + ylim(c(0, 60))
## Warning: Removed 67 rows containing missing values (geom_point).
plot of chunk gr6a

plot of chunk gr6a

Verder is er de labs functie om labels van de grafiek aan te passen:

p + xlim(c(0, 365)) + ylim(c(0, 60)) + labs(x = "Dagen in laktatie", y = "Dagproductie (kg/dag)", 
    title = "Grafiek van de melkproductie")
## Warning: Removed 67 rows containing missing values (geom_point).
plot of chunk gr6b

plot of chunk gr6b

We kunnen de legende ook aanpassen of verwijderen

p + theme(legend.position = "none")
plot of chunk gr6c

plot of chunk gr6c

p + theme(legend.position = "top")
plot of chunk gr6c

plot of chunk gr6c

p + theme(legend.position = c(0.9, 0.8))
plot of chunk gr6c

plot of chunk gr6c

Trendlijn

Het kan handig zijn om een soort gemiddelde weer te geven, hier gebruiken we een methode die het gemiddelde op 1 punt berekent op basis van omliggende punten, waarbij de invloed van punten met de afstand tot het punt afneemt, loess.

p + geom_point(aes(x = DIL, y = PROD_KG, colour = NLACTcat)) + stat_smooth()
## geom_smooth: method="auto" and size of largest group is <1000, so
## using loess. Use 'method = x' to change the smoothing method.
plot of chunk gr7

plot of chunk gr7

De lijntjes zijn wat te dun, en we zien liever niet die betrouwbaarheidsgrens eromheen:

p + geom_point(aes(x = DIL, y = PROD_KG, colour = NLACTcat)) + stat_smooth(size = 1.2, 
    se = FALSE)
## geom_smooth: method="auto" and size of largest group is <1000, so
## using loess. Use 'method = x' to change the smoothing method.
plot of chunk gr8

plot of chunk gr8

Het is duidelijk dat het gemiddelde na ca 400 DIL niet meer interessant is:

p + geom_point(aes(x = DIL, y = PROD_KG, colour = NLACTcat)) + stat_smooth(size = 1.2, 
    se = FALSE, data = df1[df1$DIL < 400, ])
## geom_smooth: method="auto" and size of largest group is <1000, so
## using loess. Use 'method = x' to change the smoothing method.
plot of chunk gr9

plot of chunk gr9

En verder willen we graag een gemiddelde voor elk laktatienummer:

p + geom_point(aes(x = DIL, y = PROD_KG, colour = NLACTcat)) + stat_smooth(size = 1.2, 
    se = FALSE, data = df1[df1$DIL < 400, ], aes(colour = NLACTcat))
## geom_smooth: method="auto" and size of largest group is <1000, so
## using loess. Use 'method = x' to change the smoothing method.
plot of chunk gr10

plot of chunk gr10

We kunnen het gemiddelde ook schatten met een rechte lijn, door middel van regressie:

p + geom_point(aes(x = DIL, y = PROD_KG, colour = NLACTcat)) + stat_smooth(method = "lm", 
    size = 1.2, se = FALSE, data = df1[df1$DIL < 400, ], aes(colour = NLACTcat))
plot of chunk gr10a

plot of chunk gr10a

Samenvattingen

Soms willen we grafieken van gemiddeldes zien, bijvoorbeeld de gemiddelde melkproductie per melkcontrole. Hiervoor is functie stat_summary, en binnen die functie moeten we aangeven dat we het gemiddelde willen berekenen met functie mean:

p1 <- ggplot(data = df, aes(x = DATUM, y = PROD_KG))
p1 + stat_summary(fun.y = "mean", geom = "point", size = 3, colour = "red")
plot of chunk gr11

plot of chunk gr11

p1 + stat_summary(fun.y = "mean", geom = "bar", colour = "red", fill = "red")
plot of chunk gr11

plot of chunk gr11

We kunnen ook een gemiddelde per lakatienummer maken:

p2 <- ggplot(data = df, aes(x = as.numeric(DATUM), y = PROD_KG, colour = NLACTcat))
p2 + stat_summary(fun.y = "mean", geom = "point", size = 3)
plot of chunk gr11a

plot of chunk gr11a

Soms kan het interessant zijn om gegevens van individuele dieren weer te geven. Stel dat we de gemiddelde melkproductie van elk laktatienummer per datum willen weergeven.

p1 <- ggplot(data = df, aes(x = DATUM, y = PROD_KG, colour = NLACTcat, 
    pch = NLACTcat))
p1 + geom_point(size = 0.75) + stat_summary(fun.y = "mean", geom = "point", 
    size = 3)
plot of chunk gr12

plot of chunk gr12

Als we nu het algemeen gemiddelde ook willen weergeven:

p1 + geom_point(size = 0.75) + stat_summary(fun.y = "mean", geom = "point", 
    size = 3) + stat_summary(show_guide = FALSE, fun.y = "mean", geom = "point", 
    size = 3, col = "black", aes(group = 1))
plot of chunk gr13

plot of chunk gr13

Tabellen van grafieken

Soms is het lastig om gegevens duidelijk in 1 grafiek weer te geven, een tabel van grafieken kan dan helpen. In ggplot2 wordt dit aangeduid met facetting en we gebruiken hiervoor functie facet_grid. Stel dat we een tabel willen maken van de producties bij de laatste 4 melkcontroles, om een of andere reden moeten we kolom DATUM eerst omzetten naar een kolom van gewone tekst:

df$DATUM <- as.character(df$DATUM)
class(df$DATUM)
## [1] "character"
## verder moeten we datums van de laatste 4 melkcontroles vinden:
dd <- unique(df$DATUM)
dd <- dd[order(dd, decreasing = TRUE)][1:4]
p3 <- ggplot(data = df[df$DATUM %in% dd, ], aes(x = DIL, y = PROD_KG)) + 
    geom_point()
p3 + facet_grid(. ~ DATUM)
plot of chunk gr14

plot of chunk gr14

We kunnen ook laktatienummer gebruiken om een tweede dimensie aan de tabel toe te voegen, nu hoeven we geen kleuren meer te gebruiken voor de laktatienummers:

ggplot(data = df[df$DATUM %in% dd, ], aes(x = DIL, y = PROD_KG)) + geom_point() + 
    facet_grid(NLACTcat ~ DATUM) + xlim(c(0, 365))
plot of chunk gr15

plot of chunk gr15

Grafieken opslaan

Het is duidelijk dat R nuttig is om grafieken te maken, we kunnen deze grafieken ook opslaan in verschillende formaten:

Als pdf met functie pdf:

pdf(file = "grafiek_p3.pdf", width = 10, height = 10)
print(p3)
dev.off()
## pdf 
##   2

Als jpeg met functie jpeg:

jpeg(file = "grafiek_p3.jpeg", width = 600, height = 600)
print(p3)
dev.off()
## pdf 
##   2

Als svg bestand, om in webpagina’s toe te voegen, met functie svg:

svg(file = "grafiek_p3.svg", width = 10, height = 10)
print(p3)
dev.off()
## pdf 
##   2

Samenvatting

In dit onderdeel van de workshop hebben we het volgende behandeld:

Terug naar hoofdpagina van de cursus