##### Rozdział 12: zaawansowane przygotowywanie danych --------------------

## tidyverse ----

library(tidyverse) # wczytujemy wszystkie pakiety tidyverse

# przekształcamy treningowy zbiór danych o pasażerach Titanica w obiekt tibble
library(tibble) # niepotrzebne, jeśli wczytano już tidyverse
titanic_csv <- read.csv("titanic_train.csv")
titanic_tbl <- as_tibble(titanic_csv)
titanic_tbl

# wczytujemy zbiór danych o pasażerach Titanica za pomoca readr
library(readr) # niepotrzebne, jeśli wczytano już tidyverse
titanic_train <- read_csv("titanic_train.csv")

# zbiór danych o pasażerach Titanica za pomocą readxl
library(readxl)
titanic_train <- read_excel("titanic_train.xlsx")

# przygotowujemy dane za pomocą dplyr
library(dplyr)

# filtrujemy tylko pod kątem wierszy z płcią żeńską
titanic_train |> filter(Sex == "female")

# wybieramy tylko kolumny nazwiska, płci i wieku
titanic_train |> select(Name, Sex, Age)

# łączymy wiele "czasowników" dplyr i zapisujemy wyniki w obiekcie tibble
titanic_women <- titanic_train |>
  filter(Sex == "female") |>
  select(Name, Sex, Age) |>
  arrange(Name)

# tworzymy nową cechę wskazującą podeszły wiek
titanic_train |>
  mutate(elderly = if_else(Age >= 65, 1, 0))

# tworzymy wiele cech jednym poleceniem mutate
titanic_train |>
  mutate(
    elderly = if_else(Age >= 65, 1, 0),
    child = if_else(Age < 18, 1, 0)
  )

# obliczamy wskaźnik przeżywalności wg płci
titanic_train |>
  group_by(Sex) |>
  summarize(survival_rate = mean(Survived))

# obliczamy średni wskaźnik przeżywalności dla dzieci i nie-dzieci
titanic_train |>
  filter(!is.na(Age)) |>
  mutate(child = if_else(Age < 18, 1, 0)) |>
  group_by(child) |>
  summarize(survival_rate = mean(Survived))

# przekształcamy zbiór danych i przekazujemy go potokowo do drzewa decyzyjnego
library(rpart)
m_titanic <- titanic_train |>
  filter(!is.na(Age)) |>
  mutate(AgeGroup = if_else(Age < 18, "Child", "Adult")) |>
  select(Survived, Pclass, Sex, AgeGroup) |>
  rpart(formula = Survived ~ ., data = _)

library(rpart.plot)
rpart.plot(m_titanic)

## Przekształcanie tekstu za pomocą pakietu stringr ----
library(readr)
titanic_train <- read_csv("titanic_train.csv")

library(stringr)

# badamy kody kabin
titanic_train <- titanic_train |>
  mutate(CabinCode = str_sub(Cabin, start = 1, end = 1))

# porównujemy kody kabin z klasą pasażerską
table(titanic_train$Pclass, titanic_train$CabinCode,
      useNA = "ifany")

# kreślimy prawdopodobieństwo przeżycia wg kodu kabiny
library(ggplot2)
titanic_train |> ggplot() +
  geom_bar(aes(x = CabinCode, y = Survived),
             stat = "summary", fun = "mean") +
  ggtitle("Wskaźnik przeżywalności pasażerów Titanica wg kodu kabiny")

# przyglądamy się kilku pierwszym nazwiskom pasażerów
head(titanic_train$Name)

# tworzymy cechę tytułu
titanic_train <- titanic_train |>
  # używamy wyrażenia regularnego, aby znaleźć znaki między przecinkiem a kropką
  mutate(Title = str_extract(Name, ", [A-z]+\\."))

# przyglądamy się kilku pierwszym przykładom
head(titanic_train$Title)

# oczyszczamy cechę tytułu
titanic_train <- titanic_train |>
  mutate(Title = str_replace_all(Title, "[, \\.]", ""))

# badamy wyniki
table(titanic_train$Title)

# grupujemy tytuły w pokrewne kategorie
titanic_train <- titanic_train |>
  mutate(TitleGroup = recode(Title,
    # kilka pierwszych tytułów pozostaje bez zmian
    "Mr" = "Mr", "Mrs" = "Mrs", "Master" = "Master",
    "Miss" = "Miss",
    # łączymy warianty "Miss"
    "Ms" = "Miss", "Mlle" = "Miss", "Mme" = "Miss",
    # inne tytuły zmieniamy w "Other"
    .missing = "Other",
    .default = "Other"
    )
  )

# badamy wyniki
table(titanic_train$TitleGroup)

# wykres prawdopodobieństwa przeżycia wg grupy tytułów
library(ggplot2)
titanic_train |> ggplot() +
  geom_bar(aes(x = TitleGroup, y = Survived),
           stat = "summary", fun = "mean") +
  ggtitle("Wskaźnik przeżywalności pasażerów Titanica wg tytułu")

## Oczyszczanie dat z wykorzystaniem pakietu lubridate ----

library(lubridate)

# wczytujemy daty wydania "Uczenia maszynowego w języku R" w różnych formatach
reading in Machine Learning with R publication dates in different formats
mdy(c("October 25, 2013", "10/25/2013"))
dmy(c("25 October 2013", "25.10.13"))
ymd("2013-10-25")

# Konstruujemy daty wydania UMwJR
MLwR_1stEd <- mdy("October 25, 2013")
MLwR_2ndEd <- mdy("July 31, 2015")
MLwR_3rdEd <- mdy("April 15, 2019")

# obliczamy różnice (polecenia zwracają obiekt difftime)
MLwR_2ndEd - MLwR_1stEd
MLwR_3rdEd - MLwR_2ndEd

# przekształcamy różnice w czasy trwania
as.duration(MLwR_2ndEd - MLwR_1stEd)
as.duration(MLwR_3rdEd - MLwR_2ndEd)

# przekształcamy czas trwania w lata
dyears()
as.duration(MLwR_2ndEd - MLwR_1stEd) / dyears()
as.duration(MLwR_3rdEd - MLwR_2ndEd) / dyears()

# łatwiejsza do zapamiętania wersja powyższych poleceń:
time_length(MLwR_2ndEd - MLwR_1stEd, unit = "years")
time_length(MLwR_3rdEd - MLwR_2ndEd, unit = "years")

# obliczamy wiek (jako czas trwania)
USA_DOB <- mdy("July 4, 1776") # Data "narodzin" Stanów Zjednoczonych
time_length(mdy("July 3 2023") - USA_DOB, unit = "years")
time_length(mdy("July 5 2023") - USA_DOB, unit = "years")

# obliczamy wiek (jako interwał)
interval(USA_DOB, mdy("July 3 2023")) / years()
interval(USA_DOB, mdy("July 5 2023")) / years()

# obliczamy wiek (za pomocą dzielenia całkowitego)
USA_DOB %--% mdy("July 3 2023") %/% years()
USA_DOB %--% mdy("July 5 2023") %/% years()

# funkcja do obliczania wieku kalendarzowego
age <- function(birthdate) {
  birthdate %--% today() %/% years()
}

# obliczamy wiek celebrytów
age(mdy("Jan 12, 1964")) # Jeff Bezos
age(mdy("June 28, 1971")) # Elon Musk
age(mdy("Oct 28, 1955")) # Bill Gates
