6 Tekst

Podstawowymi typami danych w R są wektory logiczne, numeryczne i znakowe (sekcja 5.1). Pierwsze z nich przyjmują dwie formy - TRUE i FALSE, przez co istnieje pewna skończona liczba operacji, które można na nich wykonać. Wektory numeryczne mogą przyjmować wiele form, ale najczęściej są one przetwarzanie używając podstawowych operacji arytmetycznych, takich jak dodawanie, odejmowanie, mnożenie czy dzielenie. Wektory znakowe są natomiast najbardziej zróżnicowane - mogę przyjmować różne formy (nawet w zależności od przyjętego alfabetu), w tym pozwalają one także na przechowywanie wartości logicznych czy numerycznych.

Celem tego rozdziału jest przedstawienie najczęściej spotykanych operacji na tekście, takich jak jego wyszukiwanie, wydzielanie czy zamiana. Więcej na temat przetwarzania tekstu można znaleźć w rozdziale “Strings” książki R for Data Science (Wickham and Grolemund 2016).

6.1 Reprezentacja tekstu

Typ znakowy jest określany poprzez użycie cudzysłowu " lub '. Ważne tutaj jest, aby rozpoczynać i kończyć tekst tym samym cudzysłowem.

t1 = "kot"
t2 = 'pies'
t3 = '"W teorii, teoria i praktyka są tym samym. W praktyce, nie są." - Yogi Berra'

W momencie, gdy tekst nie będzie kończył się cudzysłowem, wykonanie kodu jest niemożliwe. Wówczas zamiast znaku >, oznaczającego nową linię wykonywanego kodu, pojawi się znak +. Oznacza on, że wykonanie kodu nie może zostać zakończone.

> "Mój pierwszy alfabet
+
+

W takiej sytuacji należy nacisnąć klawisz Esc, aby przerwać wykonywanie operacji, a następnie poprawić wpisany kod.

6.2 Podstawowe operacje na tekście

Jedną z podstawowych operacji na wektorach znakowych jest ich łączenie. Do tego celu służy funkcja paste()32.

paste("t", "o", " ", "k", "o", "t")
#> [1] "t o   k o t"

Efekt działania funkcji paste() jest jeden wektor tekstowy, który składa się z wejściowych wektorów oddzielonych domyślnie spacjami. Funkcja paste() ma jednak również dodatkowy argument sep, który pozwala na dowolne określanie separatora. Ostatnim argumentem tej funkcji jest collapse, który łączy elementy jednego wektora tekstowego.

R oferuje też uproszczoną postać tej funkcji o nazwie paste0(), w której nie ma znaku separatora.

paste0("t", "o", " ", "k", "o", "t")
#> [1] "to kot"

Te funkcje są używane w sytuacjach, gdy chcemy połączyć stały, znany tekst, wraz z tekstem wprowadzanym przez użytkownika lub pochodzącym z innego źródła. Poniżej stworzono dwie nowe zmienne imie i wiek, których treść złączono ze słowami "ma" i "lat.".

imie = "Olek"
wiek = 77
tekst1 = paste(imie, "ma", wiek, "lat.")
tekst1
#> [1] "Olek ma 77 lat."

Takie konstrukcje są często używane w funkcjach. Powyższy przykład można by przepisać jako:

lata = function(imie, wiek){
  paste(imie, "ma", wiek, "lat.")
}
lata("Asia", 61)
#> [1] "Asia ma 61 lat."

Dodatkowo w R istnieje alternatywa dla paste() i paste0() w postaci funkcji sprintf().

Kolejne podstawowe funkcje, toupper() i tolower() zamieniają cały istniejący tekst na taki który posiada tylko duże lub małe litery.

toupper(tekst1)
#> [1] "OLEK MA 77 LAT."
tolower(tekst1)
#> [1] "olek ma 77 lat."

Są one używane w sytuacjach, gdy posiadamy dane, w których jeden tekst jest podany w kilku formach i chcemy je ujednolicić.

R posiada też wiele innych wbudowanych funkcji do obsługi tekstu (np. grep()), ale istnieją też specjalne pakiety poświęcone temu zagadnieniu, w tym pakiet stringr (Wickham 2019).

library(stringr)

Większość funkcji tego pakietu zaczyna się od prefiksu str_ co ułatwia znajdowanie funkcji w tym pakiecie i zmniejsza szansę na nałożenie się funkcji o takiej samej nazwie z innego pakietu.

Przykładową operacją na tekście jest jego sortowanie (czyli układanie alfabetycznie), do którego służy funkcja str_sort().

tekst2 = c("czosnek", " hałas", "ćma ")
tekst2
#> [1] "czosnek" " hałas"  "ćma "
str_sort(tekst2)
#> [1] " hałas"  "ćma "    "czosnek"

W powyższym przykładzie oczekiwalibyśmy ułożenia, w których "hałas" byłby na ostatnim miejscu. Nie jest tak z powodu istnienia z przodu tego wyrazu znaku niedrukowalnego - spacji. Aby usunąć spacje z przodu i tyłu tekstu można użyć funkcji str_trim().

tekst2 = str_trim(tekst2)
tekst2
#> [1] "czosnek" "hałas"   "ćma"

W tej chwili możemy użyć funkcji str_sort() jeszcze raz.

str_sort(tekst2)
#> [1] "ćma"     "czosnek" "hałas"

Teraz "hałas" jest poprawnie na ostatnim miejscu, ale na pierwszej pozycji jest "ćma" zamiast "czosnek". Różne alfabety na świecie mają inne znaki oraz ich kolejność. Domyślnie funkcja str_sort() używa alfabetu angielskiego, co w efekcie powoduje niepoprawne ułożenie polskich znaków. Do rozwiązania tego problemu służy argument locale, w którym można określić jaki alfabet ma być używany.

str_sort(tekst2, locale = "pl")
#> [1] "czosnek" "ćma"     "hałas"
str_sort(tekst2, locale = "cs")
#> [1] "ćma"     "czosnek" "hałas"

Powyżej można zobaczyć dwa przykłady - ułożenia tekstu według polskiego i czeskiego alfabetu33.

6.3 Wydzielanie tekstu

Częstym przypadkiem jest potrzeba wydzielenia tylko fragmentu tekstu. W tej sekcji zostanie pokazane jak wydzielać tekst na podstawie pozycji, ale możliwe jest również wydzielanie tekstu na podstawie wzorca (zobacz sekcję 6.5). Wydzielanie na podstawie pozycji jest używane w sytuacjach, gdy struktura wejściowego tekstu jest nam znana i stabilna, np. gdy interesuje nas wybranie fragmentu tekstu z automatycznie generowanych raportów.

tekst1 = "Olek ma 77 lat."

W przypadku wydzielania tekstu na podstawie pozycji należy określić pozycję pierwszego i ostatniego znaku, który nas interesuje. Można to zrobić na kilka sposobów. Pierwszy z nich polega na określeniu położenia znaków od lewej strony, np. poniższy kod wybiera tekst rozpoczynający się od 9 znaku i kończący się na znaku 15 włącznie.

str_sub(tekst1, start = 9, end = 15)
#> [1] "77 lat."

Definiowanie pozycji może się też odbywać od prawej strony tekstu używając znaku -.

str_sub(tekst1, start = 9, end = -1)
#> [1] "77 lat."

W powyższym przykładzie wybierany jest tekst zaczynający się na 9 znaku a kończący na pierwszym znaku od końca włącznie. Natomiast poniżej wybrany jest tekst zaczynający się na siódmym znaku od końca i kończący na pierwszym od końca włącznie.

str_sub(tekst1, start = -7, end = -1)
#> [1] "77 lat."

6.4 Wyrażenia regularne

Sprawdzanie czy dany tekst występuje w wektorze można wykonać używając funkcji str_detect().

tekst3 = c("Magdalena", "Lena", "1Lena.csv", "LLena", "Helena", "Anna", "99")

W takim wypadku konieczne jest zdefiniowanie argumentu pattern, czyli wzorca tekstowego, który nas interesuje. Aby znaleźć wszystkie wystąpienia (nawet fragmentaryczne) słowa "Lena" można użyć poniższego kodu.

str_detect(tekst3, pattern = "Lena")
#> [1] FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE

Jego efektem będzie wektor logiczny wskazujący, które elementy zawierają wybrany wzorzec (TRUE) oraz które go nie zawierają (FALSE). Wzorzec zdefiniowany w tej sposób jest czuły na wielkość znaków dlatego też zapytanie używając "Lena" da inny wynik niż takie używając "lena".

str_detect(tekst3, pattern = "lena")
#> [1]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE

W celu ułatwienia wyszukiwania złożonych fraz powstały wyrażenia regularne. Wyrażenia regularne (ang. regular expressions), często określane jako regex to sposób opisywanie wzorców tekstu. Używając wyrażeń regularnych możliwe jest wyszukiwanie, zamienianie, walidowanie i wydzielanie tekstu, który spełnia wymagane warunki. Wyrażenia regularne są powszechnie używane w wyszukiwarkach internetowych, edytorach tekstu, oraz wielu językach programowania.

Wyrażenia regularne opierają się o stosowanie szeregu operatorów (metaznaków) wymienionych w tabeli 6.1.

Tabela 6.1: Metaznaki w wyrażeniach regularnych.
Operator Wyjaśnienie
^ Określa początek tekstu/linii
$ Określa koniec testu/linii
() Grupowanie
| Alternatywa (lub)
[] Wymienia dozwolone znaki
[^] Wymienia niedozwolone znaki
* Poprzedni znak zostanie wybrany zero lub więcej razy
+ Poprzedni znak zostanie wybrany jeden lub więcej razy
? Poprzedni znak zostanie wybrany zero lub jeden raz
{n} Poprzedni znak zostanie wybrany n razy
. Jakikolwiek znak oprócz nowej linii (\n)
\ Pozwala na użycie specjalnych znaków

Wymienione powyżej znaki (np. ^ czy .) mają specjalne znaczenie. W związku z tym, jeżeli chcemy wyszukać tekstu zawierającego specjalny znak, musimy użyć ukośnik wsteczny (\, ang. backslash). Istnieje wiele dodatkowych znaków specjalnych, np. \n - nowa linia, \t - tabulator, \d - każdy znak numeryczny (stałoprzecinkowy), \s - znak niedrukowalny, np. spacja, tabulator, nowa linia.

Sprawdźmy działanie wyrażeń regularnych na kilku przykładach. W pierwszym z nich określiliśmy nasz wzorzec jako "^L", co oznacza, że interesują nas tylko elementy wektora tekst3 rozpoczynające się od dużej litery L.

str_detect(tekst3, pattern = "^L")
#> [1] FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE

Do określenia zakończenia wzorca służy metaznak $. Poniżej wyszukano elementy, które kończą się na ena.

str_detect(tekst3, pattern = "ena$")
#> [1]  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE

Operatory () i | można łączyć, aby zdefiniować alternatywy. Przykładowo, interesują nas elementy, które kończą się na ena lub nna.

str_detect(tekst3, pattern = "(ena|nna)$")
#> [1]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE

W wyrażeniach regularnych można też stosować pewne skrótowe polecenia. W poniższym przypadku interesują nas elementy, które zawierają jakiekolwiek znaki od małego a do małego z oraz dużego A do dużego Z.

str_detect(tekst3, pattern = "[a-zA-Z]")
#> [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE

Podobnie można określać wartości numeryczne - np. tylko elementy zawierające wartości od 0 do 9.

str_detect(tekst3, pattern = "[0-9]")
#> [1] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE

Celem metaznaku + jest określenie, że poprzedni znak musi wystąpić jeden lub więcej razy. Poniżej interesują nas tylko takie elementy, w których litera L występuje raz lub więcej.

