Jak czyścić dane?
Funkcje w pakiecie dplyr
zakładają że przetwarzanie jest wykonywane po kolumnach. Cała kolumna jest transformowana ale na raz transformowana jest tylko jedna kolumna.
Jednak czasem dane są w formacie, gdy przetwarzanie chciałoby wykonać się w wierszach. Z jednej strony można wyobrazić sobie kolejne funkcje, które działałyby na wierszach, ale zwiększyłoby to bałagan związany z tym co i kiedy można zrobić na jakich danych.
Dlatego logika w tandemie dplyr
+ tidyr
oparta jest na przetwarzaniu kolumnowym. Jeżeli dane są rozsmarowane w wierszach to potrzebujemy instrukcji które przetworzą je na postać kolumnową (tak zwaną postać wąską).
Jako przykład dla takich funkcji wykorzystamy dane z Eurostatu udostępniane przez pakiet dplyr
.
Poniżej wczytujemy dane z tabeli tsdtr210
która w Eurostacie gromadzi dane o udziale środków transportu w różnych krajach.
library(eurostat)
tsdtr210 <- getEurostatRCV("tsdtr210")
head(tsdtr210)
## unit vehicle geo time value
## PC_BUS_TOT_AT_1990 PC BUS_TOT AT 1990 11.0
## PC_BUS_TOT_BE_1990 PC BUS_TOT BE 1990 10.6
## PC_BUS_TOT_BG_1990 PC BUS_TOT BG 1990 NA
## PC_BUS_TOT_CH_1990 PC BUS_TOT CH 1990 3.7
## PC_BUS_TOT_CY_1990 PC BUS_TOT CY 1990 NA
## PC_BUS_TOT_CZ_1990 PC BUS_TOT CZ 1990 NA
Pobrane dane są w postaci wąskiej. Kolumna geo
określa kraj, kolumna time
określa rok, kolumna vehicle
rodzaj transportu, a kolumna value
popularność danego rodzaju transportu w określonym kraju, w określonym roku.
Rozsmaruj na kolumny
Aby przejść z postaci wąskiej do postaci szerokiej, można użyć funkcji spread()
.
Ta funkcja poza pierwszym argumentem - zbiorem danych - oczekuje jeszcze dwóch innych argumentów. Jeden będzie kluczem odpowiadającym nazwom kolumn a drugi będzie wartościami, które zostaną wpisane do poszczególnych kolumn. Wiersze nowej tabeli z danymi są wybierane jako unikalne wartości w pozostałych kolumnach (tutaj wiersze będą opisywały unikalne kombinacje jednostki, typu transportu i kraju).
library(tidyr)
szeroka <- spread(tsdtr210, time, value)
szeroka %>% filter(geo == "PL")
## unit vehicle geo 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
## 1 PC BUS_TOT PL 28.1 25.6 24.4 23.2 20.9 19.9 19.4 17.9 17.4 16.8 27.7
## 2 PC CAR PL 41.3 49.8 55.3 57.9 62.3 64.6 69.3 71.3 72.1 72.3 61.0
## 3 PC TRN PL 30.6 24.6 20.3 18.9 16.8 15.5 11.3 10.8 10.5 10.9 11.3
## 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013
## 1 26.4 24.9 24.3 23.6 22.4 21.8 20.8 19.9 17.9 16.8 15.7 14.8 14.1
## 2 62.9 65.1 66.5 67.9 69.4 70.1 70.7 71.9 74.7 76.1 77.4 78.5 79.6
## 3 10.7 9.9 9.2 8.5 8.2 8.2 8.5 8.2 7.4 7.1 6.9 6.7 6.2
Dane w tabeli pobranej z baz Eurostatu mają więcej wymiarów. Każdy z nich może być użyty do stworzenia nowych kolumn.
Przykładowo poniżej, kolejne kolumny opisują dane z różnych krajów.
szeroka2 <- spread(tsdtr210, geo, value)
# wyświetlmy wiersze dla roku 2010
szeroka2 %>% filter(time == "2010")
## unit vehicle time AT BE BG CH CY CZ DE DK EE EL ES
## 1 PC BUS_TOT 2010 10.3 12.7 16.4 5.1 18.1 19.5 6 10.5 14.4 17.3 12.3
## 2 PC CAR 2010 78.7 79.7 80.0 77.3 81.9 73.0 86 79.7 83.6 81.6 82.3
## 3 PC TRN 2010 11.0 7.7 3.6 17.6 NA 7.5 8 9.8 2.0 1.1 5.4
## EU27 EU28 FI FR HR HU IE IS IT LT LU LV MK MT
## 1 9.2 9.2 9.9 5.3 10.7 21.5 14.5 11.4 12.1 7.6 12.1 17.1 20.3 18.5
## 2 83.6 83.6 84.9 85.5 83.7 68.6 82.6 88.6 82.4 91.7 83.5 78.2 77.5 81.5
## 3 7.2 7.2 5.2 9.3 5.6 10.0 2.9 NA 5.6 0.7 4.5 4.7 2.2 NA
## NL NO PL PT RO SE SI SK TR UK
## 1 3.5 6.8 16.8 6.5 12.9 7.2 10.8 15.3 38.3 6.2
## 2 87.7 88.4 76.1 89.1 81.3 83.4 86.8 78.0 59.3 86.3
## 3 8.9 4.8 7.1 4.4 5.9 9.4 2.5 6.7 2.4 7.5
Zbierz w kolumny
Operacją odwrotną do rozsmarowania jest zbieranie w kolumny, można je wykonać funkcją gather()
. Przekształca ona dane z postaci szerokiej do wąskiej.
Funkcja ta jako pierwszy argument wskazuje zbiór danych, kolejne dwa argumenty określają nazwy kolumn z kluczami i wartościami a pozostałe argumenty wskazują kolumny starego zbioru danych , które mają być zebrane razem w nowym zbiorze danych. Można stosować notacje z -
czyli ,,wszystko poza...''.
szeroka %>%
gather(rok, wartosc, -geo, -vehicle) %>%
tail()
## vehicle geo rok wartosc
## 2620 TRN RO 2013 4.5
## 2621 TRN SE 2013 9.3
## 2622 TRN SI 2013 2.3
## 2623 TRN SK 2013 7.1
## 2624 TRN TR 2013 1.4
## 2625 TRN UK 2013 8.4
Aby wyświetlić przykładowe 6 wierszy użyto tutaj funkcji tail()
(wyświetla ostatnie sześć wierszy) ponieważ w pierwszych sześciu wierszach są wartości NA
,
Sklejanie kolumn
Zdarza się, że wartości z kilku kolumn chcemy skleić ze sobą w jedną kolumnę (w napis).
Można to zrobić funkcją unite()
.
Poniższy przykład skleja wartości w kolumnach geo
i time
w jedną kolumnę geo_time
.
unite(tsdtr210, geo_time, geo, time, sep=":") %>%
head()
## unit vehicle geo_time value
## PC_BUS_TOT_AT_1990 PC BUS_TOT AT:1990 11.0
## PC_BUS_TOT_BE_1990 PC BUS_TOT BE:1990 10.6
## PC_BUS_TOT_BG_1990 PC BUS_TOT BG:1990 NA
## PC_BUS_TOT_CH_1990 PC BUS_TOT CH:1990 3.7
## PC_BUS_TOT_CY_1990 PC BUS_TOT CY:1990 NA
## PC_BUS_TOT_CZ_1990 PC BUS_TOT CZ:1990 NA
Operacja sklejenia jest często przydatna, jeżeli chcemy oprzeć grupowanie o kilka zmiennych. Wtedy te zmienne możemy posklejać i taki zlepek traktować jako nową zmienną grupującą.
Rozcinanie kolumn
Operację odwrotną do sklejania, a więc rozcinanie kolumn, można wykonać funkcją separate()
.
Przedstawimy działanie tej funkcji na przykładzie sztucznego zbioru danych z dwoma kolumnami - datą i id.
W poniższym przykładzie, funkcja separate()
na podstawie kolumny daty
tworzy trzy nowe kolumny. Wypełnia je wartościami po rozbiciu napisy na części rozdzielone znakiem -
.
df <- data.frame(daty = c("2004-01-01", "2012-04-15", "2006-10-29", "2010-03-03"),
id = 1:4)
df
## daty id
## 1 2004-01-01 1
## 2 2012-04-15 2
## 3 2006-10-29 3
## 4 2010-03-03 4
separate(df, col = daty, into = c("rok", "miesiac", "dzien"), sep = "-")
## rok miesiac dzien id
## 1 2004 01 01 1
## 2 2012 04 15 2
## 3 2006 10 29 3
## 4 2010 03 03 4
Jeżeli w kolumnie, która jest rozcinana, będzie zbyt mało lub zbyt dużo wartości (np. tylko dwa elementy rozdzielane separatorem) to domyślnie funkcja separate()
będzie sygnalizowała ostrzeżenia.
Dodatkowymi argumentami extra=
i fill=
można określić jak traktowane mają być nadmiarowe lub brakujące elementy.