Młodzi XXL … od podszewki

Dzisiaj pokażę jak powstawał jeden z wykresów z poprzedniego wpisu n.t. otyłości. Ponieważ ma być bardziej warsztatowo to opowiem też jak wybierałem kolory i dlaczego wykres jest w poziomie.

Do wczytania danych wykorzystamy pakiet SmarterPoland dla programu R. Funkcją getEurostatRCV() wczytujemy tabelę z danymi o grupach BMI o nazwie hlth_ehis_de1.

1
2
3
4
5
6
7
8
9
10
11
12
library(Cairo)
library(SmarterPoland)
summary(tmp1 <- getEurostatRCV("hlth_ehis_de1"))
 
##    time           bmi       sex           age            geo         isced97         value      
## 2008:9335   18P5-25:2375   F:3145   TOTAL  :1080   AT     : 540   TOTAL :1867   Min.   : 0.10  
##             25-30  :2375   M:3015   Y18-24 :1080   BE     : 540   ED0-2 :1867   1st Qu.: 7.80  
##             GE30   :2370   T:3175   Y25-34 :1075   DE     : 540   ED3_4 :1867   Median :24.80  
##             LT18P5 :2215            Y45-54 :1075   ES     : 540   ED5_6 :1867   Mean   :26.38  
##                                     Y35-44 :1060   FR     : 540   UNK   :1867   3rd Qu.:41.30  
##                                     Y65-74 :1055   HU     : 540                 Max.   :92.20  
##                                     (Other):2910   (Other):6095                 NA's   :2685

Kolejne kolumny wczytanych danych informują o time roku badania, bmi grupie BMI (niedowaga, prawidłowa waga, nadwaga i otyłość), sex płci (T oznacza bez podziału na płeć), age wieku (TOTAL oznacza bez podziału na grupy wiekowe), geo czyli kraj, isced97 czyli wykształcenie i value czyli procent osób w danej grupie BMI wśród podpopulacji określonej przez pozostałe zmienne. Dane są w postaci luźnej, zwanej też rzadką, więc na zwykłą tabelę zamienimy je funkcją cast.

Poniższa instrukcja buduje tablicę krzyżową dla rozkładu bmi w grupach określonych przez płeć i wiek, bez podziału na wykształcenie i tylko dla Polski.

13
14
15
16
17
18
19
20
21
22
wskR2008 <- na.omit(cast(tmp1, sex + age ~ bmi, mean, subset = isced97 == "TOTAL " & 
                    sex != "T" & age != "TOTAL" & geo == "PL"))
head(wskR2008)
##   sex    age 18P5-25 25-30 GE30 LT18P5
## 1   F Y_GE85    44.0  36.2 17.0    2.8
## 2   F Y18-24    74.5  10.9  2.1   12.6
## 3   F Y25-34    70.9  17.2  5.3    6.7
## 4   F Y35-44    59.5  28.1 10.1    2.3
## 5   F Y45-54    44.0  36.5 17.9    1.7
## 6   F Y55-64    31.3  39.1 28.4    1.2

Mamy tabelę krzyżową, zabieramy się do jej wizualizacji. Chcę do tego wykorzystać wykres paskowy, czyli funkcję barplot(). Każdy wiersz obiektu wskR2008 opisuje procentowy udział osób z BMI 18.5-25, 25-30, >30, <18.5 w grupie o określonej płci i wieku. Więc aby użyć funkcji barplot() muszę ten obiekt transponować. Ponieważ na wykresie chciałbym mieć i wiersze i kolumny w innej kolejności więc muszę je przeindeksować (kolumny chciałbym od niedowagi do otyłości a wiersze od najmłodszej do najstarszej grupy wiekowej i najpierw mężczyźni a później kobiety). Obie te transformację mogę osiągnąć instrukcją t(wskR2008[c(10:16, 9, 2:8, 1), c(6, 3, 4, 5)]).

Nie wiedzieć czemu funkcja barplot() rysuje domyślnie wykres pionowo, choć znacznie czytelniejszy jest gdy jest rysowany poziomo. Zmianę kierunku osiągnąć można argumentem horiz = T.

