Diagramok R-ben

Kategória: Adattudomány R-ben

Az R többféle diagram rendszert használ, eltérő megközelítéssel és eltérő eredménnyel.

Az alap ábrázoló rendszer (Base-R)

Áttekintés

Ez az R alaprendszerének része, nem igényel külön csomag telepítését, sem csomag betöltést. A vizualizációt a "festővászon" metaforával lehet a legjobban jellemezni: minden elemet külön parancsokkal kell hozzáadni a rajzhoz. Először létrehozzuk az alaprajzot a plot() függvénnyel, majd további parancsokkal (pl. points(), text(), lines(), legend()) adjuk hozzá a részleteket, mintha ecsettel dolgoznánk egy festővásznon.

Ez a módszer rendkívül rugalmas és teljes kontrollt biztosít a grafikon minden eleme felett, de több kódot és parancsot igényel, mint a modernebb rendszerek.

Oszlopdiagram

Az oszlopdiagram számok ábrázolására alkalmas. Ezen belül kiválóan alkalmas számok összehasonlítására: jól látszik, hogy melyikből van több.

A példában az mtcars adathalmazt alapul véve az autók darabszámát ábrázoljuk a hengerek száma szerinti bontásban:

barplot(
    table(mtcars$cyl),
    main = "Autók száma hengerek szerint",
    xlab = "Hengerek száma",
    ylab = "Gyakoriság",
    col = "lightblue"
)

Eredmény:

baseplot-bar.png

Jól látható, hogy 8 hengeresből van a legtöbb.

Tortadiagram

Az oszlopdiagramhoz hasonlóan ez is számok ábrázolására alkalmas. Ez kevésbé alkalmas annak illusztrálására, hogy melyikből van több, viszont jól mutatja az egyes része arányát az összeshez. Itt fontos, hogy csak olyan adatokat használhatunk fel, ahol az adatok összege értelmezett, és valójában az összeg alábontását szeretnénk hangsúlyozni. Ebben viszont jobb, mint az oszlopdiagram, különösen akkor, ha nagyon sok számot tartalmaz. Ha például azt szeretnénk illusztrálni, hogy mekkora Kína lakossága a Föld teljes népességéhez viszonyítva úgy, hogy országonként ábrázoljuk a lakosságszámot, akkor az oszlopdiagramban kb. 200, Kína lakosságához képest többnyire elhanyagolható méretű oszlopot látnánk, abból viszont nem látnánk az arányt. A tortadiagram erre kiválóan alkalmas.

A példában ugyanazt ábrázoljuk, mint az oszlopdiagram esetén.

pie(
    table(mtcars$cyl),
    main = "Autók aránya hengerek szerint",
    col = c("lightblue", "lightgreen", "lightyellow"),
    labels = paste0(names(cyl_counts), " henger (", round(100*cyl_counts/sum(cyl_counts)), "%)")
)

Eredmény:

baseplot-pie.png

Ezen kevésbé nyilvánvaló az, hogy a 8 hengeresből van a legtöbb.

Szórásdiagram

A szórásdiagram segítségével két számszerű adat kapcsolatát tudjuk illusztrálni. Az egyiket az x, a másikat az y koordinátán ábrázoljuk. További adatok is ábrázolhatóak az egyes pontok alakja, mérete, színe, átlátszósága és egyéb tulajdonságai alapján.

Az alábbi példában az Írisz virág csészelevelének és sziromlevelének hosszát ábrázoljuk fajta szerint.

# 1. Alapdiagram létrehozása
plot(
    iris$Sepal.Length, iris$Petal.Length,
    xlab = "Csésze hossza",
    ylab = "Szirom hossza",
    main = "Iris virágok",
    type = 'n'
)

# 2. Fajták szerinti pontok hozzáadása
points(
    iris[iris$Species == "setosa",]$Sepal.Length,
    iris[iris$Species == "setosa",]$Petal.Length,
    col = "red",
    pch = 16
)
points(
    iris[iris$Species == "versicolor",]$Sepal.Length,
    iris[iris$Species == "versicolor",]$Petal.Length,
    col = "blue",
    pch = 16
)
points(
    iris[iris$Species == "virginica",]$Sepal.Length,
    iris[iris$Species == "virginica",]$Petal.Length,
    col = "green",
    pch = 16
)

