--- title: "Wprowadzenie do `reshape2`" author: "Bartosz Maćkiewicz" subtitle: Statystyka I z R output: pdf_document: default html_document: default --- # Wprowadzenie do `reshape2` Głowną funkcją pakietu `reshape2` jest możliwość przekształcenia danych z formatu "długiego" do "szerokiego" i odwrotnie. **Format "szeroki"** - każdej zmiennej odpowiada kolumna. Jest to format, z którym najczęściej się do tej pory spotykaliśmy (chociaż mieliśmy również styczność z "długim" formatem). **Format "długi** - zawiera kolumny z możliwymi zmiennymi oraz ich wartościami. Po co dokonywać konwersji pomiędzy formatami? Wszystko zależy od tego, co z nimi chcemy zrobić - czasami potrzebne nam są dane w jednym formacie, czasami w drugim. W rzeczywistości "długi" format potrzebny jest częściej, niż może się Państwu wydawać. Pakiet `reshape2` instalujemy standardowym poleceniem `install.packages` i ładujemy za pomocą `library`. ```{r} # install.packages('reshape2') library(reshape2) ``` Do ćwiczen załadujmy dane dotyczące śmiertelności dzieci poniżej 5 roku życia. ```{r} df <- read.csv('unicef-u5mr.csv') ``` Nasze dane, jak możemy zobaczyć, są w formacie "długim" - każdemu rokowi odpowiada jedna kolumna. ```{r} head(df) ``` Spróbujmy trochę uporządkować nazwy kolumn, tak by odpowiadały im liczby. Po wczytaniu danych nazwy kolumn wyglądają tak: ```{r} colnames(df)[2:ncol(df)] ``` Za pomocą polecenia `strsplit` podzielmy nazwy kolumn na dwa ciągi znaków: `U5MR` i `rok`. Funkcja `strsplit` przyjmuje jako pierwszy argument wektor typu `character` a jako drugi wyrazenie regularne mówiące, jak chcemy podzielić nasze napisy. W tym przypadku użyłem wzorca `\\.`, który dopasowuje znak podziału do kropki. ```{r} str = c('123y21321s3432', '12z3213y213213', '21321512y1321z321') strsplit(str, '[a-z]') ``` ```{r} head(strsplit(colnames(df)[2:ncol(df)], '\\.')) ``` ```{r} head(strsplit(colnames(df)[2:ncol(df)], 'R')) ``` ```{r} head(strsplit(colnames(df)[2:ncol(df)], '.')) ``` Funkcja `strsplit` zwraca listę, z której za pomocą polecenia `unlist` możemy stworzyć wektor. Problemem jest to, że otrzymamy wówczas wektor typu `character` o postaci: ```{r} unlist(strsplit(colnames(df)[2:ncol(df)], '\\.')) ``` Musimy więc wybrać co drugą wartość z tego wektora. ```{r} lata = unlist(strsplit(colnames(df)[2:ncol(df)], '\\.'))[seq(2*(ncol(df)-1),from = 2, by = 2)] lata ``` Następnie przypisujemy ten wektor do nazw kolumn. ```{r} colnames(df)[2:ncol(df)] = unlist(strsplit(colnames(df)[2:ncol(df)], '\\.'))[seq(2*(ncol(df)-1),from = 2, by = 2)] ``` Widzimy, że uporzadkowaliśmy sobie kwestię nazw kolumn. Teraz są nimi kolejne lata. ```{r} head(df) ``` ## melt Funkcja `melt` pozwala nam na przekształcenie naszej ramki danych z formatu "szerokiego" na format "długi". Jako pierwszy argument przyjmuje ramkę danych, kolejne argumenty okreslają jak ma wyglądać wynikowa ramka danych. ```{r} tail(melt(df)) ``` Możemy od razu określić jak nazywać się będzie kolumna z nazwą zmiennej. W naszym przypadku zupełnie sensownie jest nadać jej zamiast nazwy `variable` nazwę `year`, bo faktycznie znajdują się w niej daty. ```{r} df_dlugie = melt(df, variable.name = 'year', value.name = 'U5MR') tail(df_dlugie) ``` ## dcast Za pomocą funkcji `dcast` możemy dokonać przekształcenia w drugą stronę - z formatu "długiego" do formatu "szerokiego". `dcast` korzysta ze standardowego interfejsu formuł w R. W naszym przypadku przekazaliśmy następującą formułę: `CountryName ~ year` `ContryName` ma być naszą kolumną wyznaczającą wiersze, `year` jest zaś kolumną, w której znajdują się nazwy zmiennych. Argument `value` mówi, w której kolumnie znajdują się wartości wierszy. Funkcja `dcast` umożliwia również bardziej zaawansowane przekształcanie ramek danych w "długim" formacie. Nam jednak na początek starczy najbardziej podstawowe jej użycie. ```{r} df_krotkie = dcast(CountryName ~ year, data = df_dlugie, value = 'U5MR') tail(df_krotkie) ``` Mając dane w formacie "długim" możemy z łatwością stworzyć wykres obrazujący, jak śmiertelność dzieci poniżej 5 roku życia malała w Polsce na przestrzeni lat. ```{r} df_polska = df_dlugie[df_dlugie$CountryName == 'Poland',] plot(as.numeric(as.character(df_polska$year)), df_polska$U5MR, type = 'l', col = 'red') ```