Z technicznych przyczyn potrzebuję usunąć etykiety z osi OX a etykiety na osi OY wpisać poziomo, obie te rzeczy wymagają dodania argumentów las = 1, xaxt = "n".

I najciekawsze, czyli kolory.
Potrzebuję kolorów do określenia niedowagi, wagi prawidłowej, nadwagi i otyłości. Szukając kolorów wygodnie jest korzystać z nazw kolorów a nie z kodów RBG. Pisząc książkę ,,Przewodnik po pakiecie R” opracowałem mapę kolorów dostępną tutaj. Z niej wybierałem kolory do tej wizualizacji.
Waga prawidłowa kojarzy się z kolorem zielonym, poprawnym. Jaki odcień? Zbyt ciemny wygląda mało ciekawie, zbyt jaskrawy razi oczy i nie pozwala się skupić. Koniec końców wybrałem kolor "chartreuse2".
Dla otyłości chciałem wybrać któryś z odcieni czerwieni. Ciemne odcienie nie podobały mi się, bo były za mało alarmujące, a otyłość powinna być alarmująca. Po kilku eksperymentach wybór zawęziłem do "orangered1", "red1" i "firebrick1" a ostatecznie wybór padł na "red1" choć nie potrafię tego uzasadnić, po prostu podobał mi się najbardziej.
Z nadwagą poszło najłatwiej, pomiędzy zielenią a czerwienią powinien być kolor ostrzegawczy, żółty. A kolor "yellow1" jest wyrazisty więc był jedynym kandydatem (ok, tak naprawdę próbowałem też "gold" ale to była pomyłka).
Dla niedowagi potrzebne było coś kontrastujące z otyłością, więc jakiś odcień niebieskiego. Oko ludzkie z rozróżnianiem odcieni niebieskiego marnie sobie radzi. Ale R w palecie nazw kolorów ma wiele różnych odcieni błękitu więc wybierać trzeba. Zwykły niebieski "blue" jest zbyt dominujący, psuł kolor zielony sąsiedniego paska. Koniec końców z serii "lightskyblue" i "slategray" wybrałem "slategray2".

Drobnym, ale myślę że potrzebnym dodatkiem były pomocnicze pionowe linie siatki. Aby były widoczne ale nie narzucające się użyłem koloru szarego z włączonym kanałem alfa, czyli kolor o kodzie RGB "#77777730".

Ostatnie detale dla wykresu to zmiana marginesów (funkcja par), dodanie legendy (funkcja legend) i osi OX (funkcja axis) na której chciałbym by były procenty. I pierwsza wersja wykresu gotowa.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
nazwy <- c("Kobiety/ >85", "Kobiety/18-24", "Kobiety/25-34", "Kobiety/35-44", 
    "Kobiety/45-54", "Kobiety/55-64", "Kobiety/65-74", "Kobiety/75-84", "Mężczyźni/ >85", 
    "Mężczyźni/18-24", "Mężczyźni/25-34", "Mężczyźni/35-44", "Mężczyźni/45-54", 
    "Mężczyźni/55-64", "Mężczyźni/65-74", "Mężczyźni/75-84")
 
par(mar = c(5, 10, 3, 3))
barplot(t(wskR2008[c(10:16, 9, 2:8, 1), c(6, 3, 4, 5)]), names.arg = nazwy[c(10:16, 
    9, 2:8, 1)], horiz = T, las = 1, col = c("slategray2", "chartreuse2", "yellow1", 
    "red1"), xaxt = "n", main = "BMI a wiek, Polacy w 2008 roku")
 
axis(1, at = seq(0, 100, 10), paste(seq(0, 100, 10), "%", sep = ""))
abline(v = seq(0, 100, 10), col = "#77777730")
 
par(xpd = NA)
legend(17, 20.8, c("niedowaga", "prawidłowa waga", "nadwaga", "otyłość"), 
    bty = "n", fill = c("slategray2", "chartreuse2", "yellow1", "red1"), ncol = 4)

plot of chunk podsumowanie

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *