18 Práce se stringy
Předmětem této kapitoly jsou stringy, tedy nestrukturovaný text. O analýze nestrukturovaného toho lze napsat mnoho, mnohem více, než kolik dokáže pojmout tato kniha. Představíme si proto pouze úplné základy a to s pomocí balíčku stringr
, který je součástí Tidyverse.
18.1 Detekce stringů
Náš data frame countries
obsahuje proměnnou hd_title_name
. Jedná se o titula a jméno hlavy dané země (k roku 2018). Na rozdíl od ostatních kategoriálních proměnných jsou jak titul, tak jméno osoby v jednom sloupci. Práce s nimi tedy bude vyžadovat o něco jiný přístup, než na jaký jsme zvyklí.
Jedním z nejběžnějších úkonů je vyhledávání vzorců (patterns) v textu. Pro vybraní zemí, jejichž hlavou je král, je možné zkombinovat již známou funkci filter()
s funkcí str_detect()
. Tato funkce vrátí hodnotu TRUE
pro všechny řádky, ve kterých se nachází zvolený vzorec znaků, v našem případě “King”:
%>%
countries filter(str_detect(hd_title_name, pattern = "King")) %>%
select(country, hd_title_name)
# A tibble: 5 × 2
country hd_title_name
<chr> <chr>
1 Belgium King - Philippe
2 Spain King - Felipe VI
3 Netherlands King - Willem-Alexander
4 Sweden King - Carl XVI Gustaf
5 Norway King - Harald V
Pomocí stejné funkce je možné hledat i více vzorců na jednou. Pro vyhledání všech království našem datasetu vyhledáme všechny hlavy států s titulem “King” nebo “Queen”. Oba hledané vzorce oddělíme znakem |
, značící logický operátor OR:
%>%
countries filter(str_detect(hd_title_name, pattern = "King|Queen")) %>%
select(country, hd_title_name)
# A tibble: 7 × 2
country hd_title_name
<chr> <chr>
1 Belgium King - Philippe
2 Denmark Queen - Margrethe II
3 Spain King - Felipe VI
4 Netherlands King - Willem-Alexander
5 Sweden King - Carl XVI Gustaf
6 United Kingdom Queen - Elizabeth II
7 Norway King - Harald V
V některých případech nám bude stačit vědět, kolikrát se určitý vzorec vyskytuje v datech. K tomu využijeme funkci str_count()
. Protože pracujeme s vektorem stringů, zkombinujeme ji s funkcí sum()
, abychom získali celkový počet monarchů napří všemi zeměmi:
sum(str_count(countries$hd_title_name, pattern = "King|Queen"))
[1] 7
18.2 Separace stringů
Pro usnadnění budoucí práce by bylo lepší proměnnou hd_title_name
rozdělit do dvou nových proměnných. První z nových proměnných bude titul hlavy státu (title
), druhou poté samotné jméno státnika (name
). Toho nejjednodušeji docíleme pomocí funkce separate()
z balíčku tidyr
. Prvním argumentem této funkce, je string, který chceme rozdělit. Druhým argumentem, into
, je vektor obsahující jména nových proměnných. Třetím argumentem je separátor (sep
), který rozděluje obsah první a druhé z nových proměnných:
%>%
countries select(hd_title_name) %>%
separate(hd_title_name,
into = c("title", "name"),
sep = "-") %>%
head(5)
Warning: Expected 2 pieces. Additional pieces discarded in 4 rows [5, 11, 19,
30].
# A tibble: 5 × 2
title name
<chr> <chr>
1 King " Philippe"
2 President " Rumen Radev"
3 President " Miloš Zeman"
4 Queen " Margrethe II"
5 President " Frank"
Tento kód téměř funguje, jak má, s jedním drobným problémem. Jak nás upozorňuje varování Warning: Expected 2 pieces. Additional pieces discarded in 4 rows [5, 11, 19, 30].
v několika jménech se objevil náš separátor -
více než jednou. Protože jsme ale specifikovali pouze dvě nové proměnné, title
a name
, zahodili jsme omylem část jmen na řádcích 5, 11, 19 a 30. Napravit to můžeme pomocí argumentu extra = "merge"
, pomocí kterého zachováme všechny jména celé:
%>%
countries select(hd_title_name) %>%
separate(hd_title_name,
into = c("title", "name"),
sep = "-",
extra = "merge") %>%
head(5)
# A tibble: 5 × 2
title name
<chr> <chr>
1 King " Philippe"
2 President " Rumen Radev"
3 President " Miloš Zeman"
4 Queen " Margrethe II"
5 President " Frank-Walter Steinmeier"
18.3 Transformace stringů
V některých případech je nutné stringy transformovat, buď do podoby vhodné pro analýzy nebo naopak do podoby vhodné pro prezentaci výstupů. Balíček stringr
pro transformaci stringů nabízí hned několik funkcí. Funkce str_to_lower()
převede všechny písmena na malá, str_to_upper()
naopak na velká. str_to_sentence()
převede první písmeno na velké a zbytek na malá, a nakonec str_to_title()
převede první písmeno každého slova na velké a zbytek na malá:
str_to_lower(countries$hd_title_name) %>% head(5)
[1] "king - philippe" "president - rumen radev"
[3] "president - miloš zeman" "queen - margrethe ii"
[5] "president - frank-walter steinmeier"
str_to_upper(countries$hd_title_name) %>% head(5)
[1] "KING - PHILIPPE" "PRESIDENT - RUMEN RADEV"
[3] "PRESIDENT - MILOŠ ZEMAN" "QUEEN - MARGRETHE II"
[5] "PRESIDENT - FRANK-WALTER STEINMEIER"
str_to_sentence(countries$hd_title_name) %>% head(5)
[1] "King - philippe" "President - rumen radev"
[3] "President - miloš zeman" "Queen - margrethe ii"
[5] "President - frank-walter steinmeier"
str_to_title(countries$hd_title_name) %>% head(5)
[1] "King - Philippe" "President - Rumen Radev"
[3] "President - Miloš Zeman" "Queen - Margrethe Ii"
[5] "President - Frank-Walter Steinmeier"