---
title: "Strings"
output: html_notebook
---

```{r}
library(tidyverse)
library(readxl)
library(magrittr)
```

# Jak se bude jmenovat?

Pomocí chytrých filtrů na tabulce křestních jmen od Statistického úřadu vybereme
k zadanému příjmení a pohlaví dítěte pěkné křestní jméno. A dokonce půjde i 
trochu určit, jak obvyklé to jméno má být.  

## Prezentované jevy
- stažení souboru z url
- načtení excelového souboru
- čištění tabulky 
- vybrané funkce knihovny stringr a jednoduché regulární výrazy
- filtrování řádků tabulky pomocí logických operátorů 
- (převedení skriptu na funkci) výhledově
- (hromadné načtení a zpracování souborů) výhledově

## Postup

Stáhneme a vyčistíme si tabulku se jmény tak, aby obsahovala tyto sloupce:
 - name
 - sex
 - year
 - percentile
 
 Pak budeme vybírat řádky s křestními jmény pro
 to správné pohlaví a případně rozsah percentilů, podle nějakých podmínek, které
 si hned dále specifikujeme. 
 Budeme tvořit filtry na základě porovnání křestního jména s příjmením na každém 
 řádku. Příjmení si buď můžeme přidat jako sloupec ke každému řádku, nebo ho 
 nechat jako proměnnou mimo data frame. 
 
 Tabulku jsme stahovali z webu a čistili v souboru `strings02.`
 
## Kritéria "pěkného křestního jména"
Pro kombinaci jména a příjmení se traduje několik zásad, které tu podle možnosti
 aproximujeme funkcemi na prohledávání řetězců a jednoduchými regulárními výrazy. 
 

### Pavel Pavel
Jméno by nemělo být shodné s příjmením.


### Věnceslava Božetěcha Drahokoupilová
Když je dlouhé příjmení, nemělo by být moc dlouhé křestní jméno. Délku řetězce 
aproximujeme počtem samohlásek. Dvojhlásky ignorujeme, tj. počítáme jako dvě 
samohlásky. Ono to tak většinou je i správně: Eduard, Marie... netrefí např. Alois. 
Pravidlo by mohlo být, že příjmení s pěti a více slabikami by se nemělo kombinovat
s křestním jménem o pěti a více slabikách. 



### Hynek Cinek
Křestní jméno by se nemělo rýmovat s příjmením. Aproximujeme jako poslední 
tři znaky každého řetězce. Pokud implementujeme tohle, máme tím zároveň vyřešené 
zcela shodné jméno a příjmení! 

```{r}
string <- c("Hynek", "Cinek")
str_sub(string = string ,start = -3, end = -1 )
```


### Radomír Gruber
Některé hlásky, například "r" se mnoha lidem obtížně vyslovují. Spočítáme "r" 
v křestním jménu a v příjmení, sečtěte je a otestujte, že výsledek je menší 
než váš limit (třeba tři výskyty)


```{r}
str_count
```


### Tomáš Špičák
Křestní jméno by nemělo končit hláskou, kterou začíná příjmení.

__Jak to operacionalizujeme?__
Řádek tabulky splní podmínky, když poslední hláska v hodnotě ve sloupci `name` bude stejná 
(`==`) jako první hláska v hodnotě 
`surname`. 

Hláska může a nemusí odpovídat jednomu znaku. Například hláska "š" na konci 
slova může být zapsána jako "š" i jako "ž" (pomineme různé cizokrajnosti). 

__Implementace___
Pro každý z případů potřebujeme regulární výraz ve funkci, která z něj vrátí 
porovnatelný výsledek. 

- operátor pro konec řádku v regulárním výrazu: `$` 
- operátor pro začátek řádku v regulárním výrazu: `^`
- funkce na detekci daného regulárního výrazu: `str_detect`. Vrací 
`TRUE`/`FALSE`. 

__Test__
Napřed otestujeme, že regulární výrazy hledají, co mají. 

```{r}
name <- c("Rudolf", "Václav", "Olaf", "Milan")
surname <- c("Včela", "Froněk", "Frid", "Fojtek") 
```

```{r}
stringr::str_view(string = name, pattern = "[vf]$") 
```

```{r}
stringr::str_view(string = surname, pattern = "^[VF]")
```


```{r}
stringr::str_detect(string = name, pattern =  "[vf]$") == 
  stringr::str_detect(string = tolower(surname), pattern = "^[vf]")
```

Pro dvojici fv - FV to funguje správně. Takových dvojic je ale víc. Budeme je 
muset vzít jednu po druhé a pak zkombinovat.
Půjde asi ještě o *p-b, t-d, k-g, s-z, š-ž, ř-ř* (pomineme zatím *ť-ď* a *ch-h*). 
Poukládáme si ty výrazy do proměnných, aby se líp skládaly v té velké podmínce. 

```{r}
vf <- stringr::str_detect(string = name, pattern =  "[vf]$") #small letters = end of name
VF <- stringr::str_detect(string = tolower(surname), pattern = "^[vf]") 
vf_test <- vf == VF
#capital letters = start of surname (even if tolower!)
```

Testujte a implementujte. Vymýšlejte si vlastní testovací příklady jmen a příjmení. 
Nemusíte používat `str_view`, když vám bude stačit booleovský test.
__p-b, P-B__
```{r pb-PB_tests}
name <- c("Amenhotep")
surname <- c("Peterka")
stringr::str_view(string = name, pattern = "[pb$]")
stringr::str_view(string = tolower(surname), pattern = "^[pb]")
```