# 3. Jelmagyarázat hozzáadása
legend(
    "topleft",
    legend = c("setosa", "versicolor", "virginica"),
    col = c("red", "blue", "green"),
    pch = 16
)

Eredmény:

baseplot-scatterplot.png

Dobozdiagram

A dobozdiagram segítségével a számszerű adatok eloszlását tudjuk illusztrálni. A doboz a 25 és 75 centilist jelenti, külön megjelölve a mediánt. Ez a szakaszt IQR-nek (Interquantile Range) is hívjuk. A dobozdiagram szára mindkét irányban legfeljebb az IQR hosszának másfélszerese, az azon túli értékek kilógó értékekként (outlier) vannak ábrázolva.

Több dobozdiagramot is ábrázolhatunk egymás mellett, ami kiválóan alkalmas az összehasonlításra. Az alábbi példában a sziromhosszt ábrázoljuk fajták szerint.

boxplot(
    Petal.Length ~ Species,
    data = iris,
    main = "Sziromhossz a fajták szerint",
    xlab = "Fajta",
    ylab = "Szirom hossza",
    col = c("lightblue", "lightgreen", "lightyellow")
)

Eredmény:

baseplot-boxplot.png

Hisztogram

A hisztogram egy alapvető eszköz, amely egy numerikus változó eloszlását mutatja be. A diagram a változó értékeket „kosarakba” vagy intervallumokba (bins) rendezi, majd az oszlopok magassága azt jelzi, hogy hány adatpont esik az adott intervallumba. Ez segít azonosítani a leggyakoribb értékeket és az adatok alakját.

hist(
    iris$Petal.Length,
    main = "A szirmok hosszának eloszlása",
    xlab = "Szirom hossza",
    col = "lightblue"
)

Eredmény:

baseplot-histogram.png

Sűrűségábra

A sűrűségábra a hisztogram egy speciális esete, amely külön vonallal kiemeli a sűrűsödéseket.

hist(
    iris$Petal.Length,
    main = "A szirmok hosszának eloszlása",
    xlab = "Szirom hossza",
    ylab = "Sűrűség",
    probability = TRUE,
    col = "lightblue"
)
lines(
    density(iris$Petal.Length), 
    col = "red", 
    lwd = 2
)

Eredmény:

baseplot-density.png

Dendrogram

A dendrogram a hierarchikus klaszterezés vizuális megjelenítése. Egy faábra formájában mutatja be, hogy az egyes adatelemek hogyan csoportosulnak egymáshoz. A fa gyökere (felül) az összes adatpontot tartalmazza, a levelek (alul) pedig az egyes adatpontokat. A fa ágai a klasztereket jelölik, a magasságuk pedig a klaszterek közötti távolságot.

A példában véletlenszerűen kiválasztunk 20 írisz virágot. A 4 számszerű adat alapján kiszámoljuk páronként az euklideszi távolságot, és ebből készítünk hierarchikus klaszter diagramot. A hasonlóak egymás mellé ill. egymáshoz közel kerülnek, a nagy távolságúak pedig a hierarchiában a gyökérhez közelebb kapcsolódnak egymáshoz. A jobb illusztráltság érdekében címkeként a fajtákat adjuk meg, valamint a 3 legfelső klaszter köré vörös dobozokat rajzolunk.

# Mintavételezés
set.seed(123)
iris_sample <- iris[sample(1:nrow(iris), 20), ]
iris_numeric <- iris_sample[, 1:4]
iris_species <- iris_sample[, 5]

# Hierarchikus klaszterezés
hierarchical_clustering <- hclust(dist(iris_numeric))

# A dendrogram ábrázolása, a fajtákat használva címkeként
plot(
    hierarchical_clustering,
    labels = iris_species,
    main = "Hierarchikus klaszterezés (fajták szerint címkézve)",
    xlab = "Iris fajták",
    ylab = "Távolság",
    hang = -1
)

# Vörös dobozok rajzolása a 3 klaszter köré
rect.hclust(hierarchical_clustering, k = 3, border = "red")

