-
Notifications
You must be signed in to change notification settings - Fork 1
1.5.8 Agregowanie danych
Niektórych analiz nie da się wykonać poprzez proste skorzystanie z funkcji wymienionych w rozdziale 1.5.2.
W szczególności może to dotyczyć przygotowania danych do prezentacji na wykresach (np. liowym albo rozrzutu) lub w tabelach o nieznanej z góry liczbie wierszy.
W takim wypadku niezbędna może okazać się samodzielna agregacja danych.
Przebiega ona zawsze w kilku krokach:
- Utworzenie tablicy (w nomenklaturze R ramki danych) ze źródłowymi zmiennymi za pomocą funkcji
data_table()
. - Zdefiniowanie zmiennych wyznaczających grupy za pomocą funkcji
group_by()
. - Obliczenia agregatów dla grup za pomocą funkcji
summarize()
.
Najłatwiej zapoznać się z tym procesem na przykładzie.
Załóżmy, że dysponujemy zbiorem danych postaci:
Student | Przedm | Ocena |
---|---|---|
1 | wstęp do socjologii | 4 |
1 | statystyka | 2 |
2 | statystyka | 3 |
... | ... | ... |
Nie znamy jednak z góry listy przedmiotów - nasz szablon raportu powinien dopasować się do listy przedmiotów, którą zastanie w zbiorze danych.
Chcielibyśmy przedstawić średnie wyniki z poszczególnych przedmiotów w tabeli.
Ponieważ nie znamy z góry listy przedmiotów, nie możemy utworzyć szablonu tabeli, który będzie pasował do każdych danych.
Musimy skorzystać z funkcji TAB()
(patrz rozdział 1.5.4.3), której przekażemy tablicę (ramkę danych) zagregowanych wartości do wyświetlenia.
Tak więc musimy najpierw wyliczyć zagregowane wartości.
Odnosząc się do przedstawionego na początku rozdziału schematu potrzebujemy:
-
Zdefiniować tablicę (ramkę danych) umieszczając w niej zmienne Przedm oraz Ocena.
Nazwy, jakie nadajemy zmiennym w tworzonej ramce danych są dowolne, należy jedynie pamiętać, że:- w kolejnych krokach używać będziemy właśnie tych nowo nadanych nazw;
w szczególności później wykorzystane funkcje (np.TAB()
czy funkcje rysujące wykresy) mogą na ich podstawie nadawać nagłówki kolumn w tabeli czy etykiety serii danych na wykresie (z tego powodu przezywamy zmienną Przedm na Przedmiot); - w szczególności nadawane nazwy mogą być takie same, jak nazwy zmiennych źródłowych (jak tutaj w wypadku zmiennej Ocena)
daneDoAgregacji = data_frame( Przedmiot = Przedm, Ocena = Ocena )
- w kolejnych krokach używać będziemy właśnie tych nowo nadanych nazw;
-
Wskazać, że chcemy dokonać pogrupowania według zmiennej Przedmiot (która teraz nazywa się już Przedmiot):
daneDoAgregacji = group_by(daneDoAgregacji, Przedmiot)
-
Policzyć zagregowane wartości za pomocą funkcji
summarize()
oraz funkcji obliczających statystki z pakietu MLAK (patrz rozdział 1.5.2):daneZagregowane = summarize(daneDoAgregacji, 'średnia ocena' = E(Ocena))
Mając obliczone agregaty, możemy je wyświetlić funkcją TAB()
:
TAB(daneZagregowane)
Cały kod w postaci wstawki w szablonie raportu wyglądałby następująco:
```{r}
daneDoAgregacji = data_frame(
Przedmiot = Przedm,
Ocena = Ocena
)
daneDoAgregacji = group_by(daneDoAgregacji, Przedmiot)
daneZagregowane = summarize(daneDoAgregacji, 'Średnia ocena' = E(Ocena))
TAB(daneZagregowane)
```
Załóżmy, że zamiast tabeli z poprzedniego przykładu chcielibyśmy wyświetlić w raporcie wykres słupkowy.
W takim wypadku musimy przekształcić uzyskaną tablicę (ramkę danych) zagregowanych na wektor, którego wartościami będzie kolumna Średnia ocena a etykietami kolumna Przedmiot.
Możemy to uzyskać za pomocą funkcji setNames(wartości, etykiety)
:
daneDoWykresu = setNames(daneZagregowane$'Średnia ocena')
Cała wstawka w szablonie raportu, łącznie z narysowaniem wykresu, wyglądałaby następująco:
```{r, fig.width=3}
daneDoAgregacji = data_frame(
Przedmiot = Przedm,
Ocena = Ocena
)
daneDoAgregacji = group_by(daneDoAgregacji, Przedmiot)
daneZagregowane = summarize(daneDoAgregacji, 'Średnia ocena' = E(Ocena))
daneDoWykresu = setNames(daneZagregowane$'Średnia ocena')
wykresSlupkowy(daneDoWykresu)
```
Wróćmy do pierwszego przykładu (tabeli o nieznanej z góry liczbie wierszy).
Załóżmy, że zależy nam na tym, aby dane wyświetlone w raporcie były posortowane wedle wybranej kolumny, np. średniej oceny.
W tym celu wykorzystać można funkcję arrange()
, którą wywołujemy na już obliczonych danych zagregowanych:
danePosortowane = arrange_(daneZagregowane, 'Średnia ocena')
Jeśli chcielibyśmy użyć do sortowania kilku kolumn, to wymieniamy ich nazwy po przecinku, np.:
danePosortowane = arrange_(daneZagregowane, 'Średnia ocena', 'Przedmiot')
.
Kompletny szablon raportu wyglądałaby następująco:
---
title: "Przykłady agregacji"
output: pdf_document
---
```{r, echo = FALSE, message = FALSE, warning = FALSE}
library(MLAK)
wczytajOdbiorce('odbiorcy.csv', 'dane.csv')
```
```{r}
daneDoAgregacji = data_frame(
Przedmiot = Przedm,
Ocena = Ocena
)
daneDoAgregacji = group_by(daneDoAgregacji, Przedmiot)
daneZagregowane = summarize(daneDoAgregacji, 'Średnia ocena' = E(Ocena))
danePosortowane = arrange(daneZagregowane, 'Średnia ocena')
TAB(danePosortowane)
```
Czasami może się zdarzyć, że będziemy chcieli zagregować ze sobą zmienne o różnych poziomach agregacji i dopiero po ich połączeniu możliwe będzie obliczenie interesujących nas agregatów (patrz np. rozdział 1.5.7).
Jeśli zdarzy się taka sytuacja, złączenie przebiega w następującym schemacie:
- Tworzymy oddzielne tablice (w nomenklaturze R ramki danych), z których każda zawieraja zmienne z jednego poziomu agregacji.
- Odbywa to się tak samo, jak w wypadku agregacji - za pomocą funkcji
data_frame()
. Jedyna różnica polega na tym, że tym razem tworzymy dwie ramki danych, a nie jedną. - Tworzone ramki danych muszą zawierać co najmniej jedną zmienną o tej samej nazwie, po której odbędzie się złączenie.
- Odbywa to się tak samo, jak w wypadku agregacji - za pomocą funkcji
- Łączymy je ze sobą za pomocą jednej z funkcji (przykładowe wyniki złączeń można znaleźć tutaj):
-
inner_join(ramkaDanych1, ramkaDanych2)
- w wynikowy zbiorze znajdą się tylko obserwacje, które występowały zarówno wramkaDanych1
, jak iramkaDanych2
, -
left_join(ramkaDanych1, ramkaDanych2)
- w wynikowym zbiorze znajdą się wszystkie obserwacje zramkaDanych1
oraz wszystkie pasujące do nich obserwacje zramkaDanych2
, -
full_join(ramkaDanych1, ramkaDanych2)
- w wynikowym zbiorze znajdą się wszystkie obserwacje z obydwu ramek danych.
-
Załóżmy, że dysponujemy dwoma zbiorami o różnych poziomach agregacji - pierwszym opisującym absolwenta na kierunku studiów i drugim opisującym absolwenta na kierunku studiów w danym miesiącu kalendarzowym:
ID_ZDAU | DATA_ZAK | DOSW_ES | ...inne zmienne... |
---|---|---|---|
1 | 2015-10 | 1 | ...pozostałe wartości... |
2 | 2015-11 | 3 | ...pozostałe wartości... |
... | ... | ... | ... |
ID_ZDAU_M | OKRES_M | STUD_M | STUDPROG_M | BILOD_M | ...inne zmienne... ----------|---------|--------|------------|---------|--------|-------------------- 1 | 2015-10 | 1 | 1 | 0.62 | ...pozostałe wartości... 1 | 2015-11 | 0 | 0 | 0.80 | ...pozostałe wartości... ...|...| ...
Chcemy obliczyć średnią wartość zmiennej BILOD_M w grupach wyznaczanych przez zmienną DOSW_ES.
Złączenie zbiorów jest możliwe na podstawie wartości zmiennej ID_ZDAU w pierwszym zbiorze i ID_ZDAU_M w drugim zbiorze.
Zanim przystąpimy do agregacji, musimy złączyć ze sobą obydwa zbiory danych. W tym celu:
-
Tworzymy ramki danych zawierające potrzebne zmienne z obydwu zbiorów danych. Pamiętamy o tym, że obydwie ramki danych muszą zawierać kolumnę o takiej samej nazwie, która umożliwi złączenie:
zbior1 = data_frame( ID_ZDAU = ID_ZDAU, DOSW_ES = DOSW_ES ) zbior2 = data_frame( ID_ZDAU = ID_ZDAU_M, BILOD_M = BILOD_M )
-
Złączamy dane ze sobą. Tu wykorzystamy złączenie
inner_join()
:
daneZlaczone = inner_join(zbior1, zbior2)
-
Teraz możemy już dokonać agregacji, jak to zostało omówione w pierwszej części rozdziału.
Pełen szablon raportu dokonujący złączenia zbiorów, agregacji, a na końcu wstawiającej wynik obliczeń do raportu w postaci tabeli wyglądałby następująco:
---
title: "Przykłady agregacji"
output: pdf_document
---
```{r, echo = FALSE, message = FALSE, warning = FALSE}
library(MLAK)
wczytajOdbiorce('odbiorcy.csv', 'dane.csv')
```
```{r}
zbior1 = data_frame(
ID_ZDAU = ID_ZDAU,
DOSW_ES = DOSW_ES
)
zbior2 = data_frame(
ID_ZDAU = ID_ZDAU_M,
BILOD_M = BILOD_M
)
daneZlaczone = inner_join(zbior1, zbior2)
daneDoAgregacji = group_by(daneZlaczone, DOSW_ES)
daneZagregowane = summarize(daneDoAgregacji, BILOD = E(BILOD))
TAB(daneZagregowane)
```