```{r pb-PB_variables}
pb <- str_detect(string = name, pattern = "[pb$]")
PB <- str_detect(string = tolower(surname), pattern = "^[pb]")
pb_test <- pb + PB == 1
```


Průběžný test: připravíme si jména a příjmení s a bez dvojic pb a vf a podmínku 
zkombinujeme. 
```{r}
name <- c("Václav", "Václav","Amenhotep", "Richard" ,"Milan")
surname <- c("Fojtek", "Jeřábek", "Peterka", "Procházka" , "Nebeský")
pb <- str_detect(string = name, pattern = "[pb$]")
PB <- str_detect(string = tolower(surname), pattern = "^[pb]")
#pb_test <- pb & PB == TRUE
#pb_test <- pb & PB
pb_test <- pb + PB == 2 #to byly tři různé možnosti, jak napsat logický výraz. 
# pozor, aby se u dvou vektorů tvořily součty pro každý element zvlášť, je potřeba
# použít plus, ne funkci sum. Ta by vrátila souhrnný součet (jedno číslo bez ohledu na délku vektorů)!
vf <- stringr::str_detect(string = name, pattern =  "[vf]$") #small letters = end of name
VF <- stringr::str_detect(string = tolower(surname), pattern = "^[vf]") 
vf_test <- vf + VF == 2
(test_pbvr <- pb_test + vf_test == 1) # proč tady 1 a ne 2? protože netestujeme, jestli 
# vyšly pravdivě oba testy najednou, ale jen jeden. Oba vyjít pravdivě nemůžou.
```
porovnejte - správně
```{r}
pb_test | vf_test #ekvivalent pb_test + vf_test == 1
```

porovnejte - chybně

```{r}
pb_test & vf_test #ekvivalent pb_test + vf_test == 2
```
Aby tohle vyšlo všechno TRUE, muselo by každé jméno končit zároveň na v nebo f a p nebo b, 
analogicky u příjmení. 


Ještě zbývají testy pro tyto páry:  *t-d, k-g, x-s-z, š-ž, ř-ř* 


```{r td-TB}
name <- c("Eduard")
surname <- c("Tykev")
td <- str_detect(string = name, pattern = "")
TD <- str_detect(string = tolower(surname), pattern = "")
td_test <- td + TD == 
```


```{r kg-KG}
name <- c("Irving")
surname <- c("Kořínek")
kg
KG
kg_test
```

```{r xsz-XSZ}
name <- 
surname <- 
xsz
XSZ
xsz_test
```

```{r sj-zj}
#radsi zadnou diakritiku do nazvu chunku v RMarkdownu.
name <- 
surname <- 
sj 
SJ
sj_test
```

```{r rj-rj}
name <- 
surname <-  
```


__Speciální případy *ch-H* a *ďť-ĎŤ*__
Řešením jsou tzv. Look-ahead a Look-behind regular expressions. Můžete do nich
uvést, co předchází nebo následuje tomu, co hledáte. Někdy se říká, že reg. výraz
nějaké znaky "konzumuje". Značky začátku a konce řádku, look-ahead/behind a 
další konzumovány nejsou. Téma na samostatné studium. Zde příklad look-behind a ahead. 

```{r ch-H}
name <- c("Enoch", "Mirzadih")
surname <- c("Hořejší", "Choděra")
chh <- str_detect(string = name, pattern = "h$")# tady je jedno,co před tím h je
Ch <- str_detect(string = tolower(surname), pattern = "(?<=^c)h") #"h, před kterým jsem viděl začátek řádku a c."
# My ale potřebujeme ještě alternativu s H, takže proměnnou Ch dál nepoužijeme. 
ChH <- str_detect(string = tolower(surname), pattern = "((?<=^c)h|^h)") 
# h, před kterým jsem buď viděl začátek řádku a c, nebo jen začátek řádku 
```
To ChH by tedy šlo mnohem jednodušeji: 
```{r}
ChH <- str_detect(string = tolower(surname), pattern = "^c?h") 
# h, před kterým jsem viděl začátek řádku a nula nebo jeden výskyt c. 
```

Ale pro detekci Ď a Ť na začátku slova už se bez look ahead neobejdeme

```{r}
surname <- c("Diblík", "Dědek", "Ďábel", "Dudák", "Tiblík", "Tětěra", "Tuták")
djtj <- str_detect(string = tolower(surname), pattern = "(^[ďť]|^[dt](?=[ěií]))") 
print(djtj)
# začátek řádku buď rovnou ď, nebo d, po kterém následuje ě nebo i
```

__Teď všechno najednou__
Zkopírujte sem proměnné s regulárními výrazy i testy a vytvořte jednu proměnnou 
testu pro všechny podmínky dohromady. Otestujte na dodaných vektorech `name`
a `surname`. Všechny by vám měly vyjít pozitivní. 


```{r}
name <- c("Václav", "Rudolf", "Adolf", "Olav", 
          "Amenhotep", "Merab", 
          "Albert", "Hubert", "Eduard", "Bernd",
          "Alois", "Shiraz", "Abrasax",
          "Irving", "Lolek", "Oleg", "Bolek",
          "Antoš", "Miloš", "Tomaž",
          "Řehoř",
          "Bahnochoď", "Ofoť"
          )
surname <- c("Včela", "Vlček", "Fitsch", "Flink",
             "Brambora", "Pitínská", 
             "Tydlitát", "Drašar", "Duda", "Troska", 
             "Slepička", "Zlochová", "Sýkora", 
             "Kořínek", "Groš", "Grůber", "Kutil",
             "Žižka", "Šiška", "Žlůva",
             "Řežábek",
             "Děravý", "Ďůlek"
             )
```
 




















 
  
  
  
  
  
  
  
  
  
  