Eredmény:

baseplot-dendrogram.png

Megjegyzés: ez a diagram típus nem szerepel a Lattice és a ggplot2 rendszerben sem.

Hőtérkép

A hőtérkép egy kétdimenziós adatvizualizációs módszer, amely az egyes értékek nagyságát színek segítségével ábrázolja egy adatállományon belül. A színek árnyalatukban vagy intenzitásukban változhatnak.

A hőtérképek gyakori alkalmazási területe az ún. korrelációs hőtérkép, melyben a számszerű adatok közötti korrelációkat (amik -1 és 1 közötti számok) ábrázoljuk. Az alábbi ábrában a kék a pozitív, a piros a negatív korrelációt jelenti, a szín intenzitása pedig a korreláció erősségét jelenti.

heatmap(
    cor(iris[, 1:4]),
    main = "Korrelációs hőtérkép",
    xlab = "Változók",
    ylab = "Változók",
    scale = "none",
    col = colorRampPalette(c("red", "white", "blue"))(100),
    breaks = seq(-1, 1, by = 0.02),
    cexRow = 0.8,
    cexCol = 0.8,
    Rowv = NA,
    Colv = NA
)

Eredmény:

baseplot-heatmap.png

A Lattice rendszer

Áttekintés

A Lattice csomag a Base-R alternatívája, ami segít a többváltozós adatok ábrázolásában. Fő filozófiája, hogy egy parancs segítségével, a vizualizációkat táblázatos elrendezésben, rácsba (lattice) rendezi. Különösen jól használható olyan esetekben, ahol egy harmadik vagy negyedik változó mentén szeretnéd az adatok eloszlását vizsgálni.

A Lattice rendszer "magasabb szintű" megközelítést alkalmaz, mint a Base-R. Ahelyett, hogy a vizualizáció minden apró részét manuálisan adnád hozzá, a csomag egyetlen paranccsal hoz létre egy teljes grafikont. Ennek köszönhetően a kód tömörebb és könnyebben áttekinthető.

Általában része az alap R disztribúcióknak, így külön telepítést nem igényel. Ha mégsem érhető el, akkor a szokásos install.packages("lattice") parancs segítségével telepíthető. Ugyanakkor magát a könyvtárat be kell tölteni használat előtt.

Szórásdiagram

library(lattice)

xyplot(
    Petal.Length ~ Sepal.Length,
    data = iris,
    main = "Iris virágok",
    xlab = "Csésze hossza",
    ylab = "Szirom hossza",
    pch = 16,
    groups = Species,
    auto.key = list(space = "top")
)

Látható, hogy sokkal tömörebb a kód. Felhívom a figyelmet a Petal.Length ~ Sepal.Length részletre, ami különösen jellemzi ezt a megközelítést. Az eredmény:

lattice-scatterplot.png

Dobozdiagram

library(lattice)

bwplot(
    Petal.Length ~ Species,
    data = iris,
    xlab = "Fajta",
    ylab = "Szirom hossza",
    main = "Sziromhossz a fajták szerint",
    par.settings = list(box.rectangle = list(fill = c("lightblue", "lightgreen", "lightyellow")))
)
lattice-boxplot.png

Hisztogram

library(lattice)

histogram(
    ~Petal.Length,
    data = iris,
    main = "A szirmok hosszának eloszlása",
    xlab = "Szirom hossza"
)
lattice-histogram.png

Sűrűségábra

A Lattice kevésbé alkalmas egyszerre ábrázolni a hisztogramot és a sűrűségábrát.

library(lattice)

densityplot(
    ~Petal.Length,
    data = iris,
    main = "A szirmok hosszának sűrűségábrája",
    xlab = "Szirom hossza",
    ylab = "Sűrűség"
)
lattice-density.png

Hőtérkép

Lattice-ben a levelplot() segítségével tudunk hőtárképet létrehozni. Ez az adatokat nem mátrixos, hanem adatkeret formában várja. Összehasonlításul, így néz ki a mátrix:

             Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length    1.0000000  -0.1175698    0.8717538   0.8179411