str_detect(tekst3, pattern = "L+")
#> [1] FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE

W wyrażeniach regularnych metaznak ^ określa początek tekstu/linii, ale ma on też inne zastosowanie, gdy jest użyty w kwadratowym nawiasie. Przykładowo [^L] oznacza, że szukamy wszystkich elementów nie zawierających litery L. W poniższym przykładzie nie interesują nas elementy, które zaczynają się od jednej lub więcej litery L.

str_detect(tekst3, pattern = "^[^L]+")
#> [1]  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE

Metaznak . służy do określania jakikolwiek znaku, a ukośnik wsteczny (\) służy do określania innych znaków specjalnych. Dlatego też, jeżeli chcemy wyszukać elementów zawierających kropki (.) musimy połączyć ukośnik wsteczny z tym znakiem.

str_detect(tekst3, pattern = "\.")
#> Error: '\.' is an unrecognized escape in character string starting ""\."

Powyższy przykład daje jednak komunikat błędu - aby użyć ukośnik wsteczny do zasygnalizowania, że interesuje nas kropka musimy wprowadzić go dwa razy34.

str_detect(tekst3, pattern = "\\.")
#> [1] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE

Celem funkcji str_detect() jest wskazanie, który element spełnia dane zapytanie. Do wydzielenia elementu służy funkcja str_subset().

str_subset(tekst3, pattern = "\\.")
#> [1] "1Lena.csv"

Umiejętności używania wyrażeń regularnych można trenować używając różnych zasobów internetowych, np. strony https://regexr.com/, https://regex101.com/, czy https://regexcrossword.com/. Pomocne w zrozumieniu bardziej zaawansowanych elementów wyrażeń regularnych może być też prezentacja Best of Fluent 2012: /Reg(exp){2}lained/: Demystifying Regular Expressions oraz książka Mastering Regular Expressions (Friedl 2006).

6.5 Wydzielanie tekstu - regex

Innym często spotykanym problemem w pracy z tekstem jest posiadanie długiego elementu tekstowego, z którego chcemy tylko wydobyć pewien fragment. W sekcji 6.3 używaliśmy do tego pozycji, ale możemy zastosować również wzorce do tego celu.

tekst_pomiary = "Wrocław: 23.5, Bydgoszcz: 12.7, Toruń: 11.1, Lublin: 14.3"

Wektor tekst_pomiary zawiera tylko jeden element tekstowy, w którym wymienione są kolejne miasta i ich wartości. Wyobraźmy sobie, że interesują nas tylko nazwy miast zawarte w powyższym wektorze. Do wydzielania tekstu na podstawie wyrażeń regularnych służy funkcja str_extract().

str_extract(tekst_pomiary, pattern = "[a-zA-Z]*")
#> [1] "Wroc"

Podaliśmy jako wzorzec wszystkie litery od małego a do małego z oraz dużego A do dużego Z. Niestety w efekcie otrzymaliśmy tylko Wroc - taka definicja wzorca obejmuje tylko litery z angielskiego alfabetu.

Aby to naprawić możemy dodać do tego wzorca polskie litery.

str_extract(tekst_pomiary, pattern = "[a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]*")
#> [1] "Wrocław"

Tym razem otrzymaliśmy pełną nazwę pierwszego miasta, ale nie żadnego kolejnego. Funkcja str_extract() jest leniwa - po znalezieniu pierwszego pasującego fragmentu przestaje ona szukać dalej i przekazuje wynik.

Aby uzyskać wszystkie przypadki spełniające określony wzorzec należy użyć funkcji str_extract_all().

str_extract_all(tekst_pomiary, pattern = "[a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]*")
#> [[1]]
#>  [1] "Wrocław"   ""          ""          ""         
#>  [5] ""          ""          ""          ""         
#>  [9] ""          "Bydgoszcz" ""          ""         
#> [13] ""          ""          ""          ""         
#> [17] ""          ""          "Toruń"     ""         
#> [21] ""          ""          ""          ""         
#> [25] ""          ""          ""          "Lublin"   
#> [29] ""          ""          ""          ""         
#> [33] ""          ""          ""

