W pierwotnym planie wydawniczym Poradnika dla sponiewieranych Excelem, dzisiejszy odcinek miał traktować o dodawaniu oraz usuwaniu wierszy i kolumn w ramce danych. Na szczęście mogę ów plan spontanicznie modyfikować, więc dziś będzie o… gimbazie.
Do gimnazjów uczęszczały roczniki 1986-2003. Najmłodsi absolwenci mają dziś ponad dwadzieścia lat. Za dwadzieścia lat dobiją do czterdziestki. Zastanowiłem się, jak ich podróż w przyszłość będzie wyglądała na wizualizacji piramidy wieku mieszkańców Polski. Obserwatorzy social mediów Informatyka Zakładowego już to wiedzą:
Piramida wieku
Skąd wziąć informacje o bieżącej i prognozowanej strukturze wieku ludności Polski? Oczywiście z Głównego Urzędu Statystycznego, który kilka lat temu opublikował prognozę ludności rezydującej na lata 2015 – 2050. Pobrany plik Excela wygląda następująco (arkusz „Roczniki”):
Kolumna A składa się z szeregu połączonych komórek, my chcemy mieć rok prognozy w każdym wierszu. Teraz uważajcie, będzie sztuczka z Excela. Może jedyna w całym Poradniku dla sponiewieranych Excelem, więc proszę o skupienie.
Podświelamy całą kolumnę A. Następnie zakładka Narzędzia główne → Wyrównanie → Scal i wyśrodkuj (rozwijak) → Rozdziel komórki. To było łatwe, trick będzie teraz. Ponownie zaznaczamy całą kolumnę A, następnie Narzędzia główne → Edytowanie → Znajdź i zaznacz (wybierak) → Przejdź do – specjalnie → Zaznacz puste → OK. Mamy zaznaczone wszystkie puste obszary. Teraz wciskamy kolejno klawisze:
- znak równości
- strzałka w górę
- CTRL+Enter
Wszystkie puste komórki powinny zapełnić się poprawnym numerem roku! Możesz usunąć dwa pierwsze wiersze i zapisać arkusz do osobnego pliku.
Wczytujemy i przekształcamy dane
Wczytujemy dane z Excela do ramki danych
gimby <- read_excel("roczniki.xlsx")
Filtrujemy tylko wiersze z wiekiem podanym cyframi (odpadają wiersze „Ogółem” i „100+”), usuwamy też niepotrzebną kolumnę „Ogółem”
gimby <- gimby %>% filter (grepl("^[0-9]+$", Wiek)) %>% select(-Ogółem)
Przekształcamy ramkę danych na wąską, zgodnie z opisem z poprzedniego odcinka
gimby <- gimby %>% pivot_longer(cols=c(Mężczyźni, Kobiety), names_to="Gender", values_to = "Number")
Pierwsza przymiarka do wykresu obejmującego jeden rok:
gimby %>%
filter(Rok==2020) %>%
ggplot(aes(x = Wiek, y = Number, fill=Gender)) +
geom_col(width = 1)
proto-wykres
To jeszcze nie to. Zamieńmy populację kobiet na liczby ujemne
gimby[gimby$Gender=="Kobiety",]$Number <- gimby[gimby$Gender=="Kobiety",]$Number *-1
Do wykresu dodajemy komendę zamiany współrzędnych, by wartości rosły nie z lewej strony na prawą, lecz z dołu do góry
coord_flip()
Jest dobrze! Czas na dodanie do każdej płci dwóch wariantów – gimby i nie-gimby. Najpierw wyliczamy rok urodzenia, potem określamy czy mieści się w przedziale właściwym dla roczników gimnazjalnych.
gimby <- gimby %>% mutate(RokUrodzenia = Rok-Wiek, Gimba = paste0(Gender, RokUrodzenia >=1986 & RokUrodzenia<=2003 ))
Mamy to! Pozostaje już tylko usunąć legendę, ręcznie dobrać kolorki (scale_fill_manual
), dostosować parametry obu osi (scale_y_continuous
, scale_x_continuous
), nadać temat graficzny i trochę go zmodyfikować (theme_minimal
, theme
), oraz dodać napisy (annotate
). Gotowy kod można znaleźć na Githubie, efekt działania wygląda następująco:
Aby duży napis wędrował po ekranie wraz z podkreślonym przedziałem, jedna ze współrzędnych będzie zależna od rozpatrywanego roku
annotate("text", x=rok-1995, y=10, label= "GIMBY", size=15)
Teraz wystarczy wstawić procedurę rysującą wskazany rok w pętlę wartości 2023-2050 i tak oto jednym ruchem wygenerujemy zestaw grafik wynikowych.
ggsave(paste0(rok,".png"), width = 1080, height = 1080, units = "px", dpi=150 )
Łączenie grafik z większym obrazkiem
Do połączenia obrazka stanowiącego tło (poniżej) ze wszystkimi wyprodukowanymi grafikami, zastosowałem pakiet ImageMagick, który umożliwia edytowanie obrazów z linii komend.
W moim przypadku wystarczył plik BAT z następującą komendą uruchamianą w katalogu z obrazkami.
FOR /R %%plik IN (*.png) DO magick composite "%%~plik" ../background.png "%%~plik"
Łączenie obrazów w animację
Serię obrazów PNG full HD połączyłem w animację GIF przy użyciu programu Gifski, łączącego prostotę użycia z niesamowitą jakością plików wynikowych. Apka dostępna jest w wariancie okienkowym i działającym z linii komend. Użyłem tego drugiego:
gifski -r 4 -o ../outfinal.gif -W 1920 -H 1080 *.png
Edycja animacji
Gotową animację wrzuciłem jeszcze do edytora programu ScreenToGif, który oprócz funkcji przechwytywania części ekranu do pliku wideo jest wyposażony we wszechstronny edytor. Tu dodałem „efekt yoyo” z przyspieszonym cofaniem i zmieniłem czas wyświetlania wybranych klatek animacji.
Finalny efekt możesz obejrzeć na początku artykułu (albo tutaj).
Podsumowanie
I to już wszystko! Daj proszę znać, jak oceniasz niniejszy odcinek, z mini-projektem wykraczającym poza analizę danych. W ramach zadania domowego uruchom skrypt z GitHuba i wygeneruj własny zestaw obrazków składających się na animację.
O autorze: zawodowy programista od 2003 roku, pasjonat bezpieczeństwa informatycznego. Rozwijał systemy finansowe dla NBP, tworzył i weryfikował zabezpieczenia bankowych aplikacji mobilnych, brał udział w pracach nad grą Angry Birds i wyszukiwarką internetową Microsoft Bing.
W odpowiedzi na “Analiza danych w języku R – odcinek 7”
Jakiś pomysł skąd taka duża różnica pomiędzy liczbą 74 a 75 latek i latków? Sprawdziłem w innych miejscach w Sieci i wygląda to podobnie. Dziwne.