Sepal.Width    -0.1175698   1.0000000   -0.4284401  -0.3661259
Petal.Length    0.8717538  -0.4284401    1.0000000   0.9628654
Petal.Width     0.8179411  -0.3661259    0.9628654   1.0000000

A következő pedig ugyanez, adatkeret formában:

           Var1         Var2      value
1  Sepal.Length Sepal.Length  1.0000000
2   Sepal.Width Sepal.Length -0.1175698
3  Petal.Length Sepal.Length  0.8717538
4   Petal.Width Sepal.Length  0.8179411
5  Sepal.Length  Sepal.Width -0.1175698
6   Sepal.Width  Sepal.Width  1.0000000
7  Petal.Length  Sepal.Width -0.4284401
8   Petal.Width  Sepal.Width -0.3661259
9  Sepal.Length Petal.Length  0.8717538
10  Sepal.Width Petal.Length -0.4284401
11 Petal.Length Petal.Length  1.0000000
12  Petal.Width Petal.Length  0.9628654
13 Sepal.Length  Petal.Width  0.8179411
14  Sepal.Width  Petal.Width -0.3661259
15 Petal.Length  Petal.Width  0.9628654
16  Petal.Width  Petal.Width  1.0000000

Az átalakítást legegyszerűbben a reshape2 csomag melt() függvénye segítségével tudjuk végrehajtani. Ehhez fel kell telepíteni a reshape2 csomagot:

install.packages("reshape2")

A diagram generálása:

library(lattice)
library(reshape2)

levelplot(
    value ~ Var1 * Var2,
    data = melt(cor(iris[, 1:4])),
    main = "Korrelációs hőtérkép (Lattice)",
    xlab = "",
    ylab = "",
    col.regions = colorRampPalette(c("red", "white", "blue"))(100),
    at = seq(-1, 1, length.out = 101),
    scales = list(x = list(rot = 45))
)

Eredmény:

lattice-heatmap.png

Többváltozós diagramok

A Lattice csomag fő ereje a többpanelos ábrákban rejlik, azaz egy harmadik változó alapján felosztott diagramok. Példaként tekintsük a hengerek száma (cyl) szerint felosztott teljesítmény (hp) és fogyasztás (mpg) szórásdiagramot, trendvonallal.

library(lattice)

xyplot(
    mpg ~ hp | factor(cyl),
    data = mtcars,
    main = "Fogyasztás (mpg) a tejesítmény (hp) függvényében, hengerek szerint",
    xlab = "Lóerő (hp)",
    ylab = "Fogyasztás (mpg)",
    panel = function(x, y, ...) {
        panel.xyplot(x, y, ...)
        panel.lmline(x, y, ...)
    }
)

Eredmény:

lattice-multivar.png

A ggplot2 rendszer

Áttekintés

A ggplot2 a legtöbb adattudós és statisztikus által preferált vizualizációs eszköz R-ben. A csomag az ún. "Grammar of Graphics" (a grafikonok nyelvtana) elméletre épül, ami azt jelenti, hogy a vizualizációkat egy logikai rétegrendszerből építi fel, hasonlóan ahogy a nyelvben a szavakat, mondatokat és bekezdéseket építjük egymásra.

A Base-R és a Lattice rendszerekkel ellentétben a ggplot2 egy egységes, intuitív nyelvet kínál a vizualizációk létrehozásához. Ezáltal a kód rendkívül olvasható és könnyen módosítható. Egyetlen parancsban meg lehet adni a grafikont, a vizsgált adatokat, a vizualizáció típusát (pl. pontok, vonalak, oszlopok), a tengelyek és a színek megfeleltetését, és a stilisztikai elemeket.

A ggplot2 nem része az alap R disztribúciónak, azt a következő paranccsal lehet feltelepíteni:

install.packages("ggplot2")

Oszlopdiagram

Oszlopdiagramot a következőképpen tudunk létrehozni:

library(ggplot2)

ggplot(mtcars, aes(x = factor(cyl))) +
  geom_bar(fill = "lightblue") +
  labs(title = "Autók száma hengerek szerint",
       x = "Hengerek száma",
       y = "Gyakoriság") +
  theme_minimal()

Eredmény:

ggplot-bar.png