Efektem jej działania są wszystkie nazwy miast z wektora tekst_pomiary, ale też wiele elementów pustych. Dlaczego? W powyższym wzorcu użyliśmy metaznaku *, który szuka wystąpienia zdefiniowanych znaków zero lub więcej razy. Gdy napotkany jest zdefiniowany znak sprawdzane jest jego kolejne wystąpienie, aż do momentu, gdy pojawi się jakiś inny znak. W efekcie zwrócony został np. "Wrocław". Metaznak * w przypadku, gdy zdefiniowanego znaku nie ma (wystąpił zero razy) zwraca pusty element.

Jeżeli interesują nas tylko fragmenty wektora zawierające tekst musimy użyć metaznaku +.

str_extract_all(tekst_pomiary, pattern = "[a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]+")
#> [[1]]
#> [1] "Wrocław"   "Bydgoszcz" "Toruń"     "Lublin"

Wyobrażmy sobie, że otrzymaliśmy rozszerzoną wersję poprzednich danych, która tym razem zawiera dwa dodatkowe miasta - Gorzów Wielkopolski i Zieloną Górę.

tekst_pomiary2 = "Wrocław: 23.5, Bydgoszcz: 12.7, Toruń: 11.1, Lublin: 14.3, 
Gorzów Wielkopolski: 20, Zielona Góra: 19"

Nadal interesuje nas wydzielenie nazw miast, więc próbujemy użyć kodu, który stworzyliśmy powyżej.

str_extract_all(tekst_pomiary2, pattern = "[a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]+")
#> [[1]]
#> [1] "Wrocław"      "Bydgoszcz"    "Toruń"       
#> [4] "Lublin"       "Gorzów"       "Wielkopolski"
#> [7] "Zielona"      "Góra"

Niestety w efekcie otrzymujemy osiem elementów, gdzie "Gorzów" jest innym elementem niż "Wielkopolski". Zdefiniowany przez nas wzorzec nie brał pod uwagę możliwości wystąpienia spacji. Możemy naprawić tę sytuację w poniższy sposób.

str_extract_all(tekst_pomiary2, 
       pattern = "[a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]+[\\s]?[a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]*")
#> [[1]]
#> [1] "Wrocław"             "Bydgoszcz"          
#> [3] "Toruń"               "Lublin"             
#> [5] "Gorzów Wielkopolski" "Zielona Góra"

Teraz szukamy wystąpienia liter co najmniej raz lub więcej (+), następnie wystąpienia spacji zero razy lub raz ([\\s]?) i kończymy na sprawdzeniu wystąpienia tekstu zero razy lub więcej (*).

Podobnie jak w każdym powyższym przypadku, efekt działania funkcji może być użyty do stworzenia nowego obiektu.

miasta_pomiary2 = str_extract_all(tekst_pomiary2,
       pattern = "[a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]+[\\s]?[a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]*")
miasta_pomiary2
#> [[1]]
#> [1] "Wrocław"             "Bydgoszcz"          
#> [3] "Toruń"               "Lublin"             
#> [5] "Gorzów Wielkopolski" "Zielona Góra"

6.6 Zamiana tekstu - regex

Innym przykładem działania na tekście jest zamiana wybranych jego elementów.

tekst_pomiary3 = "Wrocław: 23.5, Bydgoszcz: 12.7, Toruń: 11.1, Lublin: 14.3"

Powyższy obiekt tekst_pomiary3 zawiera nazwy miast i wartości pomiarów przedstawione zgodnie z amerykańskim standardem, gdzie kropka oddziela wartości dziesiętne, a przecinek kolejne elementy. Aby zamienić wybrany wzorzec w tekście (np. kropkę na przecinek) możemy użyć funkcji str_replace(), w której podajemy obiekt tekstowy, szukany wzorzec oraz jego zamianę.