Szembeötlő, hogy ilyen egyszerű diagram esetén a kód meglepően bonyolult, és az eredmény különösen nem is tetszetős.

Tortadiagram

A példához szükséges a dplyr külső csomag:

install.packages("dplyr")

Tortadiagram készítése:

library(ggplot2)
library(dplyr)

ggplot(mtcars %>% count(cyl), aes(x = "", y = n, fill = factor(cyl))) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +
  geom_text(aes(label = paste0(round(n/sum(n)*100), "%")),
            position = position_stack(vjust = 0.5)) +
  labs(title = "Autók aránya hengerek szerint",
       fill = "Hengerek száma") +
  theme_void()

Eredmény:

ggplot-pie.png

Itt is elmondható ugyanaz mint az oszlopdiagram esetén: a kód különösen bonyolult, az eredmény pedig leginkább közepes. Ez viszont tartalmazza a százalékokat.

Szórásdiagram

library(ggplot2)

ggplot(
    data = iris,
    aes(x = Sepal.Length, y = Petal.Length, color = Species)
) +
    geom_point() + 
    labs(title = "Iris virágok", x = "Csésze hossza", y = "Szirom hossza")

Ez a Lattice-hez hasonlóan ugyancsak tömör, ám a filozófiája eltér tőle. A ggplot() parancs tartalmazza az adatok és az "esztétikát", majd + jellel fűzünk hozzá további részeket.

Az eredmény tartalmazza a jellegzetes szürke rácsszerű hátteret:

ggplot-scatterplot.png

Dobozdiagram

library(ggplot2)

ggplot(iris, aes(x = Species, y = Petal.Length, fill = Species)) +
    geom_boxplot() +
    labs(title = "Sziromhossz a fajták szerint", x = "Fajta", y = "Szirom hossza") +
    theme(legend.position = "none")
ggplot-boxplot.png

Hisztogram

library(ggplot2)

ggplot(iris, aes(x = Petal.Length)) +
    geom_histogram() +
    labs(
        title = "A szirmok hosszának eloszlása",
        x = "Szirom hossza",
        y = "Gyakoriság"
    )
ggplot-histogram.png

A ggplot2 egyszerűen alkalmas finomabb ábrázolásra, aminek az elkészítése az alaprendszerben sokkal munkásabb lenne. Az alábbi ábra a fajta szerint mutatja be a sziromhosszt:

library(ggplot2)

ggplot(iris, aes(x = Petal.Length, fill = Species)) +
    geom_histogram(binwidth = 0.2, color = "black") +
    facet_wrap(~Species, ncol = 1) +
    labs(
        title = "A szirmok hosszának eloszlása fajta szerint",
        x = "Szirom hossza",
        y = "Gyakoriság") +
    theme(legend.position = "none")
ggplot-histogram-split.png

Sűrűségábra

A sűrűségábra ggplot2 segítségével:

library(ggplot2)

ggplot(iris, aes(x = Petal.Length)) +
    geom_histogram(aes(y = after_stat(density)), binwidth = 0.2, fill = "lightblue", color = "black") +
    geom_density(color = "red", linewidth = 1.2) +
    labs(title = "A szirmok hosszának eloszlása",
        x = "Szirom hossza",
        y = "Sűrűség")

Eredmény:

ggplot-density.png

Hőtérkép

A ggplot2 rendszerben rá tudjuk tenni a hőtérképre a számokat is, ezáltal informatívabb, mint a másik kettő. A ggplot2 is - a Lattice-hoz hasonlóan - adatkeretet vár paraméterként, emiatt itt is a melt() függvényt kell használni.

library(ggplot2)
library(reshape2)

ggplot(data = melt(cor(iris[, 1:4])), aes(x = Var1, y = Var2, fill = value)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(value, 2)), color = "black", size = 4) +
  scale_fill_gradient2(low = "red", high = "blue", mid = "white", midpoint = 0, limit = c(-1, 1), name = "Korreláció") +
  labs(title = "Korrelációs hőtérkép (ggplot2)", x = "", y = "") +
  theme_minimal() +
  coord_fixed()

Eredmény:

ggplot-heatmap.png
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License