str_replace(tekst_pomiary3, 
            pattern = ".", 
            replacement = ",")
#> [1] ",rocław: 23.5, Bydgoszcz: 12.7, Toruń: 11.1, Lublin: 14.3"

Efekt działania tego kodu nie jest jednak zgodny z naszymi oczekiwaniami. Zamiast zamiany wszystkich kropek na przecinki, nastąpiła zamiana pierwszego znaku w tekście (litery W) na przecinek. Wynika to ze znaczenia metaznaku ., który reprezentuje jakikolwiek znak oprócz nowej linii. Żeby naprawić tę sytuację musimy użyć ukośnika wstecznego.

str_replace(tekst_pomiary3, 
            pattern = "\\.", 
            replacement = "\\,")
#> [1] "Wrocław: 23,5, Bydgoszcz: 12.7, Toruń: 11.1, Lublin: 14.3"

Funkcja str_replace(), podobnie jak str_extract(), jest leniwa i zamienia tylko pierwsze wystąpienie wzorca. Do zamiany wszystkich przypadków trzeba użyć funkcji str_replace_all().

str_replace_all(tekst_pomiary3, 
                pattern = "\\.", 
                replacement = "\\,")
#> [1] "Wrocław: 23,5, Bydgoszcz: 12,7, Toruń: 11,1, Lublin: 14,3"

W przypadku, gdy interesuje nas zarówno zamiana kropek na przecinki oraz przecinków na średniki, musimy zacząć od tej drugiej zamiany.

tekst_pomiary4 = str_replace_all(tekst_pomiary3,
                                 pattern = "\\,",
                                 replacement = "\\;")

Nowy obiekt tekst_pomiary4 oddziela kolejne miasta średnikami. Teraz na jego podstawie możliwa jest zamiana kropek na przecinki w sposób opisany powyżej.

str_replace_all(tekst_pomiary4, 
                pattern = "\\.", 
                replacement = "\\,")
#> [1] "Wrocław: 23,5; Bydgoszcz: 12,7; Toruń: 11,1; Lublin: 14,3"

Funkcje jakie jak str_replace() czy str_replace_all() mogą być też stosowane do usuwania fragmentów tekstu. Do tego celu można zdefiniować wzorzec jaki chcemy usunąć, a jako jego zamianę tekst pusty ("").

str_replace_all(tekst_pomiary4, 
                pattern = "[a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]+",
                replacement = "")
#> [1] ": 23.5; : 12.7; : 11.1; : 14.3"

6.7 Wyszukiwanie plików

Umiejętności związane z obsługą wyrażeń regularnych przydają się też w przypadku wyszukiwania plików zawierających określony tekst w nazwie lub specyficzne rozszerzenie. Jest to szczególnie przydatne, gdy posiadamy wiele plików na komputerze, które chcemy następnie przetwarzać w sposób automatyczny.

Do wyświetlania nazw plików znajdujących się w wybranym folderze służy funkcja dir(). Przykładowo poniższa linia kodu wyświetla wszystkie pliki znajdujące się w folderze "pliki"35.

dir("pliki")
#>  [1] "dane_meteo.csv"  "dane_meteo.rds" 
#>  [3] "dane_meteo.xlsx" "dane_meteo2.csv"
#>  [5] "dokument.docx"   "kod.R"          
#>  [7] "list.txt"        "mapa.png"       
#>  [9] "obrazek.png"     "zdjecie.jpg"

W przypadku, gdy interesują nas tylko pliki o wybranym rozszerzeniu możemy użyć argumentu pattern i zdefiniować wzorzec.

dir("pliki", pattern = "*\\.png$")
#> [1] "mapa.png"    "obrazek.png"

W powyższym przykładzie zostaną wybrane tylko pliki o jakiejkolwiek nazwie, ale kończące się na rozszerzenie .png. Metaznak $ użyty w tym przypadku zapobiega sytuacji, gdy tekst .png znajduje się w środku nazwy pliku.

Do znalezienia plików o kilku rozszerzeniach można użyć metaznaków () i |.

dir("pliki", pattern = "*\\.(png|jpg)$")
#> [1] "mapa.png"    "obrazek.png" "zdjecie.jpg"

Domyślnie funkcja dir() pokazuje zawartość wybranego folderu, aby jednak poznać jego pełną ścieżkę względną należy określić argument full.names na TRUE.

dir("pliki", pattern = "*\\.(png|jpg)$", full.names = TRUE)
#> [1] "pliki/mapa.png"    "pliki/obrazek.png"
#> [3] "pliki/zdjecie.jpg"

6.8 Zadania

  1. Plik tekstowy zawiera listę pomiarów, w której piąty i czwarty znak od końca oznacza symbol chemiczny pomierzonego pierwiastka, przykładowo:
"TERYT 18; podkarpackie; Rzeszów; 0.2 He; A"
"TERYT 22; pomorskie;   Gdańsk; 12 C ; B"

Napisz kod, który będzie wydzielał symbole chemiczne pomierzonych pierwiastków.

  1. Napisz funkcję nazywającą się horoskop, która przyjmuje dwa argumenty imie (pierwsze imię, tekst) oraz miesiac (miesiąc urodzin, liczba). Funkcja ma zwrócić tekst “Osoba o imieniu ‘imie’ będzie miała jutro szczęście.” w przypadku, gdy argument miesiac jest liczbą parzystą oraz “Osoba o imieniu ‘imie’ będzie miała jutro nieszczęście.” jeżeli argument miesiac jest liczbą nieparzystą.
  2. Rozbuduj funkcję horoskop poprzez sprawdzenie pierwszej litery podanego imienia. Jeżeli pierwsza litera imienia to K, M, lub Z wówczas wyświetli się zawsze tekst “Osoba o imieniu ‘imie’ będzie miała jutro szczęście.”, bez względu na podany miesiąc.
  3. Efektem zbierania pomiarów temperatury okazał być się plik tekstowy, który zawiera datę pomiaru oraz wartość. W jaki sposób możliwe jest wydzielenie tylko dat w takiej sytuacji? Poniżej znajduje się fragment przykładowych danych wejściowych.
"2019-03-11: 23.5, 19/03/12: 12.7, 2019.03.13: 11.1, 2019-marzec-14: 14.3"
  1. Co należałoby zrobić, aby wydzielić tylko wartości pomiarów w powyższym przypadku? Stwórz nowy obiekt wartosci zawierający te pomiary. Jakiej klasy powinien być wyjściowy obiekt?
  2. Posiadasz wektor wsp zawierający współrzędne geograficzne szeregu miast w formacie DMS (Stopnie, Minuty, Sekundy). Wydziel tylko wartości stopni z tej reprezentacji. Poniżej znajduje się fragment przykładowych danych wejściowych.
wsp = c("52°24′N 16°55′E", "53°08′07″N 23°08′44″E", "39°6′N 84°31′W")
  1. Stwórz funkcję, która przyjmując przykładowe dane z poprzedniego zadania zamieni współrzędne na format w postaci stopni dziesiętnych (np. 52°24′N w formacie DMS to 52.4 w stopniach dziesiętnych).

Bibliografia

Friedl, Jeffrey EF. 2006. Mastering Regular Expressions. " O’Reilly Media, Inc.".

Wickham, Hadley. 2019. Stringr: Simple, Consistent Wrappers for Common String Operations. https://CRAN.R-project.org/package=stringr.

Wickham, Hadley, and Garrett Grolemund. 2016. R for Data Science: Import, Tidy, Transform, Visualize, and Model Data. " O’Reilly Media, Inc.".


  1. Odpowiednikiem funkcji paste() w pakiecie stringr jest funkcja str_c()↩︎

  2. https://en.wikipedia.org/wiki/Czech_orthography↩︎

  3. https://xkcd.com/1638/↩︎

  4. Folder o tej nazwie znajduje się w folderze roboczym.↩︎