Tick Char Weighted – Opcje binarne Wskazniki

Najlepsi brokerzy opcji binarnych 2020:
  • Binarium
    Binarium

    1 miejsce w rankingu! Najlepszy wybor dla poczatkujacego!
    Bezplatne konto szkoleniowe i demo!
    Bonus za rejestracje!

  • FinMax
    FinMax

    Uczciwy i niezawodny broker! Dobre recenzje!

Checking your browser before accessing 4programmers.net.

This process is automatic. Your browser will redirect to your requested content shortly.

Przemysław Biecek. Przewodnik po pakiecie

    Marian Jakubowski 3 lat temu Przeglądów:

3 Przemysław Biecek Przewodnik po pakiecie

4 Przemysław Biecek Przewodnik po pakiecie

5 Wnioski, skargi i zażalenia należy kierować na adres dr hab. inż. Przemysław Biecek Uniwersytet Warszawski, Politechnika Warszawska strona www: Redakcja i korekta Katarzyna Wróbel Projekt okładki: Jakub Rakusa-Suszczewski Skład komputerowy książki w systemie LATEX: Przemysław Biecek Przygotowałem tę książkę, aby przedstawić możliwości programu R, filozofię pracy z tym programem, pokazać dobre praktyki dotyczące codziennej pracy z danymi w R. Liczę, że książka ta przyda się tym wszystkim, którzy w pracy lub w szkole zajmują się analizą danych. Książka może być wykorzystana, jako pomoc w nauce programu R lub jako atlas funkcjonalności i możliwości tego programu. W latach używałem jej z powodzeniem jako główny podręcznik do przedmiotu Programowanie w R. Mam nadzieje, że pomoże ona odkryć przyjemność w pracy z danymi i z programem R. Pod adresem czytelnik znajdzie dodatkowe informacje, treści przykładów oraz odnośniki do innych materiałów pomagających w nauce programu R. Dziękuję za pomoc przy przygotowaniu czwartego wydania, wiele cennych uwag i korekt (w kolejności alfabetycznej): Bartoszowi Jabłońskiemu, Katarzynie Pękała, Pawłowi Sakowskiemu, Bartoszowi Sękiewiczowi, Małgorzacie Szatkowskiej-Żak i Krzysztofowi Trajkowskiemu. Dziękuję mojej żonie i dzieciom za cierpliwość, wsparcie i wyrozumiałość. Copyright c 2008, 2020, 2020, 2020 by Przemysław Biecek Wszelkie prawa zastrzeżone. Żadna część niniejszej publikacji, zarówno w całości, jak i we fragmentach, nie może być reprodukowana w sposób elektroniczny, fotograficzny i inny bez pisemnej zgody posiadaczy praw autorskich. Wydanie czwarte rozszerzone, Wrocław 2020 ISBN: Oficyna Wydawnicza GiS, s.c., Druk i oprawa: I-BiS Usługi Komputerowe Wydawnictwo s.c.

6 Spis treści 1. Wprowadzenie Data science, czyli dlaczego warto poznać R Jak wygląda praca z programem R Przykład: Pozycja Polski w rankingu FIFA Jak przygotować środowisko pracy Instalacja podstawowego środowiska R Instalacja edytora RStudio Instalacja dodatkowych pakietów Gdzie szukać dalszych informacji Podstawy pracy z R Wczytywanie danych Struktury danych Wektory Ramki danych Listy Statystyki opisowe Zmienne ilościowe Zmienne jakościowe Statystyki graficzne Wykres słupkowy Histogram Wykres pudełkowy Jądrowy estymator gęstości Wykres kropkowy Wykres mozaikowy Jak przetwarzać dane z pakietem dplyr Jak filtrować wiersze Jak wybierać kolumny Jak tworzyć i transformować zmienne Jak sortować wiersze Jak pracować z potokami v

7 vi Spis treści Jak wyznaczać agregaty/statystyki w grupach Postać szeroka/postać wąska Sklejanie/rozcinanie kolumn Jak wczytać i zapisać dane w różnych formatach Wczytywanie danych z pakietów Wczytywanie danych z plików tekstowych Zapisywanie danych do pliku tekstowego Wczytywanie i zapisywanie z zastosowaniem formatu JSON Wczytywanie danych w formatach HTML i XML Inne formaty plików tekstowych Wczytywanie danych z plików Excela Wczytywanie danych z SPSS a Wczytywanie danych z programu Matlab Wczytywanie danych z SAS Inne funkcje do importu danych Automatyczne raporty, powtarzalne badania Pakiet knitr, markdown a raporty w HTML Prezentacje w HTML Pakiet Sweave a raporty w języku L A TEX Niezbędnik programisty Instrukcje sterujące Jak tworzyć funkcje Jak stosować instrukcje warunkowe Jak budować pętle Jak pracować z bazami danych Jak pracować z bazą danych SQLite Jak pracować z większymi relacyjnymi bazami danych Jak używać pakietu dplyr w pracy z bazami danych Budowa aplikacji WWW z pakietem shiny Jak wygląda model akcja reakcja Jak opisać interfejs użytkownika Jak opisać przetwarzanie na serwerze Jak dodawać kontrolki sterujące Budowanie własnych pakietów Niezbędne oprogramowanie Jak wygląda struktura pakietu Jak stworzyć nowy pakiet Plik DESCRIPTION Jak dodawać funkcje do pakietu Jak dodawać zbiory danych do pakietu

8 Spis treści vii Jak dodawać testy do pakietu Jak budować stworzony pakiet Git, GitHub i kontrola wersji Jak kopiować repozytorium clone Jak dodawać zmiany commit Debugger Co mogłoby pójść źle? Błędy i ostrzeżenia Co można zrobić post-mortem funkcja traceback() Jak zastawić pułapkę funkcja recover() Jak śledzić krok po kroku funkcja debug() Jak ignorować błędy funkcja try() Zaokrąglenia numeryczne studium przypadku Profiler Jak mierzyć czas działania bloku instrukcji Jak mierzyć czas co do milisekundy Jak szukać wąskich gardeł Jak przedstawiać graficznie wyniki profilowania Jak zrównoleglać obliczenia Jak zwiększać wydajność R Więcej o obiektach w R Funkcje polimorficzne i klasy S Tworzenie własnych operatorów Obiekty wywołań funkcji Leniwa ewaluacja Zasięg symboli w przestrzeniach nazw Współdzielona przestrzeń nazw Obiekty Klasy S Formuły Inne przydatne funkcje Rodzina funkcji *apply Pakiety plyr i reshape Funkcje systemowe Operacje na plikach i katalogach Niezbędnik statystyka Generatory liczb losowych Wprowadzenie do generatorów liczb pseudolosowych Popularne rozkłady zmiennych losowych Wybrane metody generowania zmiennych losowych

9 viii Spis treści Estymacja parametrów rozkładu Wstępne przetwarzanie danych Brakujące obserwacje Normalizacja, skalowanie i transformacje nieliniowe Analiza wariancji, regresja liniowa i logistyczna Wprowadzenie do analizy wariancji Analiza jednoczynnikowa Analiza wieloczynnikowa Regresja Wprowadzenie do regresji logistycznej Testowanie Testowanie zgodności Testowanie hipotezy o równości parametrów położenia Testowanie hipotezy o równości parametrów skali Testowanie hipotez dotyczących wskaźnika struktury Testy istotności zależności pomiędzy dwoma zmiennymi Testowanie zbioru hipotez Rozkład statystyki testowej Bootstrap Rozkład i obciążenie estymatorów Testy bootstrapowe Analiza przeżycia Krzywa przeżycia Model Coxa Wybrane funkcje matematyczne Operacje na zbiorach Operacje arytmetyczne Wielomiany Bazy wielomianów ortogonalnych Szukanie maksimum/minimum/zer funkcji Rachunek różniczkowo całkowy Graficzna prezentacja danych Znajdź siedem różnic Jak zapisać wykres do pliku Pakiet lattice Wprowadzenie Szablony dla wykresów Formuły i wybór zmiennych Panele i mechanizm warunkowania Mechanizm grupowania

Najlepsi brokerzy opcji binarnych 2020:
  • Binarium
    Binarium

    1 miejsce w rankingu! Najlepszy wybor dla poczatkujacego!
    Bezplatne konto szkoleniowe i demo!
    Bonus za rejestracje!

  • FinMax
    FinMax

    Uczciwy i niezawodny broker! Dobre recenzje!

10 Spis treści ix Legenda wykresu Atlas funkcji graficznych z pakietu lattice Więcej o panelach Motywy i parametry graficzne Zaawansowane opcje Pakiet ggplot Wprowadzenie Warstwy wykresu Mapowanie zmiennych na atrybuty wykresu Geometria warstwy Statystyki i agregacje Mechanizm warunkowania Kontrola skal Układ współrzędnych i osie wykresu Motywy i kompozycje graficzne Pozycjonowanie wykresów na rysunku Obiekt klasy gg Pakiet graphics Wprowadzenie Funkcja plot() Funkcja matplot() Osie wykresu Legenda wykresu Funkcja image() Wyrażenia matematyczne Kolory Właściwości linii Właściwości punktów/symboli Atomowe, niskopoziomowe funkcje graficzne Tytuł, podtytuł i opisy osi wykresu Pozycjonowanie wykresu, wiele wykresów na rysunku Wykres słonecznikowy Wykresy kropkowe, dwu- i wielowymiarowe Wykres macierzy korelacji Wykres konturowy Wykres koniczyny Wielowymiarowy, jądrowy estymator gęstości Wykresy konturowe Wykres mapa ciepła Wykres profili obserwacji Parametry graficzne

11 x Spis treści 5.6. Pakiet rcharts Wprowadzenie Biblioteka NVD Biblioteka Leaflet Inne szablony Opis zbiorów danych Skorowidz

12 Rozdział 1 Wprowadzenie One of the greatest advantages of R: getting your work done better and in less time. Frank Harrell, Biostatistics, Vanderbilt University W tym rozdziale przybliżymy czytelnikowi podstawowe informacje związane z programem R. Rozdział jest przygotowany z myślą o osobach, które jeszcze nie zetknęły się z R, nie wiedzą, jak wygląda praca w tym języku, i być może nie są pewne, czy warto się go uczyć. Zaczniemy więc od uzasadnienia, dlaczego warto. Następnie przedstawimy historię tego języka i kierunki rozwoju. Druga część tego rozdziału ilustruje, jak wygląda przykładowa praca z R. Na prostym przykładzie zaprezentujemy, jak pobierać dane, przetwarzać je i tworzyć wykresy. W trzecim rozdziale pokażemy, w jaki sposób przygotować sobie środowisko pracy, co i jak należy zainstalować. W ostatnim podrozdziale wymienimy miejsca, w których można znaleźć więcej informacji o tym języku Data science, czyli dlaczego warto poznać R Data science to dynamicznie rosnąca dyscyplina, łącząca zagadnienia z obszaru analizy danych i programowania. Szybko wzrasta zapotrzebowanie na osoby potrafiące analizować nowo pojawiające się strumienie danych. Aby nadążyć za tym cyfrowym tsunami, potrzebne są dobre narzędzia do analizy danych. Takim narzędziem jest właśnie język R. Języków programowania jest wiele, ale jeżeli chodzi o analizę danych, to z R możesz szybciej i lepiej zrobić więcej niż w jakimkolwiek innym języku. Pod adresem (Video Introduction to R przygotowane przez Microsoft) znajduje się 90-sekundowe video-wprowadzenie do potencjału programu R. Dlaczego? R powstał po to, by ułatwić profesjonalistom pracę z danymi. Język R jest dialektem języka S, który opracował John Chambers w Bell Labs 1

13 2 Rozdział 1. Wprowadzenie Liczba pakietów w repozytorium CRAN Sumaryczna liczba pakietów Rok pierwszej publikacji w repozytorium CRAN Rysunek 1.1. Liczba pakietów R w repozytorium CRAN, stan na listopad 2020 w okolicach roku Język S stworzono z myślą o interaktywnej analizie danych. Wiele rozwiązań zostało wprowadzonych do tego języka po to, by ułatwić pracę z danymi. Pierwsza wersja R została napisana w roku 1991 przez Roberta Gentlemana i Rossa Ihakę (znanych jako R&R), pracujących na Wydziale Statystyki Uniwersytetu w Auckland. Pakiet R początkowo służył jako pomoc dydaktyczna do uczenia statystyki na tym uniwersytecie. Jednocześnie, ponieważ był to projekt otwarty, bardzo szybko zyskiwał na popularności. Od roku 1997 rozwojem R kierował zespół ponad dwudziestu osób, tworzących tzw. core team. W zespole tym znaleźli się eksperci z różnych dziedzin (statystyki, matematyki, metod numerycznych oraz szeroko pojętej informatyki) z całego świata. Liczba osób rozwijających R szybko rosła, a obecnie rozwojem projektu kieruje fundacja The R Foundation for Statistical Computing, licząca setki aktywnych uczestników. Ponadto w rozwój R mają wkład tysiące osób z całego świata udostępniające własne pakiety z funkcjami do najróżniejszych zastosowań. Liczba bibliotek dostępnych dla użytkowników R szybko rośnie. W roku 2020 przekroczyła liczbę pakietów w głównym repozytorium CRAN (zobacz rysunek 1.1). Do tej liczby trzeba doliczyć tysiące pakietów prywatnych lub umieszczonych w innych repozytoriach. Program R jest projektem GNU opartym na licencji GNU GPL, co oznacza, iż jest zupełnie darmowy zarówno do zastosowań edukacyjnych, jak i biznesowych. Więcej o licencji GNU GPL można przeczytać pod adresem [53]. Platforma R wyposażona jest w świetną dokumentację, dostępną w postaci

14 1.1 Data science, czyli dlaczego warto poznać R 3 Rysunek 1.2. Ranking IEEE dotyczący popularności języków, rok 2020 dokumentów PDF lub stron HTML. Dokumentacja w większości jest angielskojęzyczna, ale niektóre pliki pomocy mają swoje lokalizacje, w tym polską. Od początku język R był tworzony i rozwijany z myślą o osobach zajmujących się analizą danych. Z tego też powodu przez informatyków często nie był traktowany jak pełnowartościowy język, ale raczej jak język domenowy (DSL, ang. domain-specific language). Z czasem jednak możliwości R rosły, pojawiło się coraz więcej rozwiązań wykraczających poza analizę danych i dziś R jest jednym z popularniejszych języków programowania. Świadczyć może o tym ranking przygotowany na podstawie głosów członków komitetu IEEE (Institute of Electrical and Electronics Engineers). W tym rankingu R został w roku 2020 wymieniony na 5. miejscu wśród najpopularniejszych języków, wyprzedzając takie tuzy jak PHP czy JavaScript. Jest wiele powodów takiej popularności języka R. Poniżej przedstawiamy te subiektywnie uznane za najważniejsze. Z uwagi na swoją elastyczność dzisiaj jest to podstawowy język wykorzystywany w nauczaniu statystyki i analizy danych, obecny na praktycznie każdej dobrej uczelni. Program R pozwala na tworzenie i upowszechnianie pakietów zawierających nowe funkcjonalności. Obecnie dostępnych jest przeszło pakietów do różnorodnych zastosowań, np. rgl do grafiki trójwymiarowej, lima do analizy danych mikromacierzowych, seqinr do analizy danych genomicznych, psy z funkcjami statystycznymi powszechnie wykorzystywanymi w psychometrii, geor z funkcjami geostatystycznymi, Sweave do generowania raportów w języku L A TEX i wiele, wiele innych. Każdy może napisać swój własny pakiet i udostępnić go innym osobom.

15 4 Rozdział 1. Wprowadzenie Program R pozwala na wykonywanie funkcji z bibliotek napisanych w innych językach (C, C++, Fortran), a także istnieje możliwość wykonywania funkcji dostępnych w programie R z poziomu innych języków (Java, C, C++, pakiety Statistica, SAS i wiele innych). Dzięki temu możemy np. znaczną część programu napisać w Javie, a R wykorzystywać jako dużą zewnętrzną bibliotekę funkcji statystycznych. Program R jest w zupełności darmowy do wszelkich zastosowań zarówno prywatnych, naukowych, jak i komercyjnych. Również większość pakietów napisanych dla R jest darmowa i dostępna w ramach licencji GNU GPL lub GNU GPL 2.0. W programie R można wykonać wykresy o wysokiej jakości, co jest bardzo istotne przy prezentacji wyników. Wykresy te nawet przy domyślnych ustawieniach wyglądają znacznie lepiej od podobnych wykresów przygotowanych w innych pakietach. Więcej o historii i kierunkach rozwoju języka R można przeczytać na stronie (Kurs R Programming na coursera.org) Jak wygląda praca z programem R Praca z programem R jest najczęściej interaktywna. Sam program R jest często kojarzony z konsolą, w której mruga kursor, służącą do wprowadzania poleceń i odczytywania wyników. Aby oddać ten styl pracy, w tej książce prezentujemy przykłady instrukcji R wraz z wynikami, które te instrukcje generują. Zarówno instrukcje R, jak i ich wyniki są otoczone szarą ramką, aby łatwiej było je odnaleźć. Wyniki znajdują się w liniach oznaczonych podwójnym komentarzem ##. Przykładowo, funkcja substr() wycina z napisu podciąg o wskazanych współrzędnych. Po uruchomieniu programu R wystarczy wpisać do konsoli poniższą instrukcję, aby w tej samej konsoli pojawił się wynik. Tutaj wynikiem jest napis składający się z jednej litery R. substr(„co jest super?”, start = 13, stop = 13) ## [1] „R” Pisząc o funkcjach, pakietach, elementach języka, stosujemy pismo o stałej szerokości znaków. Angielskie nazwy oznaczymy z kolei kursywą. Przy pierwszym wymienieniu nazwy funkcji z niestandardowego pakietu zaznaczamy również, w jakim pakiecie ta funkcja jest dostępna. Zapis ggplot2::qplot() oznacza, że funkcja qplot() znajduje się w pakiecie ggplot2. Czasem funkcja o tej samej nazwie dostępna jest w różnych pakietach. Zatem wskazanie w jawny sposób, w którym pakiecie dana funkcja się znajduje, pozwala na jednoznaczne określenie, o którą funkcję chodzi. W sytuacji, gdy do użycia danej funkcji potrzeba zainstalować lub włączyć

16 1.2 Jak wygląda praca z programem R 5 niestandardowy pakiet, warto wiedzieć, w jakim pakiecie danej funkcji szukać. Na końcu tej książki znajduje się indeks funkcji, zarówno alfabetyczny, jak i w podziale na pakiety Przykład: Pozycja Polski w rankingu FIFA Przyjrzyjmy się, jak wygląda przykładowa poważna praca z R na poniższym przykładzie. Wykorzystamy funkcje z pakietu rvest, aby odczytać bezpośrednio z Wikipedii dane o pozycji Polski w rankingu FIFA. Wykorzystamy funkcje z pakietów tidyr i dplyr, aby przekształcić wczytane dane do odpowiedniej postaci. Wykorzystamy funkcje z pakietu ggplot2, aby przedstawić graficznie wczytane dane. Cały kod R, który wykonuje te trzy etapy, jest dosyć krótki i łatwo go prześledzić krok po kroku. Niektóre elementy mogą wydawać się znajome, inne mogą być zaskakujące. W kolejnych rozdziałach wyjaśnimy każdy z zaprezentowanych tutaj elementów. Wszystkie instrukcje R przedstawiane w tej książce można pobrać ze strony Przedstawiane instrukcje R pozwalają na odtworzenie przedstawianych wyników. Jedynym odstępstwem od tej reguły są niektóre wykresy, które zostały zmodyfikowane aby zwiększyć ich czytelność w druku. Wczytanie danych Poniższy fragment kodu wczytuje do R tabelę z danymi ze strony Reprezentacja Polski w piłce nożnej z Wikipedii. Wykorzystujemy tutaj funkcje z pakietu rvest, który jest bardzo przydatny w pobieraniu danych ze stron internetowych. Na interesującej nas stronie jest wiele tabel. Pobieramy wszystkie, a następnie wybieramy tę o 14 kolumnach. Po wczytaniu danych wyświetlamy pierwszych 6 wierszy. library(„rvest”) wikipl 17 6 Rozdział 1. Wprowadzenie head(tab) ## Rok I II III IV V VI VII VIII IX X XI XII Sr. ## ## ## ## ## ## Transformacja danych Po wczytaniu danych zazwyczaj kolejnym krokiem jest ich wyczyszczenie i przetransformowanie. Do tego celu mogą przydać się funkcje z pakietów tidyr i dplyr, omówimy je szczegółowo już niedługo, poniżej krótka ilustracja. Zamieniamy dane z formatu szerokiego, w którym miesiące są w różnych kolumnach, na format wąski, w którym miesiące są w jednej kolumnie. Następnie zamieniamy rzymskie nazwy miesięcy na arabskie. Teraz dane są gotowe do prezentacji graficznej. library(„tidyr”) library(„dplyr”) colnames(tab)[2:13] 18 1.3 Jak przygotować środowisko pracy 7 80 Pozycja Polski w rankingu FIFA 60 Pozycja Data publikacji rankingu Rysunek 1.3. Przykładowy wykres wykonany przy użyciu pakietu ggplot2. Przedstawiona jest pozycja Polski w rankingu FIFA w różnych latach. W ostatnich dwóch latach odnotowano znaczącą poprawę 1.3. Jak przygotować środowisko pracy Należy wykonać trzy kroki, aby wygodnie pracować z programem R. Zainstalować podstawowe środowisko R, na które składa się interpreter i podstawowy zbiór pakietów. Już ten zestaw ma potężne możliwości. W większości przypadków wystarczające do analizy danych, rysowania wykresów i wykonywania innych typowych zadań. Zainstalować edytor RStudio, narzędzie, które bardzo ułatwia pracę z programem R. Nie jest to jedyny edytor dla R, ale z obecnych dzisiaj na rynku wydaje się najlepszym rozwiązaniem. Podobnie jak R również ten edytor w wersji podstawowej jest dostępny bezpłatnie. Doinstalować dodatkowe pakiety z przydatnymi funkcjami. Obecnie dostępnych jest ponad siedem tysięcy pakietów! Nie ma jednak potrzeby instalowania ich wszystkich od razu. Z reguły w miarę używania okazuje się, że przydałaby się nam jakaś dodatkowa funkcja z nowego pakietu. Dopiero wtedy warto taki pakiet doinstalować. Poniżej znajduje się krótka informacja ułatwiająca przejście przez poszczególne etapy instalacji.

19 8 Rozdział 1. Wprowadzenie Instalacja podstawowego środowiska R Dla większości systemów operacyjnych, w tym wszystkich dystrybucji Linuxa, Unixa, dla wersji Windows począwszy od Windows 95 i dla Mac OS, pakiet R jest dostępny w postaci źródłowej oraz binarnej. W chwili pisania tego tekstu aktualna wersja R to Co roku w kwietniu ukazuje się kolejna duża wersja 3.x, czyli niedługo będziemy cieszyć się wersją W trakcie roku w miarę potrzeb wydawane są podwersje. Program R szybko się rozwija i warto przynajmniej raz do roku aktualizować go do najnowszej dostępnej wersji. Aby zainstalować R, należy otworzyć stronę wybrać system operacyjny i pobrać plik binarny do instalacji. Instalacja sprowadza się do kliknięcia kilka razy przycisku Next. Można mieć zainstalowanych jednocześnie kilka różnych wersji R. Przechowywanie starszych wersji programu R może być przydatne, jeżeli chcemy mieć prostą możliwość odtworzenia w przyszłości dokładnie tych samych wyników. W przypadku instalacji na nietypowych platformach można posiłkować się szczegółową instrukcją instalacji dostępną na stronie [49]. Wygodną właściwością środowiska R jest to, że można je uruchamiać bez instalowania. Można więc skopiować środowisko R na płytę CD, na pendrive lub dysk przenośny i uruchamiać na dowolnym komputerze bez potrzeby instalacji. Rysunek 1.4. Strona Można z niej pobrać program R dla najpopularniejszych systemów operacyjnych

20 1.3 Jak przygotować środowisko pracy 9 Trudno jest podać minimalne wymagania sprzętowe niezbędne do działania R. Wersję podstawową można bez problemu zainstalować na wieloletnich maszynach z 256 MB RAM, procesorami klasy Pentium lub wyższej i kilkudziesięcioma MB miejsca na dysku twardym. O ile jednak wersja podstawowa jest lekka, to instalacja dodatkowych pakietów może wymagać kilku GB pamięci RAM lub miejsca na dysku. Szczególnie pakiety z dużymi danymi genomicznymi potrafią dużo ważyć. Osoby wykorzystujące program R do bardzo wymagających obliczeniowo analiz powinny raczej używać OS X-owej, linuksowej lub uniksowej wersji R. W tych systemach operacyjnych zarządzanie pamięcią jest wydajniejsze, przez co R działa (odrobinę) szybciej. W przypadku Uniksów dostępne są też dodatkowe narzędzia pozwalające na wykorzystanie wielowątkowości i innych mechanizmów systemowych (np. funkcji fork()). Instalacja edytora RStudio Można pracować z podstawowym programem R bez dodatkowego edytora, jednak praca z edytorem jest znacznie wygodniejsza, szczególnie jeżeli R to nasze podstawowe narzędzie pracy. Obecnie najlepszym edytorem do programu R jest RStudio narzędzie opracowane przez firmę o tej samej nazwie. Ten edytor dostępny jest zarówno na platformę Windows, Linux, jak i OS X, wspiera on wiele zaawansowanych pakietów i funkcjonalności R. RStudio jest narzędziem ułatwiającym pracę z R. Jest to edytor, manager wersji, narzędzie wspierające debugowanie, tworzenie pakietów, aplikacji czy raportów. Można żyć bez tej nakładki, ale co to za życie. Najnowszą wersję RStudio Desktop można pobrać ze strony Przykładowy wygląd tego programu jest przedstawiony na rysunku 1.5. Korzystanie z omawianego edytora jest bardzo intuicyjne. Do ciekawszych funkcji tego narzędzia należą następujące: możliwość automatycznego wysyłania całego skryptu lub fragmentu kodu do konsoli R. Po zaznaczeniu określonego fragmentu kodu i naciśnięciu Ctrl-Enter zadany fragment będzie wykonany w konsoli R, zarządzanie wieloma plikami/projektami, wsparcie dla pakietów knitr, Sweave i shiny, łatwa nawigacja po wstawkach kodu, praca z R Notebooks, interaktywna praca z raportami i możliwość uruchamiania i aktualizacji poszczególnych wstawek kodu, wyświetlanie obiektów (nazwa, klasa, wymiary) obecnych w przestrzeni nazw,

21 10 Rozdział 1. Wprowadzenie Rysunek 1.5. Przykładowy wygląd paneli edytora RStudio. Na czterech panelach widoczne są: okno pozwalające na edycję kodu, okno pozwalające na podgląd zmiennych załadowanych do globalnej przestrzeni nazw R, konsola programu R, w której możemy wpisywać bezpośrednio polecenia, oraz okno, w którym domyślnie wyświetlane są pliki pomocy oraz wykresy edytor danych, funkcji i innych obiektów R, po kliknięciu na nazwę zbioru danych obecnego w przestrzeni nazw mamy możliwość edycji tego obiektu, jest to często wygodniejszy sposób niż użycie funkcji fix() czy edit(), uproszczony sposób wczytywania danych z plików poprzez interfejs graficzny, podświetlanie słów kluczowych i funkcji, kontekstowe uzupełnianie nazw funkcji, zmiennych, właściwości, argumentów funkcji (gdy rozpoczynamy pisanie nazwy funkcji, zmiennej lub argumentu, pojawia się lista wszystkich słów, które pasują w danym kontekście), zwijanie/rozwijanie kodu funkcji i pętli, wsparcie dla tworzenia i testowania nowych pakietów, domykanie otwartych nawiasów, cudzysłowów, wraz z inteligentnym zaznaczaniem zawartości, inteligentne wstawianie wcięć połączone z rozpoznawaniem składni (czyli nowe wcięcie dodawane jest w pętlach, funkcjach itp.), interaktywny debugger. Interesującym rozszerzeniem programu RStudio Desktop jest wersja serwerowa RStudio Server. Po zainstalowaniu na serwerze można z niej korzystać zdalnie przez przeglądarkę internetową. W wersji płatnej możne z niej korzystać jednocześnie kilka osób.

22 1.3 Jak przygotować środowisko pracy 11 Pracę z narzędziem RStudio bardzo ułatwi poznanie kilku podstawowych skrótów klawiszowych. Poniżej przedstawiam te moim zdaniem najciekawsze. Bardzo dobry opis programu RStudio wraz z listą wszystkich skrótów klawiszowych można pobrać ze strony (tzw. RStudio IDE cheatsheets). W poniższym opisie zapis Ctrl/Cmd oznacza Ctrl dla systemu Windows i Linux oraz Cmd dla systemu OS X. Ctrl/Cmd+Shift+C, komentowanie linii lub zbioru linii kodu, Ctrl/Cmd+Enter, wykonanie zaznaczonego kodu w konsoli, Ctrl/Cmd+Up, wyświetlanie historii komend, Ctrl+L, czyszczenie konsoli, Ctrl+1-9, przełączanie pomiędzy oknami aplikacji, Tab, uzupełnianie kodu, bardzo, bardzo użyteczne, Ctrl/Cmd+Shift+K, kompilacja obecnego dokumentu Instalacja dodatkowych pakietów Po zainstalowaniu podstawowego środowiska R mamy już dostęp do wielu użytecznych funkcjonalności. Prawdziwa potęga kryje się jednak w tysiącach dodatkowych pakietów, w których znajdują się kolejne tysiące funkcji. Aby skorzystać z dodatkowych pakietów, należy wykonać dwa kroki: 1. Zainstalować nowy pakiet na dysku. Ten krok wystarczy wykonać raz, skopiuje on niezbędne pliki do katalogu z pakietami. Ścieżkę do katalogu z pakietami można sprawdzić, używając polecenia.libpaths(). 2. Włączyć zainstalowany pakiet w działającej sesji R. Ten krok należy wykonać po każdym uruchomieniu środowiska R. Spowoduje on, że w aktualnej sesji będzie można korzystać z funkcji i zbiorów danych dostępnych w pakiecie. Instalować pakiety można na kilka sposobów. Najczęściej pakiety instaluje się z oficjalnego repozytorium CRAN (The Comprehensive R Archive Network). Jeżeli pakiet, który nas interesuje, jest w tym repozytorium, to można go zainstalować funkcją install.packages(). Przykładowo, poniższe polecenie zainstaluje pakiet Przewodnik wraz z pakietami zależnymi, bezpośrednio z repozytorium CRAN. Pakiet Przewodnik zawiera jako zależności wszystkie pakiety i zbiory danych, z których korzystamy w tej książce. Aby go zainstalować, wystarczy wpisać w konsoli programu R: install.packages(„przewodnik”) lub wybrać z menu RStudio opcję Tools/Install packages. Niektórych pakietów nie ma w repozytorium CRAN lub są dostępne, ale w starszej wersji. Przykładowo, jednym z wymogów stawianych pakietom w CRAN jest ograniczenie wielkości pakietu do 10 MB. Z uwagi na to ogra-

23 12 Rozdział 1. Wprowadzenie niczenie większe rozmiarowo pakiety są przechowywane na innych repozytoriach, najczęściej w repozytorium GitHub. Do instalacji pakietów z GitHuba można wykorzystać funkcję devtools::install_github(). Na przykład, aby zainstalować najnowszą wersję pakietu Przewodnik z repozytorium użytkownika pbiecek z repozytorium GitHub, można użyć instrukcji: devtools::install_github(„pbiecek/przewodnikpakiet”) Poza tymi dwoma repozytoriami istnieje też wiele innych specjalistycznych. Przykładowo wiele pakietów wykorzystywanych w analizach bioinformatycznych znajduje się w repozytorium Bioconductor. Więcej o tym repozytorium na stronie Po zainstalowaniu nowego pakietu pliki z danymi, funkcjami i plikami pomocy znajdą się na dysku twardym komputera. Aby jednak móc skorzystać z wybranych funkcji, należy przed pierwszym użyciem załadować (włączyć) odpowiedni pakiet. Po każdym uruchomieniu platformy R ładowane są pakiety podstawowe, takie jak: base, graphics, stats itp. Aby skorzystać z dodatkowych funkcji lub zbiorów danych, należy załadować (włączyć) pakiet, w którym się one znajdują (zakładamy, że pakiety te zostały już zainstalowane). Pakiety włącza się poleceniem library(). Poniższa instrukcja włącza pakiet devtools. Po włączeniu pakietu można używać funkcji z tego pakietu bez konieczności dodawania prefixu devtools. library(„devtools”) Jak już pisaliśmy, w repozytorium CRAN dostępnych jest obecnie ponad pakietów. W tak dużym zbiorze trudno czasem odnaleźć pakiet z interesującą nas funkcjonalnością. Dlatego przedstawiając nowe funkcje, będziemy korzystać z notacji nazwapakietu::nazwafunkcji(). Zapis ggplot2::qplot() oznacza, że funkcja qplot() znajduje się w pakiecie ggplot2. W skorowidzu, znajdującym się na końcu książki, funkcje są wymienione zarówno w kolejności alfabetycznej, jak i po pogrupowaniu w pakiety. Jeżeli znamy nazwę funkcji i chcemy dowiedzieć się, w jakim pakiecie się ona znajduje, a nie mamy tej książki pod ręką, to możemy wykorzystać funkcję help.search(). Przeszuka ona wszystkie zainstalowane pakiety w poszukiwaniu funkcji o wskazanej nazwie lub funkcji, w których opisie wystąpiło zadane słowo kluczowe. Więcej o tej funkcji i innych sposobach wyszukiwania informacji o funkcjach piszemy w podrozdziale 1.4. Po załadowaniu odpowiedniego pakietu możemy korzystać z dostępnych w nim funkcji, podając ich nazwę. Możemy też wprost wskazać, z którego pakietu funkcję chcemy uruchomić, co jest przydatne, gdy funkcje o identycznych nazwach znajdują się w kilku załadowanych pakietach. Przykładowo zarówno w pakiecie epitools, jak i vcd znajduje się funkcja oddsratio(), przy

24 1.4 Gdzie szukać dalszych informacji 13 czym każda z nich ma inne działanie. Aby wskazać, z którego pakietu chcemy wybrać funkcję, należy użyć operatora :: lub . Operator :: pozwala na odnoszenie się wyłącznie do publicznych funkcji z pakietu, podczas gdy operator . umożliwia odwoływanie się również do funkcji prywatnych. Oba poniższe wywołania dotyczą funkcji seq() z pakietu base. Drugi sposób jest przydatny, gdy występuje kolizja nazw funkcji z różnych pakietów. seq(10) base::seq(10) Jeżeli nie zastosujemy operatora . a funkcja o danej nazwie występuje w kilku różnych pakietach, to program R użyje funkcji z ostatnio załadowanego pakietu Gdzie szukać dalszych informacji W dalszej części tej książki omawiamy biblioteki do transformacji danych, modelowania statystycznego oraz wizualizacji. Z pewnością jednak pojawią się pytania lub wątki, które nie będą tutaj opisane. Gdzie szukać dodatkowych informacji? Najłatwiej i najszybciej jest zapytać kogoś, kto to wie i chce nam podpowiedzieć. Tak się składa, że wokół programu R działa duże środowisko entuzjastów, organizujących cykliczne spotkania z referatami. Obecnie trzy największe w Polsce środowiska pasjonatów R działają w trzech dużych miastach. Spotkania odbywają się mniej więcej raz w miesiącu. SER: Warszawskie Spotkania Entuzjastów R, erka: Entuzjastów R Krakowska Alternatywa, PAZUR: Poznań R User Group, Silne grupy użytkowników R działają również we Wrocławiu, Łodzi i innych miastach, wymieniając się informacjami w ramach spotkań data science. W sytuacji, gdy nie mamy takiej osoby pod ręką, program R oferuje bogaty system pomocy. Pierwszym jej źródłem są wbudowane funkcje R ułatwiające wyszukiwanie informacji. Oto lista najbardziej przydatnych: Funkcja help() wyświetla stronę powitalną systemu pomocy R. Na tej stronie opisane są szczegółowo wymienione poniżej funkcje. Funkcje help(„sort”) i?sort wyświetlają stronę z pomocą dotyczącą funkcji o nazwie sort. Zobacz też przykład przedstawiony poniżej. Format opisów funkcji jest ujednolicony, tak aby łatwo było z nich korzystać. W RStudio można też użyć przycisku F1 aby aktywować pomoc dla funkcji. Kolejne sekcje pomocy zawierają: zwięzły opis funkcji (sekcja Description), deklaracje funkcji (sekcja Usage), objaśnienie poszczególnych argumentów

25 14 Rozdział 1. Wprowadzenie (sekcja Arguments), szczegółowy opis funkcji (sekcja Details), literaturę (sekcja References), odnośniki do innych funkcji (sekcja See Also) oraz przykłady użycia (sekcja Examples). Jeżeli podamy argument package, to uzyskamy pomoc dotyczącą wskazanego pakietu. Przykładowo polecenie help(package=mass) wyświetla opis pakietu MASS. Funkcja args(„nazwafunkcji”) wyświetla listę argumentów nazwafunkcji. Funkcje apropos(„regression”) i find(„regression”) wypisują listę funkcji (oraz obiektów), które w swojej nazwie mają podciąg regression. Funkcja example(„plot”) uruchamia skrypt z przykładami użycia funkcji plot. Dzięki przykładom można szybko zobaczyć, jak korzystać z danej funkcji, a także jakich wyników należy się spodziewać. Funkcja help.search(„slowokluczowe”) przegląda opisy funkcji znajdujących się w zainstalowanych pakietach i wyświetla te funkcje, w których znaleziono wskazane slowokluczowe. W tym przypadku slowokluczowe może oznaczać również kilka słów lub zwrot. Lista wyników zawiera też informację, w którym pakiecie znajdują się znalezione funkcje. Poniżej przedstawiona jest przykładowa sesja w programie R. Szukamy informacji o funkcji plot() oraz o funkcjach do testowania hipotez. W pierwszej linii wyświetlamy pomoc dotyczącą funkcji plot, następnie przykłady jej użycia. Kolejna linia wyświetla funkcje ze słowem „test” w nazwie, a ostatnia wyświetla nazwy funkcji ze zwrotem „normality test” w opisie.?plot example(plot) apropos(„test”) help.search(„normality test”) Funkcje przedstawione powyżej wyszukują informacje na zadany temat, przeglądając pakiety, które są już zainstalowane na komputerze. Jeżeli to okaże się niewystarczające (a może się zdarzyć, że nie mamy zainstalowanego pakietu, w którym znajduje się potencjalnie interesująca nas funkcja), to możemy skorzystać z zasobów dostępnych w Internecie. W szczególności warto wiedzieć, gdzie znaleźć poniższe pomoce: Internetowy kurs w języku polskim Pogromcy Danych, dostępny pod adresem Kurs podzielony jest na kilkanaście krótkich bloków z zadaniami pozwalającymi na sprawdzenie poziomu opanowania omawianego materiału. Forum StackExchange, z licznymi pytaniami i setkami osób chętnych, by na te pytania odpowiedzieć. Forum często pojawia się w wynikach wyszukiwarki Google. Jest dostępne pod adresem Poradniki (podręczniki, ang. manuals) poświęcone różnym aspektom programowania w R lub analizy danych w programie R. Dostępne są bezpośrednio z menu Help w programie R oraz w Internecie pod adresem

26 1.4 Gdzie szukać dalszych informacji 15 R-bloggers, czyli agregator blogów poświęconych programowi R, często źródło wielu ciekawych informacji: Książki poświęcone pakietowi R oraz analizie danych z użyciem tego pakietu. Aktualizowana lista książek na ten temat znajduje się pod adresem Portale z pytaniami i odpowiedziami dotyczącymi statystyki, programowania. Np. (pytania dotyczące statystyki) lub (pytania dotyczące programowania). W Internecie można znaleźć też wiele materiałów w języku polskim. Jednym z pierwszych jest Wprowadzenie do środowiska R Łukasza Komsty [17], a co roku przybywa wiele kolejnych. Aktualna lista polskojęzycznych pozycji znajduje się na stronie Wikipedii Bardzo dobrą książką do nauki języka R jest książka Johna Chambersa [5], a do nauki funkcji statystycznych dostępnych w programie R polecamy pozycję Briana Everitta [8]. Obie one dotyczą języka S, jednak z punktu widzenia użytkownika jest on prawie identyczny z R. Uzupełnieniem licznych pozycji książkowych jest olbrzymia liczba stron internetowych oraz dokumentów elektronicznych szczegółowo przedstawiających rozmaite aspekty programu i języka R. Pod koniec roku 2007 ukazała się bardzo obszerna i godna polecenia książka Michaela Crawleya [6] przedstawiająca zarówno język R, jak i wiele procedur statystycznych zaimplementowanych w programie R. Pojawiają się też i będą się pojawiały liczne książki poświęcone specjalistycznym zastosowaniom programu R, jak np. świetna pozycja przygotowana przez Paula Murrella poświęcona grafice [21], książka autorstwa Juliana Farawaya poświęcona modelom liniowym [10] czy kolejna pozycja Briana Everitta przedstawiająca podstawy statystyki [9]. Wydawnictwo Springer ma w ofercie ponad 45 książek o programie R wydanych w serii Use R!, każda z tych pozycji traktuje o jednym wybranym zagadnieniu, takim jak analiza danych przestrzennych, wizualizacja danych, analiza danych socjologicznych, genetycznych itp.

27 Rozdział 2 Podstawy pracy z R W tym rozdziale przedstawiamy podstawowe informacje związane z pracą w programie R. Pierwsze cztery podrozdziały wprowadzają do tematu wczytywania danych z plików tekstowych, omawiają kluczowe struktury danych w programie R, przedstawiają wybrane statystyki opisowe, zarówno liczbowe, jak i graficzne. Temat wczytywania danych wraca ponownie w podrozdziale 2.6, w którym pokazujemy, jak wczytywać i zapisywać dane, wykorzystując najróżniejsze formaty. Następnie omawiane są pakiet dplyr i tidyr, dwa pakiety pozwalające na przeprowadzenie większości transformacji i agregacji danych, takich jak filtrowanie, grupowanie, wyznaczanie agregatów. Ostatnim podrozdziałem jest omówienie zagadnień związanych z tworzeniem automatycznych raportów. Pokazujemy, jak prosto jest wykorzystać pakiet knitr lub program RStudio, aby błyskawicznie wykonać czytelny i łatwy do odtworzenia raport Wczytywanie danych Dwa najpopularniejsze formaty przechowywania danych to pliki tekstowe i pliki w formacie Excel/OpenOffice. Korzystając z programu RStudio, oba te formaty można wczytać zaledwie kilkoma kliknięciami. Wystarczy wybrać opcję File/Import Dataset, aby otworzyć graficzny interfejs do importu danych zobacz rysunek 2.1. W przypadku niestandardowego formatowania pliku do dyspozycji mamy kilka kontrolek pozwalających na dookreślenie, co jest separatorem, czy w pierwszej linii są nazwy zmiennych itp. Jeżeli nie korzystamy z programu RStudio, to do wczytywania danych z plików tekstowych możemy użyć funkcji read.table(). Zilustrujmy użycie tej funkcji na poniższym przykładzie. 16

28 2.1 Wczytywanie danych 17 Rysunek 2.1. Przykładowe okno programu RStudio do importu danych za pomocą graficznego interfejsu W pliku znajdują się dane dotyczące 2400 ofert sprzedaży samochodów różnych marek. Dane te są zapisane w pliku o rozszerzeniu csv. Z każdą ofertą związanych jest 8 parametrów, w pliku tekstowym są one rozdzielone średnikami. Fragment tego pliku przedstawiony jest poniżej. „Marka”;”Model”;”Cena”;”KM”;”Pojemnosc”;”Przebieg”;”Paliwo”;” Produkcja” „Peugeot”;”206″;8799;60;1100;85000;”benzyna”;2003 „Peugeot”;”206″;15500;60;1124;114000;”benzyna”;2005 „Peugeot”;”206″;11900;90;1997;215000;”diesel”;2003 „Peugeot”;”206″;10999;70;1868;165000;”diesel”;2003 „Peugeot”;”206″;11900;70;1398;146000;”diesel”;2005 „Peugeot”;”206″;19900;70;1398;86400;”diesel”; Pierwszym argumentem funkcji read.table() jest ścieżka do pliku z danymi. Plik może znajdować się na dysku lub w Internecie. Następne dwa argumenty w poniższym wywołaniu określają, że wartości w kolejnych kolumnach są rozdzielone średnikami, a pierwszy wiersz zawiera nazwy zmiennych. Wynik funkcji read.table(), czyli tabela z danymi, jest przypisany do symbolu auta za pomocą operatora 29 18 Rozdział 2. Podstawy pracy z R auta 30 2.2 Struktury danych 19 Wiele użytecznych wektorów jest dostępnych w podstawowych pakietach. Przykładami są nazwy miesięcy czy kolejne litery. month.name ## [1] „January” „February” „March” „April” „May” ## [6] „June” „July” „August” „September” „October” ## [11] „November” „December” LETTERS ## [1] „A” „B” „C” „D” „E” „F” „G” „H” „I” „J” „K” „L” „M” „N” ## [15] „O” „P” „Q” „R” „S” „T” „U” „V” „W” „X” „Y” „Z” Indeksowanie wektorów Aby odwołać się do elementów wektora, należy użyć operatora [], wewnątrz którego podaje się wektor indeksów do odczytania. Elementy wektora numerowane są od liczby 1. Najłatwiej będzie nam przedstawić indeksowanie na przykładzie wybierania części liter z wektora LETTERS. LETTERS[ 5:10 ] ## [1] „E” „F” „G” „H” „I” „J” LETTERS[ c(1, 2, 9:14) ] ## [1] „A” „B” „I” „J” „K” „L” „M” „N” Funkcja length() wyznacza liczbę elementów w wektorze. Jest ona przydatna, np. gdy chcemy wybrać co drugi element wektora. Poniżej korzystamy z funkcji seq(), aby zbudować sekwencję indeksów złożoną z co drugiej litery wektora LETTERS. co_drugi 31 20 Rozdział 2. Podstawy pracy z R Celem indeksowania nie zawsze jest wybieranie podwektora. Równie często chodzi o zmianę kolejności elementów w wektorze. Przykładowo, poniżej odwracamy kolejność elementów, podając nowy zbiór indeksów. wartosc[ 6:1 ] ## krol hetman wieza goniec skoczek pion ## Inf Innym przydatnym sposobem wskazywania podciągu elementów wektora jest korzystanie z wartości logicznych. Na poniższym przykładzie wybieramy wszystkie elementy wektora, które mają wartość mniejszą od 6. wartosc[ wartosc 32 2.2 Struktury danych 21 ## gatunek waga dlugosc predkosc habitat zywotnosc druzyna ## 1 Tygrys Azja 25 Kot ## 2 Lew Afryka 29 Kot ## 3 Jaguar Ameryka 15 Kot ## 4 Puma Ameryka 13 Kot ## 5 Leopard Azja 21 Kot ## 6 Gepard Afryka 12 Kot Indeksowanie ramek danych Ramka danych ma strukturę dwuwymiarowej tabeli. Aby określać jej elementy, należy podać współrzędne i wierszy, i kolumn. W tym celu można wykorzystać operatory [] lub $ (ten omawiamy pod koniec podrozdziału). Używając operatora [], należy wskazać osobno indeksy wierszy i indeksy kolumn, rozdzielając je znakiem „,” (przecinka). Jeżeli indeksy wierszy lub kolumn nie zostaną wskazane, to wybrane będą wszystkie wiersze/kolumny. W poniższym przykładzie wybieramy trzy wiersze z ramki koty_ptaki. koty_ptaki[ c(1, 3, 5), ] ## gatunek waga dlugosc predkosc habitat zywotnosc druzyna ## 1 Tygrys Azja 25 Kot ## 3 Jaguar Ameryka 15 Kot ## 5 Leopard Azja 21 Kot Możemy jednocześnie indeksować i wiersze, i kolumny. koty_ptaki[ c(1, 3, 5), 2:5] ## waga dlugosc predkosc habitat ## Azja ## Ameryka ## Azja Każdy wymiar można indeksować zgodnie z tymi samymi zasadami co indeksowanie wektorów. A więc indeksami mogą być warunki logiczne, można odwoływać się do nazw lub używać ujemnych indeksów. W poniższym przykładzie wybieramy tylko zwierzęta rozwijające większą prędkość niż 100 km/h. Dla każdego wiersza spełniającego ten warunek wyświetlamy gatunek, prędkość i długość zwierzaka. koty_ptaki[ koty_ptaki[,”predkosc”] > 100, c(„gatunek”, „predkosc”, „dlugosc”)] ## gatunek predkosc dlugosc ## 6 Gepard ## 8 Jerzyk ## 10 Orzel przedni ## 11 Sokol wedrowny ## 13 Albatros

33 22 Rozdział 2. Podstawy pracy z R Poszczególne kolumny ramki danych to wektory. Jeżeli odwołamy się do jednej kolumny, to jako wynik otrzymamy już nie ramkę danych, ale wektor. Jest to bardzo użyteczna właściwość, skracająca w wielu miejscach zapis. Są jednak sytuacje, w których jest to przyczyną błędów, więc należy zachować ostrożność gdy wybiera się tylko jedną kolumnę. Wybrać kolumnę możemy przez wskazanie jej numeru lub nazwy. Poniższe polecenie ma ten sam efekt co koty_ptaki[,4]. koty_ptaki[, „predkosc”] ## [1] Gdy chcemy wybrać tylko jedną kolumnę z ramki, to możemy również skorzystać z operatora $. Skraca on zapis o całe 4 znaki, a jednocześnie łatwiej zauważyć, że wynik jest z pewnością wektorem. Po operatorze $ możemy podać całą nazwę zmiennej lub jej część. Jeżeli podamy część, to wynikiem będzie kolumna o nazwie rozpoczynającej się od wskazanego napisu. koty_ptaki$predkosc ## [1] Operator $ jest też przydatny, gdy chcemy do ramki danych dodać nową kolumnę. Można za jego pomocą dokleić na koniec ramki danych nową kolumnę o wskazanej nazwie. Zmieniamy jednostkę, pamiętając, że 1 mila/h = 1.6 km/h. koty_ptaki$predkosc_mile 34 2.3 Statystyki opisowe 23 trojka 35 24 Rozdział 2. Podstawy pracy z R Zmienne jakościowe (nazywane również wyliczeniowymi, czynnikami lub kategorycznymi) to zmienne przyjmujące określoną liczbę wartości (najczęściej nieliczbowych). Zmienne te można podzielić na: binarne (nazywane również dwumianowymi, dychotomicznymi), np. płeć (poziomy: kobieta/mężczyzna), nominalne (nazywane również zmiennymi jakościowymi nieuporządkowanymi), np. marka samochodu, pomiędzy wartościami tych zmiennych nie ma żadnego porządku, porządkowe (nazywane też jakościowymi uporządkowanymi), np. wykształcenie (poziomy: podstawowe/średnie/wyższe). Zmienne ilościowe, które można dodatkowo podzielić na: licznikowe (liczba wystąpień pewnego zjawiska, opisywana liczbą naturalną), np. liczba lat nauki, przedziałowe (nazywane też interwałowymi), mierzone w skali, w której odejmowanie wartości ma sens, ale iloraz już nie, np. temperatura w stopniach Celsjusza lub rok naszej ery, ilorazowe, czyli zmienne przedziałowe, mierzone w skali, w której dodatkowo zachowane są proporcje, wartości można dzielić, skala ma zero absolutne, np. temperatura w stopniach Kelvina, wzrost w centymetrach itp. W programie R zmienne ilościowe reprezentowane są przez typ liczbowy numeric. Nie ma osobnych typów do opisywania liczb w skali ilorazowej i interwałowej. Zmienne jakościowe w R są reprezentowane przez typ czynnikowy factor. Zmienne typu factor mogą dodatkowo być oznaczone jako uporządkowane, mają wtedy dodatkowo klasę ordered. Zmienne binarne mogą być też reprezentowane przez typ logiczny logical. W tabeli 2.1 przedstawiamy funkcje wyznaczające najpopularniejsze statystyki opisowe. Przykładowe wywołania statystyk opisowych przećwiczymy na danych danesoc z pakietu Przewodnik. library(„przewodnik”) head(danesoc, 4) ## wiek wyksztalcenie st.cywilny plec praca ## 1 70 zawodowe w zwiazku mezczyzna uczen lub pracuje ## 2 66 zawodowe w zwiazku kobieta uczen lub pracuje ## 3 71 zawodowe singiel kobieta uczen lub pracuje ## 4 57 srednie w zwiazku mezczyzna uczen lub pracuje ## cisnienie.skurczowe cisnienie.rozkurczowe ## ## ## ##

36 2.3 Statystyki opisowe Zmienne ilościowe Przyjrzyjmy się wartościom w kolumnie wiek. Możemy się do niej odwoływać przez instrukcję danesoc$wiek. Wiek to zmienna ilościowa w skali ilorazowej (ilorazy mają w jej przypadku sens, można np. powiedzieć, że ktoś jest dwa razy starszy niż inna osoba). Pierwsze pytanie: jaka jest najmniejsza i największa wartość przyjmowana przez zmienną wiek? Zawsze warto sprawdzić wartości skrajne, mogą uwidocznić jakieś błędy w danych. range(danesoc$wiek) ## [1] Jaka jest średnia dla zmiennej wiek? mean(danesoc$wiek) ## [1] A średnia obcięta wyznaczona na podstawie 60% środkowych obserwacji? mean(danesoc$wiek, trim=0.2) ## [1] Mediana okazuje się bliska średniej czyżby brak skośności? median(danesoc$wiek) ## [1] 45 Do przedstawiania najważniejszych charakterystyk zmiennych można wykorzystać funkcję summary(). W przypadku zmiennych ilościowych wynikiem jest wektor z wartościami minimum, maksimum, średniej, mediany i kwartyli pierwszego i trzeciego (nazywanych też dolnym i górnym). Wszystkie te wartości poza średnią są również wyznaczane przez funkcje fivenum() (tzw. pięć liczb Tukeya, dzielących obserwowane wartości na cztery równe części). Jeżeli w zmiennej występują brakujące obserwacje, to w podsumowaniu wypisywana jest ich liczba. summary(danesoc$wiek) ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## Odchylenie standardowe: sd(danesoc$wiek) ## [1] Kurtoza / miara spłaszczenia: kurtosis(danesoc$wiek) ## [1]

37 26 Rozdział 2. Podstawy pracy z R Skośność: skewness(danesoc$wiek) ## [1] Wybrane kwantyle zmiennej wiek: quantile(danesoc$wiek, c(0.1, 0.25, 0.5, 0.75, 0.9)) ## 10% 25% 50% 75% 90% ## Dla kilku zmiennych ilościowych popularnie wyznaczaną statystyką jest korelacja. Można ją obliczyć funkcją cor(). Macierz korelacji dla trzech wybranych kolumn: cor(danesoc[,c(1,6,7)]) ## wiek cisnienie.skurcz cisnienie.rozkurcz ## wiek ## cisnienie.skurcz ## cisnienie.rozkurcz Zmienne jakościowe Przyjrzyjmy się teraz wartościom w kolumnie wyksztalcenie. Możemy się do niej odwoływać przez instrukcję danesoc$wyksztalcenie. Wykształcenie to zmienna jakościowa uporządkowana. Przyjmuje cztery różne wartości i mają one naturalnie określony porządek. Najczęściej wykorzystywaną statystyką w przypadku zmiennych jakościowych jest tablica liczebności. Funkcja table(): table(danesoc$wyksztalcenie) ## podstawowe srednie wyzsze zawodowe ## Funkcja ta wyznacza tablicę liczebności dla jednej, dwóch lub większej liczby zmiennych wyliczeniowych. Tablice kontyngencji można również obliczyć funkcjami xtabs() i ftable(). table(danesoc$wyksztalcenie, danesoc$praca) ## nie pracuje uczen lub pracuje ## podstawowe 8 14 ## srednie 6 28 ## wyzsze ## zawodowe W przypadku zmiennych jakościowych podobny efekt co funkcja table() ma funkcja summary(). Różnica polega na tym, że w razie występowania danych NA funkcja table() je ignoruje, a funkcja summary() wypisuje ich liczbę.

38 2.3 Statystyki opisowe 27 Tablica 2.1. Statystyki opisowe dla wektora lub macierzy Z pakietu base max()/min() Wartość maksymalna/minimalna w próbie. mean() Średnia arytmetyczna, x = i x i /n. Opcjonalnym argumentem jest trim, jeżeli jest różny od zera, to wyznaczana jest średnia ucięta. Średnią uciętą oblicza się tak jak arytmetyczną, po usunięciu 200% trim skrajnych obserwacji. length() Liczba elementów w próbie. range() Przedział zmienności próby, wyznaczony jako [min i x i, max i x i ]. Z pakietu stats weighted.mean() Średnia ważona, wyznaczona jako n 1 i w i jest drugim argumentem. w i x i. Wektor wag median() Mediana (wartość środkowa). quantile() Kwantyl wybranego rzędu. Drugim argumentem funkcji quantile() jest wektor kwantyli do wyznaczenia. W tej funkcji zaimplementowano 9 różnych algorytmów do wyliczania kwantyli, zobacz opis argumentu type. IQR() Rozstęp międzykwartylowy, czyli różnica pomiędzy górnym a dolnym kwartylem, IQR = q 0.75 q var() Wariancja w próbie. Wyznaczana jest nieobciążona ocena wariancji S 2 = n 1 1 i (x x) 2. Dla dwóch wektorów obliczona będzie kowariancja dla tych wektorów, a dla macierzy wynikiem będzie macierz kowariancji kolumn. sd() Odchylenie standardowe wyznaczone jako S 2, gdzie S 2 to ocena wariancji. cor(), cov() Macierz korelacji i kowariancji. Argumentami może być para wektorów lub macierz. mad() Medianowe odchylenie bezwzględne, wyznaczone jako median( x i median(x i ) ). Z innych pakietów kurtosis() Kurtoza, miara koncentracji, n i (x i x) 4 3. Rozkład normalny ( i (x i x) 2 ) 2 ma kurtozę 0. Funkcja z pakietu e1071. skewness() n Skośność, miara asymetryczności, i (x i x) 3. Rozkład symetryczny ( i (x i x) 2 ) 3/2 ma skośność 0. Funkcja z pakietu e1071. geometric.mean() Średnia geometryczna, wyznaczona jako (Π i x i ) 1/n. Funkcja z pakietu psych. harmonic.mean() Średnia harmoniczna, wyznaczona jako n/ i x 1 i. Funkcja z pakietu psych. moda() Moda lub dominanta, czyli wartość występująca najczęściej w próbie. Funkcja z pakietu dprep. W Linuxie można też użyć funkcji mod() z pakietu RVAideMemoire.

39 28 Rozdział 2. Podstawy pracy z R summary(danesoc$wyksztalcenie) ## podstawowe srednie wyzsze zawodowe ## Argumentem funkcji summary() może być również obiekt typu data.frame. W tym przypadku podsumowania wyznaczane są dla każdej kolumny wskazanej ramki danych. summary(danesoc[,1:4]) ## wiek wyksztalcenie st.cywilny plec ## Min. :22.00 podstawowe:93 singiel :120 kobieta : 55 ## 1st Qu.:30.00 srednie :55 w zwiazku: 84 mezczyzna:149 ## Median :45.00 wyzsze :34 ## Mean :43.16 zawodowe :22 ## 3rd Qu.:53.00 ## Max. : Statystyki graficzne Poniżej prezentujemy najpopularniejsze wykresy wykorzystywane do graficznej reprezentacji zmiennych. Mniej popularne, ale równie ciekawe i użyteczne wykresy przedstawione są w rozdziale 5.5. W poniższych przykładach wykorzystano zbiór danych danesoc z pakietu Przewodnik Wykres słupkowy, funkcja: barplot() Wykresy słupkowe są jedną z najpopularniejszych form graficznego przedstawiania danych. Patrząc na słupki, zazwyczaj porównujemy ich względne długości, dlatego ta forma prezentacji nadaje się do zmiennych w skali ilorazowej. Funkcja barplot() (patrz rysunki 2.2 i 2.3) służy do przedstawiania danych w postaci słupków, zarówno poziomych, jak i pionowych. Argumentem może być wektor wartości do przedstawienia lub dwuwymiarowa macierz. Argument horiz określa, czy słupki mają być rysowane poziomo, czy pionowo. Argument las wskazuje natomiast, w jakim kierunku mają być rysowane opisy przy osiach. Funkcją legend() można dorysować do wykresu legendę, o tej funkcji można przeczytać więcej w rozdziale Argument col pozwala na wybranie kolorów dla słupków i legendy, a zastosowanie argumentu add=true powoduje, że nie jest tworzony nowy wykres, ale słupki dorysowane są do poprzedniego. Poniższy kod generuje wykresy przedstawione na rysunkach 2.2 i 2.3. Funkcją table() wyznaczana jest macierz częstości, która jest następnie rysowana funkcją barplot().

40 2.4 Statystyki graficzne 29 library(„przewodnik”) tab 41 30 Rozdział 2. Podstawy pracy z R tość tego argumentu jedną liczbę, to będzie ona potraktowana jako sugestia oczekiwanej liczby automatycznie wyznaczonych przedziałów (tylko sugestia, ponieważ funkcja hist() może liczbę przedziałów nieznacznie zwiększyć lub zmniejszyć). Jeżeli podany będzie wektor liczb, to będzie on uznany za wektor punktów rozdzielających przedziały (przedziały nie muszą mieć równych szerokości). Jeżeli argumentem będzie napis, to zostanie on zinterpretowany jako nazwa algorytmu do wyznaczenia liczby przedziałów (możliwe wartości to: „Sturges”, „Scott”, „FD” i „Freedman-Diaconis”). Poniżej przedstawiamy dwa przykładowe wywołania funkcji hist(), wyniki ich działania można zobaczyć na rysunkach 2.4 i 2.5. Zaczniemy od histogramu dla zmiennej wiek. Ponieważ w danych mamy wiele wierszy, argumentem breaks zasugerujemy podział poziomej osi na 15 przedziałów/kubełków. Pozostałe argumenty poniższego wywołania to określenia opisów osi i tytułu wykresu. hist(danesoc$wiek, breaks = 15, main=”histogram wieku”, las=1, ylab=”liczba”, xlab=”wiek”) Zmieniając kolory obramowania histogramu i słupków, możemy uzyskać bardziej estetyczny histogram. Dodatkowo zmieniamy oś pionową, by przedstawiać częstości zamiast liczebności. hist(danesoc$wiek, breaks = 15, col=”grey”, border=”white”, las=1, probability = TRUE, ylab=”czestosc”, xlab=”wiek”) Histogram wieku Liczba Czestosc Wiek Rysunek 2.4. Histogram dla zmiennej wiek Wiek Rysunek 2.5. Zmiana kolorów wypełniania i obramowania słupków.

42 2.4 Statystyki graficzne Wykres pudełkowy: boxplot() Główną zaletą histogramu jest to, że łatwo na nim zauważyć regiony dużego zagęszczenia/rozrzedzenia wartości. Wadę stanowi to, że trudno z jego pomocą porównać grupy obserwacji, ponieważ dla każdej grupy przedstawianych jest wiele informacji. Do porównywania rozkładów wartości w grupach bardzo popularną metodą jest wykres pudełkowy, nazywany też boxplotem. Funkcja boxplot() (patrz rysunki 2.6 i 2.7) służy do przedstawiania rozkładu zmiennej liczbowej za pomocą pudełek. Na jednym wykresie można zaprezentować wyniki dla kilku zmiennych (by porównać rozkłady tych zmiennych) lub dla pojedynczej zmiennej w rozbiciu na grupy obserwacji (by porównać rozkład zmiennej w podgrupach). Pierwszy argument funkcji boxplot() określa wektor lub listę wektorów, lub ramkę danych, lub formułę ze zmiennymi, które mają znaleźć się na wykresie pudełkowym. Można też podać kilka wektorów zmiennych jako kolejne argumenty. Jeżeli argumentem będzie wektor liczb, to narysowane zostanie jedno pudełko, jeżeli będzie to kilka wektorów liczb, to narysowanych zostanie kilka pudełek, a jeżeli argumentem będzie formuła opisująca zależność pomiędzy zmienną ilościową a zmienną jakościową, to powstanie osobne pudełko dla każdego poziomu zmiennej jakościowej. Pozostałe argumenty funkcji boxplot() to: range określający szerokość przedziału, poza którym obserwacje są traktowane jako odstające, argument varwidth określający czy grubość pudełka ma być proporcjonalna do pierwiastka z liczby obserwacji w wektorze, argument outline określający, czy mają być rysowane wartości odstające. Poniżej zamieszczamy dwa przykłady wywołania funkcji boxplot(). Wynik tych wywołań prezentujemy na rysunkach 2.6 i 2.7. Jako kolejne argumenty funkcji boxplot() można podawać następne wektory liczb, a argumentem names można określić etykiety na osi wykresu. Argument horizontal umożliwia obrót wykresu pudełkowego. boxplot(danesoc$cisnienie.rozk, danesoc$cisnienie.skur, horizontal = TRUE, names = c(„skurczowe”,”rozkurczowe”)) Pierwszym argumentem może być formuła, w wygodny sposób określa ona, jakie grupy mają być porównywane. Poniżej porównujemy wiek w grupach wykształcenia. Dodatkowo, argumentem varwidth powodujemy, że szerokość pudełka odpowiadać będzie liczebności porównywanej grupy. boxplot(wiek

wyksztalcenie, data = danesoc, varwidth=true, col=”lightgrey”, ylab=”wiek”, las=1)

43 32 Rozdział 2. Podstawy pracy z R Skurczowe Rozkurczowe Wiek podstawowe srednie wyzsze zawodowe Rysunek 2.6. Wykresy pudełkowe dla dwóch wektorów Rysunek 2.7. Wykres pudełkowy przedstawiający zmienną wiek Wykres pudełkowy przypomina ramkę z wąsami, stąd też inna jego nazwa: wykres ramka wąsy. Pomiędzy wąsami znajdują się prawie wszystkie obserwacje (poza odstającymi). Za odstające obserwacje uznawane są te, które odstają od kwartyli bardziej niż o 1,5 IQR (1,5 to domyślna wartość argumentu range). Wewnątrz pudełka wyznaczonego przez kwartyle znajduje się 50% obserwacji. Znaczenie poszczególnych elementów jest przedstawione na poniższym schemacie. obs. odstają ca obs. odstają ca obs. odstają ca min. bez obs. odst. 1. kwartyl 95% p. ufn. dla med. mediana 95% p. ufn. dla med. 3. kwartyl max. bez obs. odst. obs. odstają ca ciś nienie rozkurczowe Jądrowy estymator gęstości, funkcja: density() Zarówno histogram, jak i wykres pudełkowy przedstawiają rozkład wartości wektora liczb. Dwie inne statystyki, które są często wykorzystywane w tym celu, to jądrowy estymator gęstości (gładka wersja histogramu wyznaczana funkcją density()) i dystrybuanta empiryczna (obliczana funkcją ecdf()).

44 2.4 Statystyki graficzne 33 Idea jądrowego estymatora gęstości polega na wyznaczeniu oceny gęstości w danym punkcie na podstawie koncentracji obserwacji w okolicy tego punktu. Obserwacje położone bliżej interesującego punktu wpływają na oceny gęstości z większą wagą niż obserwacje bardziej oddalone. Szablon tych wag określony jest przez parametr nazywany jądrem. Za to, które obserwacje są uznawane za bliskie, odpowiada parametr nazywany szerokością okna, szerokością pasma lub też stopniem wygładzenia. Funkcja density() (patrz rysunki 2.8 i 2.9) służy do wyznaczania jądrowego estymatora gęstości dla wektora liczb. Pierwszym argumentem jest wektor wartości, dla których chcemy wyliczyć ocenę gęstości. Argumenty from i to określają początek i koniec przedziału, w którym wyznaczona ma być gęstość, argument n wskazuje liczbę punktów, w których wartość gęstości ma być wyznaczona (gęstość wyliczana jest dla regularnej siatki punktów). Parametry kernel i bw służą do określenia rodzaju jądra i szerokości okna. Wynikiem funkcji density() jest obiekt klasy density, którego składowe przechowują wartości ocen gęstości we wskazanych punktach. Obiekty tej klasy można przedstawiać graficznie przeciążoną funkcją plot(). Domyślnie ocena gęstości wyznaczana jest z użyciem jądra gaussowskiego. Przeglądając plik pomocy dla funkcji density(), zainteresowany czytelnik odkryje, jak wykorzystywać inne jądra i czym one się różnią. Wybór jest spory, dostępne są jądra prostokątne, trójkątne i wiele innych, patrz parametr kernel. Szerokość pasma (szerokość okna) można ustalić ręcznie lub wskazać regułę jej wyboru, która automatycznie określi najodpowiedniejszą szerokość. W pakiecie stats zaimplementowanych jest pięć różnych metod automatycznego wyboru szerokości pasma. Domyślnie stosowana jest reguła kciuka (używna gdy bw=”nrd0″) zaproponowana przez Silvermana. Zgodnie z tą regułą szerokość okna h wyznaczana jest ze wzoru: h bw.nrd0 = 0,9 min(ˆσ, IQR/1,34)n 1/5, (2.1) gdzie ˆσ to ocena odchylenia standardowego, IQR to rozstęp kwartylowy z próby, a n to liczba obserwacji. Magiczna stała 1,34 bierze się stąd, że dla rozkładu normalnego IQR/1,34 σ. Inną popularną regułą kciuka jest reguła Scota, stosowana gdy bw=”nrd”. Szerokość okna wyznacza się ze wzoru: h bw.nrd = 1,06ˆσn 1/5. (2.2) Można wykorzystać też inne reguły wyboru szerokości pasma, np. oparte na metodzie walidacji krzyżowej (ang. cross validation): nieobciążoną dla argumentu bw=”ucv” i obciążoną dla argumentu bw=”bcv”, lub estymator typu plug-in Sheathera-Jonesa (dla argumentu bw=”sj”). W większości przypad-

45 34 Rozdział 2. Podstawy pracy z R ków najlepsze wyniki oceny szerokości pasma otrzymuje się, wykorzystując metodę Sheathera-Jonesa. Poniżej przedstawiamy przykłady dwóch ocen gęstości wyznaczonych dla różnych parametrów szerokości pasma (pierwszy wybrany automatyczny, drugi ręcznie ). Efekt wykonania tych instrukcji znajduje się na rysunkach 2.8 i 2.9. plot(density(danesoc$wiek), main=”rozklad wieku”) Jeżeli uznamy, że okno wygładzania jest zbyt szerokie, można je ręcznie zmodyfikować. Na przykładzie poniżej redukujemy je do wartości 1,5. plot(density(danesoc$wiek, bw=1.5), main=”rozklad wieku”,type=”h”) Rozklad wieku Rozklad wieku Density Density N = 204 Bandwidth = Rysunek 2.8. Jądrowy estymator gęstości z automatycznie wybraną szerokością okna N = 204 Bandwidth = 1.5 Rysunek 2.9. Jądrowy estymator z szerokością okna ustawioną na 1,5. Kolejną przydatną statystyką do opisu rozkładu wektora obserwacji jest dystrybuanta empiryczna. Można ją wyznaczyć używając komendy ecdf(). Dystrybuanta empiryczna to funkcja opisująca, jaki procent obserwacji w wektorze przyjmuje wartości mniejsze niż x. Wynik funkcji ecdf() jest obiektem klasy ecdf. Dla tej klasy zaimplementowano przeciążoną wersję funkcji plot() prezentującą graficznie dystrybuantę empiryczną (zobacz przykład na rysunku 2.11). plot(ecdf(danesoc$wiek), main=”dystrybuanta wieku”) Dystrybuantę można wykorzystać, aby porównać kilka grup obserwacji. Wystarczy na jednym wykresie przedstawić dystrybuanty dla różnych grup (argument add). Na poniższym przykładzie rysujemy dwie dystrybuanty na jednym wykresie, jedną dla mężczyzn, a drugą dla kobiet.

46 2.4 Statystyki graficzne 35 library(„dplyr”) mezczyzni 47 36 Rozdział 2. Podstawy pracy z R Do wykresu rozrzutu można dorysować prostą regresji liniowej (prosta jest rysowana w zależności od wartości argumentu reg.line, wartość FALSE wyłącza rysowanie prostej regresji, domyślnie reg.line=true) oraz krzywą regresji wygładzonej (krzywa jest rysowana w zależności od wartości argumentu smooth, wartość FALSE wyłącza rysowanie tej krzywej, domyślna wartość to smooth=true). W prezentowanym przykładzie (rysunek 2.13) wykres rozrzutu dla dwóch zmiennych (ciśnienia skurczowego i rozkurczowego) został przedstawiony w dwóch podpopulacjach określonych przez zmienną plec. Na wykresie rozrzutu możemy zobaczyć, czy istnieje wyraźna zależność pomiędzy badanymi zmiennymi i czy ta zależność jest taka sama, czy różna w podpopulacjach. Efekty wykonania poniżej przedstawionych instrukcji znajdują się na rysunkach 2.12 i Pierwszy argument funkcji sp() to formuła określająca, która zmienna ma być przedstawiona na osi OX, a która na osi OY wykresu. Argument pch wskazuje kształt rysowanych punktów. library(„car”) sp(cisnienie.rozkurczowe

cisnienie.skurczowe, data=danesoc, smooth=false, reg.line=false, pch=19) W formule, po znaku, możemy również określić zmienną warunkującą. W przykładzie poniżej każda płeć jest rysowana na wykresie za pomocą innych kształtów punktów i kolorów. Dodatkowo do każdego zbioru punktów dodawany jest trend liniowy. sp(cisnienie.rozkurczowe

cisnienie.skurczowe plec, data=danesoc, smooth=false, lwd=3, pch=c(19,17)) Wykresy rozrzutu są bardzo przydatne do wykrywania i opisywania zależności liniowych lub monotonicznych pomiędzy parą zmiennych. W przypadku dużej liczby zmiennych można wykorzystać funkcje pairs(), scatterplot.matrix() lub YaleToolkit::gpairs(). Rysują one macierz zależności pomiędzy każdą parą analizowanych zmiennych Wykres mozaikowy, funkcja: mosaicplot() Jak pokazać zależność pomiędzy dwoma lub większą liczbą zmiennych jakościowych? Jedną z możliwości jest użycie wykresu słupkowego barplot(). Inną jest zastosowanie jego mniej znanego, ale bardzo potężnego brata wykresu mozaikowego. Funkcja mosaicplot() (patrz rysunki 2.14 i 2.15) przedstawia liczebność wartości w zbiorze danych za pomocą pola prostokątów. Prostokąty te są tak ułożone, by można było łatwo zauważyć: (1) czy dwie zmienne od siebie zależą oraz (2) jakie jakie są częstości występowania pojedynczych wartości i par wartości.

48 2.4 Statystyki graficzne cisnienie.skurczowe cisnienie.rozkurczowe Rysunek Wykres kropkowy dla dwóch zmiennych cisnienie.skurczowe cisnienie.rozkurczowe plec kobieta mezczyzna Rysunek Dodajemy linie trendu i zaznaczamy dane dla różnych płci. Przedstawmy ten wykres na dwóch przykładach. Wyniki poniższych instrukcji są zaprezentowane na rysunkach 2.14 i Pierwszy wykres przestawia wyłącznie częstość występowania różnych grup wykształcenia. Prostokąty mają stałą wysokość, ale różnią się szerokością. Im prostokąt jest szerszy (pole większe) tym dana grupa jest częstsza. mosaicplot(

wyksztalcenie, data=danesoc, main=””, border=”white”) Drugi wykres przedstawia zależność pomiędzy zmiennymi wyksztalcenie a praca. Tak jak w poprzednim przykładzie szerokość prostokątów odpowiada częstościom grup wykształcenia. Wysokości odpowiadają względnym częstościom osób pracujących w różnych grupach wykształcenia. Co ważne, jeżeli dwie zmienne są niezależne, to mozaika przypomina regularną kratę. Jeżeli występuje jakaś zależność, to łatwo zauważyć, jakiego jest ona rodzaju. Na poniższym wykresie widać, że najwięcej osób pracujących występuje wśród osób z wykształceniem wyższym. mosaicplot(

wyksztalcenie+praca, data=danesoc, border=”white”, col=c(„grey40”, „grey70”)) Na jednej mozaice można zaprezentować wyniki dla więcej niż dwóch zmiennych typu wyliczeniowego. Należy jednak uważać, bowiem umieszczenie bardzo wielu zmiennych lub zmiennych o bardzo wielu poziomach znacząco zmniejsza czytelność i przydatność tego wykresu.

49 38 Rozdział 2. Podstawy pracy z R podstawowe srednie wyzsze zawodowe podstawowe srednie wyzsze zawodowe praca uczen lub pracuje nie pracuje wyksztalcenie Rysunek Wykres mozaikowy przedstawiający częstość zmiennej wyksztalcenie. wyksztalcenie Rysunek Wykres mozaikowy przedstawiający zależność pomiędzy zatrudnieniem a wykształceniem Jak przetwarzać dane z pakietem dplyr Program R jest wyposażony w tysiące (tak, dosłownie tysiące!) funkcji do przetwarzania danych. Na szczęście, aby wygodnie pracować z większością danych, wystarczy poznać na początek kilka najważniejszych. W przypadku przetwarzania danych obowiązuje zasada 80/20 (tzw. zasada Pareta, od nazwiska Wilfreda Pareto). Oznacza ona, że aby efektywnie przetwarzać większość (nie wszystkie, ale np. 80% możliwych) danych, wystarczy znać jedynie niewielki ułamek z wszystkich dostępnych funkcji. Hadley Wickham przygotował dwa pakiety, dplyr i tidyr, które udostępniają dokładnie tę niewielką część funkcji. Każda z nich wykonuje tylko jedną elementarną operację. Ale można je elastycznie łączyć, przez co w sumie pozwalają one na przeprowadzenie większości typowych operacji na danych. Wickham nazywa funkcje w tych pakietach czasownikami, a proces analizy danych przyrównuje do konstrukcji zdania. Podstawowymi czasownikami analizy danych są: filter() wybierz wskazane wiersze ze zbioru danych, select() wybierz tylko wskazane kolumny ze zbioru danych, arrange() posortuj wiersze względem wskazanych kolumn, mutate() dodaj nową kolumnę z danymi lub zmień istniejącą, group_by() / ungroup() – pogrupuj dane względem wskazanych czynników / usuń informację o pogrupowaniu, summarise() wyznacz określone agregaty w każdej grupie,

50 2.5 Jak przetwarzać dane z pakietem dplyr 39 gather() / spread() – przekształć dane z postaci szerokiej na wąską / z wąskiej na szeroką. Te podstawowe czasowniki są opisane w kolejnych podrozdziałach. Więcej funkcji pozwalających na eksplorację danych przedstawionych jest w ściągawce opracowanej przez RStudio, dostępnej na ich stronie [26] lub na Jak filtrować wiersze Jedną z najczęstszych operacji na danych jest filtrowanie wierszy, które spełniają określony warunek lub warunki. Funkcja filter() z pakietu dplyr wykonuje filtrowanie. Jej pierwszym argumentem jest zbiór danych, na których ma pracować, a kolejne argumenty to warunki logiczne. Wynikiem tej funkcji są wiersze spełniające wszystkie wskazane warunki logiczne. Określając warunki, można wykorzystywać nazwy kolumn ze zbioru danych bez podawania dodatkowych odnośników. Pokażmy to na przykładzie. Instrukcja, która ze zbioru danych auta wybierze tylko oferty z polem Model == „Corsa”, jest następująca: library(„dplyr”) tylkocorsa 51 40 Rozdział 2. Podstawy pracy z R Jak wybierać kolumny Dane zawierają niekiedy dużą liczbę kolumn, ale często pracujemy tylko na kilku z nich. Usunięcie pozostałych spowoduje, że dane będą mniejsze i operacje na nich będą szybsze. Inną zaletą wybierania jedynie potrzebnych kolumn jest łatwiejsze wyświetlanie danych. Zamiast pokazywać wszystkie, nawet nieistotne kolumny, często lepiej zaprezentować jedynie te istotne. Funkcja select() z pakietu dplyr pozwala na wybór jednej lub wielu zmiennych ze źródła danych. Pierwszym argumentem jest źródło danych, a kolejnymi są nazwy kolumn, które mają być wybrane. Przykładowo poniższa instrukcja wybiera jedynie kolumny z marką, modelem i ceną auta. trzykolumny 52 2.5 Jak przetwarzać dane z pakietem dplyr 41 Funkcja mutate() z pakietu dplyr pozwala na wygodne tworzenie dodatkowych kolumn w zbiorze danych na podstawie transformacji istniejących już kolumn. Przedstawmy działanie tej funkcji na przykładzie danych auta, dostępnych w pakiecie Przewodnik. Jest to zbiór danych o ogłoszeniach sprzedaży samochodów z portalu otomoto.pl z roku Przykład rozpoczniemy od wyznaczenia wieku oferowanych aut. Ponieważ przedstawione ogłoszenia pochodzą z roku 2020, a rok produkcji oferowanego samochodu znajduje się w kolumnie Produkcja, to wiek będzie równy Produkcja. W kolejnym kroku liczymy średni przebieg na rok użytkowania. Do tej operacji potrzebujemy jednocześnie danych z dwóch kolumn. autazwiekiem 53 42 Rozdział 2. Podstawy pracy z R ## Marka Model Cena KM Pojemnosc Przebieg Paliwo Produkcja ## 1 Peugeot diesel 2004 ## 2 Peugeot diesel 2004 ## 3 Peugeot diesel 2004 ## 4 Peugeot benzyna 2004 ## 5 Peugeot benzyna 2005 ## 6 Peugeot benzyna 2004 Aby odwrócić kolejność sortowania, należy wskazaną zmienną otoczyć wywołaniem funkcji desc(). posortowaneauta 54 2.5 Jak przetwarzać dane z pakietem dplyr 43 head( select( arrange( filter(auta, Marka == „Kia”), Cena), Model, Cena, Przebieg, Produkcja), 4) ## Model Cena Przebieg Produkcja ## 1 Cee d ## 2 Cee d ## 3 Cee d ## 4 Cee d Taką cebulkę czyta się od środka na zewnątrz. Najpierw wykonywane jest filtrowanie, później sortowanie, następnie wybieranie czterech kolumn i wybieranie pierwszych czterech wierszy. Jednak taki zapis nie jest czytelny, szczególnie w przypadku tych bardziej zewnętrznych funkcji. W powyższym przykładzie funkcja head() przyjmuje dwa argumenty, ale pierwszy zajmuje 6 linii kodu, a drugi jest wymieniony dopiero w siódmej linii. Przy dłuższych cebulkach łatwo pomylić, które argumenty są argumentami których funkcji. Jak działa operator potoku Rozwiązaniem problemu cebulki jest stosowanie specjalnego operatora do przetwarzania potokowego %>%. Operator ten pochodzi z pakietu magrittr, ale jest też dostępny po włączeniu pakietu dplyr. Najłatwiej zapamiętać, co robi ten operator, na prostym przykładzie dwuargumentowej funkcji. Zapis: a %>% funkcja(b) jest równoważny instrukcji: funkcja(a, b) Można go też stosować do funkcji o większej liczbie argumentów. Operator %>% przekazuje lewą stronę jako pierwszy argument funkcji wskazanej z prawej strony. Jeżeli chcemy przekazać wartość do drugiego lub dalszego argumentu, to można ten argument wskazać znakiem „.” (kropki), tak jak na poniższym przykładzie: a %>% funkcja(b, data=.)

55 44 Rozdział 2. Podstawy pracy z R Potoki w akcji Przedstawiona powyżej cebulka może być zapisana równoważnie w następujący, znacznie bardziej czytelny sposób. auta %>% filter(marka == „Kia”) %>% arrange(cena) %>% select(model, Cena, Przebieg, Produkcja) -> posortowane head(posortowane) ## Model Cena Przebieg Produkcja ## 1 Cee d ## 2 Cee d ## 3 Cee d ## 4 Cee d ## 5 Cee d ## 6 Cee d W powyższym przykładzie użyliśmy też operatora przypisania ->. Dzięki temu składowe potoku czytamy konsekwentnie od lewej do prawej. Operator -> działa jak % pozwala na skrótowy i czytelny zapis nawet dużej sekwencji wywołań funkcji. W przypadku funkcji, które przyjmują zbiór danych jako drugi lub kolejny argument, trzeba posłużyć się dodatkowo symbolem „.” (kropki). Symbol ten wskazuje, gdzie należy wstawić lewą stronę operatora %>%. Zobaczmy przykład z użyciem funkcji lm(), która buduje model liniowy. Ta funkcja oczekuje, że dane bedą przekazane jako drugi argument. Musimy więc użyć symbolu „.”. auta %>% lm(cena

przebieg, data =.) %>% summary() ## Call: ## lm(formula = Cena

Przebieg, data =.) ## ## Coefficients: ## Estimate Std. Error t value Pr(> t ) ## (Intercept) 4.388e e 56 2.5 Jak przetwarzać dane z pakietem dplyr 45 Zauważmy, że potoki nie tylko łatwiej się czyta, ale też łatwiej opatrywać je komentarzami. Linię komentarza można umieścić przed każdą linią potoku, opisując, co się akurat dzieje w tym konkretnym miejscu Jak wyznaczać agregaty/statystyki w grupach Częstą operacją, którą wykonuje się na danych, szczególnie tych dużych, jest wyznaczanie statystyk/podsumowań/agregatów dla podgrup danych. Aby takie agregaty wyznaczać przy użyciu pakietu dplyr możemy wykorzystać funkcje summarise() i group_by(). Pierwsza określa, jakie statystyki chcemy policzyć, a druga wskazuje, w jakich grupach. Przedstawiamy te funkcje poniżej jedna po drugiej. Agregaty Funkcją summarise() można wyznaczyć agregaty w danych. Przykładowo poniższa instrukcja dla zbioru danych auta liczy średnią cenę, medianę przebiegu aut i średni wiek aut. auta %>% summarise(sredniacena = mean(cena), medianaprzebiegu = median(przebieg), sredniwiek = mean( Produkcja), liczba = n()) ## sredniacena medianaprzebiegu sredniwiek liczba ## Nie zawsze agregat związany jest z przekształceniem wartości w jakiejś kolumnie. Na przykład dosyć przydatną statystykę stanowi liczba wierszy, która nie zależy od wartości w danych. Taki agregat jest w powyższym przykładzie wyznaczany funkcją n(). Grupowanie Funkcja group_by() pozwala określić, w jakich grupach ma być przeprowadzane dalsze przetwarzanie. Sama funkcja nie powoduje żadnych modyfikacji w danych, a jedynie dodaje znacznik wskazujący, co jest teraz zmienną grupującą. Kolejne funkcje w potoku będą dzięki temu znacznikowi wiedziały, że przetwarzanie należy prowadzić w grupach. Funkcja group_by wpływa na działanie innych funkcji z pakietu dplyr w intuicyjny sposób. W przypadku funkcji summarise(), liczącej statystyki, powoduje wyznaczenie statystyk dla każdej możliwej kombinacji zmiennych grupujących. W przypadku funkcji arrange(), sortującej wiersze, powoduje, że wiersze są sortowane najpierw po zmiennej grupującej.

57 46 Rozdział 2. Podstawy pracy z R W przypadku funkcji sample_n(), filtrującej wiersze, powoduje, że próbkowanie zostaje wykonane w każdej grupie niezależnie. W przypadku funkcji mutate() powoduje, że każdy agregat jest wyznaczany w ramach grupy, dzięki czemu można łatwo normować zmienne w grupach. Poniższy przykład liczy trzy statystyki (średnią cenę, medianę przebiegu, średni wiek aut i liczbę ofert) w grupach opisanych przez rodzaj paliwa. auta %>% group_by(marka) %>% summarise(sredniacena = mean(cena), medianaprzebiegu = median(przebieg), sredniwiek = mean( Produkcja), liczba = n()) ## Marka sredniacena medianaprzebiegu sredniwiek liczba ## 1 Audi ## 2 Fiat ## 3 Kia ## 4 Opel Agregaty są zwykłą ramką danych, można wykonywać na nich kolejne operacje, np. sortowanie. auta %>% group_by(marka) %>% summarise(sredniacena = mean(cena), medianaprzebiegu = median(przebieg), sredniwiek = mean( Produkcja), liczba = n()) %>% arrange(sredniacena) ## Marka sredniacena medianaprzebiegu sredniwiek liczba ## ## 1 Fiat ## 2 Peugeot ## 3 Opel ## 4 Kia Poniższy przykład modyfikuje zmienną Przebieg, dzieląc ją przez średni przebieg danej marki. auta %>% select(marka, Cena, Przebieg, Model) %>% group_by(marka) %>% mutate(przebieg = Przebieg/mean(Przebieg, na.rm=true)) ## Marka Cena Przebieg Model ## 1 Peugeot ## 2 Peugeot ## 3 Peugeot ## 4 Peugeot

58 2.5 Jak przetwarzać dane z pakietem dplyr Postać szeroka/postać wąska Wiele funkcji zakłada, że dane mają strukturę tabeli, w której wiersze to kolejne obserwacje, a kolumny to cechy kolejnych obserwacji. Takiego formatu danych oczekują między innymi pakiety dplyr, ggplot2 i wiele innych. Jednak czasem dane są dostępne w innym formacie. Czasem ta sama zmienna jest opisana przez wiele kolumn lub wiele zmiennych jest opisanych w jednej kolumnie. Funkcje z pakietu tidyr pozwalają na transformacje różnych formatów danych. Przedstawimy te formaty danych i funkcje do ich przekształcania na przykładzie danych z Eurostatu. Pobierzemy te dane z pomocą pakietu eurostat. Poniżej wczytujemy dane z tabeli tsdtr210, w której Eurostat gromadzi dane o popularności różnych form transportu w różnych krajach. library(„eurostat”) tsdtr210 59 48 Rozdział 2. Podstawy pracy z R library(„tidyr”) szeroka % filter(geo == „PL”) ## unit vehicle geo ## 1 PC BUS_TOT PL ## 2 PC CAR PL ## 3 PC TRN PL Dane w tabeli tsdtr210 opisują wartości w przekrojach przez cztery wymiary (jednostka, typ transportu, kraj, rok). Każdy z tych wymiarów może być użyty do stworzenia nowych kolumn w postaci szerokiej. Przykładowo poniżej kolejne kolumny są tworzone na bazie kolumny geo z danych w postaci wąskiej. szeroka2 % filter(time == „2020”) ## unit vehicle time AT BE BG CH CY CZ DE DK EE ## 1 PC BUS_TOT ## 2 PC CAR ## 3 PC TRN NA Zbierz w kolumny Operacją odwrotną do rozciągnięcia jednej kolumny na wiele kolumn jest zbieranie wielu kolumn w jedną. Można to zrobić funkcją gather(). Ta funkcja jako pierwszy argument przyjmuje zbiór danych. Kolejne dwa argumenty określają nazwy kolumn z kluczami i wartościami, a pozostałe argumenty wskazują kolumny starego zbioru danych, które mają być zebrane razem w nowym zbiorze danych. Można stosować notację ze znakiem -” (minus), czyli wszystko poza. Na poniższym przykładzie przekształcamy ramkę szeroka na postać wąską w taki sposób, że wszystkie kolumny poza geo i vehicle są przekształcane w kolumnę wartosc. Dlatego w wyniku występują kolumny geo i vehicle (pominięte przy zbieraniu) oraz rok i wartosc (wynik zbierania). szeroka %>% gather(rok, wartosc, -geo, -vehicle) %>% tail() ## vehicle geo rok wartosc ## 2622 TRN SI ## 2623 TRN SK ## 2624 TRN TR ## 2625 TRN UK

60 2.5 Jak przetwarzać dane z pakietem dplyr 49 Aby wyświetlić przykładowe 4 wiersze, użyto tutaj funkcji tail() (wyświetla ostatnie sześć wierszy), ponieważ w pierwszych sześciu wierszach są wartości NA Sklejanie/rozcinanie kolumn Pracując z danymi, często potrzebujemy zamienić kilka kolumn w jedną kolumnę lub jedną w kilka. Sklejanie kolumn Zdarza się, że wartości z kilku kolumn chcemy skleić ze sobą w jedną kolumnę. Można to zrobić funkcją unite(). Poniższy przykład skleja wartości z kolumnach geo i time w jedną kolumnę geo_time klasy napis. unite(tsdtr210, geo_time, geo, time, sep=”:”) %>% head(4) ## unit vehicle geo_time values ## PC_BUS_TOT_AT_1990 PC BUS_TOT AT: ## PC_BUS_TOT_BE_1990 PC BUS_TOT BE: ## PC_BUS_TOT_BG_1990 PC BUS_TOT BG:1990 NA ## PC_BUS_TOT_CH_1990 PC BUS_TOT CH: Operacja sklejenia jest często przydatna, jeżeli chcemy oprzeć grupowanie na kilku zmiennych. Wtedy te zmienne możemy posklejać i taki zlepek traktować jako nową zmienną grupującą. Rozcinanie kolumn Operacją odwrotną do sklejania jest rozcinanie kolumn. Można je wykonać funkcją separate(). Działanie tej funkcji przedstawimy na przykładzie sztucznego zbioru danych z dwoma kolumnami datą i identfikatorem. W poniższym przykładzie funkcja separate() na podstawie kolumny daty tworzy trzy nowe kolumny. Wypełnia je wartościami po rozbiciu daty na części rozdzielone znakiem -. df 61 50 Rozdział 2. Podstawy pracy z R separate(df, col=daty, into=c(„rok”, „miesiac”, „dzien”), sep=”-„) ## rok miesiac dzien id ## ## ## ## Długość wektora into określa, ile kolumn ma powstać po rozcięciu. Jeżeli w kolumnie, która jest rozcinana, będzie zbyt mało lub zbyt dużo wartości (np. tylko dwa elementy rozdzielane separatorem), to domyślnie funkcja separate() będzie sygnalizowała ostrzeżenia. Dodatkowymi argumentami extra i fill można określić, jak w takiej sytuacji mają być uzupełniane brakujące wartości Jak wczytać i zapisać dane w różnych formatach W tym rozdziale pokazujemy, jak wczytywać dane tabelaryczne z różnych źródeł. Przedstawiamy najróżniejsze formaty, mając na uwadze dużą różnorodność potrzeb osób korzystających z programu R. W większości przypadków lekturę tego rozdziału można ograniczyć do trzech podrozdziałów, pokazujących, jak wczytywać dane z pakietów, plików tekstowych i plików Excela. W ogólności dane mogą mieć najróżniejszą strukturę. Mogą przyjmować strukturę grafu, drzewa, mogą opisywać zdjęcia czy pliki multimedialne. Wszystkie te struktury można do programu R wczytać i je analizować. Najczęściej jednak dane, z którymi pracujemy, mają strukturę tabeli z wyróżnionymi kolumnami i wierszami. Na tego rodzaju strukturze skupimy się w tym rozdziale Wczytywanie danych z pakietów Najłatwiej wczytać dane, które są umieszczone w pakiecie. W takiej sytuacji wystarczy włączyć pakiet funkcją library() oraz użyć funkcji data(), aby wczytać dane o określonej nazwie. W jednym pakiecie można umieścić wiele zbiorów danych, przez co często pakiety wykorzystywane są jako nośniki użytecznych danych. Takim pakietem nośnikiem danych jest pakiet PogromcyDanych. Zawiera on różne zbiory danych, z których korzystamy w tej książce, między innymi zbiór danych koty_ptaki. Po zainstalowaniu pakietu PogromcyDanych, aby skorzystać z tego zbioru danych, wystarczą dwa polecenia: library(„pogromcydanych”) data(„koty_ptaki”)

62 2.6 Jak wczytać i zapisać dane w różnych formatach 51 W okienku Environment programu RStudio powinien pojawić się nowy symbol wskazujący na dodany zbiór danych. Używając funkcji head(), wyświetlmy pierwsze wiersze z ww. zbioru danych. head(koty_ptaki) ## gatunek waga dlugosc predkosc habitat zywotnosc druzyna ## 1 Tygrys Azja 25 Kot ## 2 Lew Afryka 29 Kot ## 3 Jaguar Ameryka 15 Kot ## 4 Puma Ameryka 13 Kot ## 5 Leopard Azja 21 Kot ## 6 Gepard Afryka 12 Kot Zbiór danych koty_ptaki składa się z 7 kolumn, opisujących różne parametry przykładowych zwierząt. Aby wyświetlić listę wszystkich zbiorów danych, które znajdują się w określonym pakiecie, również można wykorzystać funkcję data(): data(package=”pogromcydanych”) Wczytywanie danych z plików tekstowych Bardzo popularnym formatem przechowywania danych są pliki tekstowe. Ich zaletą jest to, że zawartość pliku można podejrzeć w dowolnym edytorze tekstu, np. w RStudio. Najczęściej mają one rozszerzenia txt, csv (od ang. comma separated values), tsv (od ang. tab separated values) itp. W takich plikach kolejne wartości kolumn są rozdzielane za pomocą jakiegoś znaku separującego, np. tabulacji, przecinka, średnika czy innej wyróżnionej wartości. Przyjrzyjmy się takim przykładowym danym umieszczonym w pliku Poniżej znajduje się treść tego pliku: gatunek;waga;dlugosc;predkosc;habitat;zywotnosc;druzyna Tygrys;300;2,5;60;Azja;25;Kot Lew;200;2;80;Afryka;29;Kot Jaguar;100;1,7;90;Ameryka;15;Kot Puma;80;1,7;70;Ameryka;13;Kot Leopard;70;1,4;85;Azja;21;Kot Gepard;60;1,4;115;Afryka;12;Kot Irbis;50;1,3;65;Azja;18;Kot Jerzyk;0,05;0,2;170;Euroazja;20;Ptak Strus;150;2,5;70;Afryka;45;Ptak Orzel przedni;5;0,9;160;polnoc;20;ptak Sokol wedrowny;0,7;0,5;110;polnoc;15;ptak Sokol norweski;2;0,7;100;polnoc;20;ptak Albatros;4;0,8;120;Poludnie;50;Ptak

63 52 Rozdział 2. Podstawy pracy z R Widzimy, że plik zawiera tabelę wartości rozdzielanych średnikami. Pierwszy wiersz to nagłówek z nazwami kolumn zmiennych: gatunek;waga;dlugosc;predkosc;habitat;zywotnosc;druzyna Kolejne wiersze zawierają wartości tych zmiennych. Opis struktury logicznej tego pliku przedstawiamy na rysunku Rysunek Logiczna struktura pliku koty_ptaki.csv Aby dane w tym formacie wczytać do programu R, można wykorzystać funkcję read.table(). Ma ona wiele parametrów, które opisujemy szczegółowo w dalszej części. Na poniższym przykładzie wczytana tabela wartości jest przypisywana za pomocą operatora 64 2.6 Jak wczytać i zapisać dane w różnych formatach 53 file = ” czyli ścieżka do pliku tekstowego, sep=”;”, czyli informacja, co jest separatorem kolejnych pól, tutaj jest to średnik, dec=”,”, czyli informacja, co jest kropką dziesiętną, zazwyczaj jest to znak kropki, ale akurat w tym pliku kropką dziesiętną jest przecinek, header=true, czyli informacja, że pierwszy wiersz z danymi to nazwy kolumn, a nie wartości. Aby przekonać się, że dane zostały poprawnie wczytane, wykorzystajmy ponownie funkcję head(). Innym sposobem jest użycie zakładki Environment w programie RStudio, tak jak to przedstawiliśmy na rysunku head(koty_ptaki) ## gatunek waga dlugosc predkosc habitat zywotnosc druzyna ## 1 Tygrys Azja 25 Kot ## 2 Lew Afryka 29 Kot ## 3 Jaguar Ameryka 15 Kot ## 4 Puma Ameryka 13 Kot ## 5 Leopard Azja 21 Kot ## 6 Gepard Afryka 12 Kot Rysunek Podgląd tabeli z danymi w programie RStudio. Wczytywanie danych z dużych plików funkcją read.table() może być czasochłonne. W takich sytuacjach warto rozważyć użycie znaczenie szybszej funkcji data.table::fread(), z niewiele mniejszą liczbą parametrów.

65 54 Rozdział 2. Podstawy pracy z R Funkcja read.table() od podszewki Niestety nie ma jednego oficjalnego formatu przechowywania danych w plikach tekstowych. Separatorami, kropkami dziesiętnymi, znakami komentarza czy znakami oznaczającymi napisy może być wiele różnych znaków. Funkcja read.table() potrafi wczytać dane z praktycznie każdym wariantem zapisu. Jest to jednak możliwe wyłącznie za cenę olbrzymiej liczby dodatkowych opcji. Deklaracja funkcji read.table() jest następująca: read.table(file, header=false, sep=””, quote=”\” „, dec=”.”, row.names, col.names, as.is=!stringsasfactors, na.strings=”na”, colclasses=na, nrows=-1, skip=0, check.names=t, fill=!blank.lines.skip, strip.white=f, blank.lines.skip=t, comment.char=”#”, allowescapes=f, flush=false, stringsasfactors, encoding = „unknown”) W pakiecie utils znajdują się również cztery inne funkcje o takim samym działaniu, ale innych wartościach domyślnych. read.csv(file, header=true, sep=”,”, quote=”\””, dec=”.”, fill=true, comment.char=””. ) read.csv2(file, header=true, sep=”;”, quote=”\””, dec=”,”, fill=true, comment.char=””. ) read.delim(file, header=true, sep=”\t”, quote=”\””, dec=”.”, fill=true, comment.char=””. ) read.delim2(file, header=true, sep=”\t”, quote=”\””, dec=”,”, fill=true, comment.char=””. ) Jeżeli dane zapisaliśmy w formacie CSV przy użyciu polskiej wersji programu Excel, separatorem kolumn będzie średnik, a znakiem dziesiętnym będzie przecinek. W tym przypadku najodpowiedniejszą funkcją do odczytu takich danych jest funkcja read.csv2(). Jeżeli korzystamy z angielskiej wersji Excela, to znakiem dziesiętnym jest kropka, a najodpowiedniejszą funkcją do odczytu tych danych jest funkcja read.csv(). W tabeli 2.2 przedstawiamy opis argumentów funkcji read.table(). Angielską wersję tych opisów znaleźć można w pliku pomocy?read.table. Jak widzimy, argumentów jest wiele, warto choć raz o wszystkich przeczytać.

66 2.6 Jak wczytać i zapisać dane w różnych formatach 55 Tablica 2.2. Argumenty funkcji read.table() file Pole o wartości typu znakowego. Jest to jedyny argument obligatoryjny, tzn. musi być jawnie wskazany. Jego wartość to ścieżka do pliku, w którym znajdują się dane. Można wskazać plik na dysku lokalnym lub z Internetu, podając adres URL określający, na którym serwerze i w jakim katalogu ten plik się znajduje. To pole może również określać połączenie lub gniazdo (ang. socket). Jeżeli zamiast nazwy pliku podamy wartość „clipboard”, to dane będą czytane ze schowka systemowego, co jest wygodnym sposobem przenoszenia danych z różnych office ów. header Pole o wartości typu logicznego. Jeżeli wartość w tym polu wynosi TRUE, to pierwszy wiersz będzie traktowany jako lista nazw kolumn. Jeżeli ten argument nie zostanie podany, a w pierwszej linii w pliku jest o jedno pole mniej pól niż pól w kolejnych liniach, to R automatycznie potraktuje tę linię jako nagłówek. sep Pole o wartości typu znakowego. Wskazany łańcuch znaków będzie traktowany jako separator kolejnych pól. Wartość „” (domyślna) powoduje, że każdy biały znak (spacja lub ich ciąg, tabulator, znak nowej linii) jest traktowany jako separator. quote Pole o wartości typu znakowego. Każdy znak występujący w tym łańcuchu jest traktowany jako znak cytowania. Tekst pomiędzy dwoma znakami cytowania traktowany jest jako jedno pole nawet wtedy, gdy występują w nim separatory. dec Pole o wartości typu znakowego. Określa, jaki znak reprezentuje kropkę dziesiętną. Jeżeli dane zapisane są zgodnie z polskimi standardami, to kropką dziesiętną jest znak „,” (przecinek). row.names Pole o wartości typu wektor napisów lub pojedyncza liczba. Jeżeli jest to wektor napisów, to będzie on traktowany jako nazwy kolejnych wierszy. Jeżeli tym argumentem jest liczba, to jest ona traktowana jako numer kolumny w odczytywanym pliku, która zawiera nazwy wierszy. Jeżeli w danych występuje nagłówek (a więc parametr header=true) i pierwsza linia ma o jedno pole mniej niż pozostałe, to pierwsza kolumna automatycznie traktowana jest jako wektor z nazwami wierszy. col.names Wektor napisów. Tym argumentem można określić nazwy kolumn. Jeżeli ten argument nie jest podany, a w pliku nie ma nagłówka, to nazwy kolejnych zmiennych konstruowane są przez złączenie litery „V” z numerem kolumny. nrows Wartość typu liczbowego. Określa, jaka maksymalna liczba wierszy ma być odczytana.

67 56 Rozdział 2. Podstawy pracy z R skip Wartość typu liczbowego. Określa, ile początkowych linii pliku ma zostać pominiętych przed rozpoczęciem czytania danych. check.names Wartość typu logicznego. Czy wymuszać sprawdzanie, czy nazwy zmiennych są poprawne, bez niedozwolonych znaków i powtórzeń. as.is Wektor zmiennych typu logicznego lub liczbowego. Domyślnie każde pole, które nie jest konwertowane na liczbę rzeczywistą lub wartość logiczną, jest konwertowane na zmienną typu factor. Jeżeli parametr as.is jest wektorem wartości logicznych, to jest on traktowany jako wskazanie, które kolumny mogą być konwertowane na typ factor, a które nie. Wektor liczb jest traktowany jako indeksy kolumn, które nie powinny być konwertowane. na.strings Wektor napisów. Wskazuje, jakie wartości mają być traktowane jako NA, czyli jakie wartości określają brakujące obserwacje. Dodatkowo jako brakujące obserwacje oznaczane są też puste pola w kolumnach o wartościach typu liczbowego lub logicznego. colclasses Wektor znaków. Każdy znak określa typ kolejnej zmiennej (kolumny). Dopuszczalne wartości to: NA domyślna wartość, oznacza automatyczną konwersję, NULL ta kolumna będzie pominięta, jedna z klas atomowych (logical, integer, numeric, complex, character, raw, factor, Date lub POSIXct). fill Wartość typu logicznego. Jeżeli kolejne linie mają różną liczbę wartości, a argument fill=false (domyślnie), to działanie funkcji read.table() zakończy się błędem. Jeżeli argument fill=true, to do krótszych wierszy dodawane będą na koniec wartości NA, tak aby uzupełnić wiersze do równej długości. blank.lines.skip Wartość typu logicznego. Jeżeli wynosi TRUE, to przy wczytywaniu danych pomijane będą puste linie. comment.char Wartość typu znakowego. Ten znak traktowany jest jako znak komentarza. Po wystąpieniu tego znaku zawartość do końca linii jest ignorowana. allowescapes Wartość typu logicznego. Jeżeli jest równa TRUE, to tekst odczytywany jest zgodnie z zasadami oznaczania znaków specjalnych. Przykładowo napisy \t lub \n są zamieniane na odpowiednio znak tabulacji oraz znak nowej linii. Wartość FALSE (domyślna) powoduje, że tekst czytany jest dosłownie, bez żadnych interpretacji. stringsasfactors Wartość typu logicznego. Jeżeli jest równa TRUE, to łańcuchy znaków będą konwertowane na typ wyliczeniowy factor. Jeżeli FALSE, to będą reprezentowane jako łańcuchy znaków. Domyślna wartość to TRUE.

68 2.6 Jak wczytać i zapisać dane w różnych formatach Zapisywanie danych do pliku tekstowego Funkcja write.table() Funkcja write.table() zapisuje wartość zmiennej (atomowej, wektora, macierzy lub ramki danych) w określonym formatowaniu do pliku tekstowego. Pełna deklaracja tej funkcji jest następująca: write.table(x, file=””, append=false, quote=true, sep=” „, eol=”\n”, na=”na”, dec=”.”, row.names=true, col.names=true, qmethod=c(„escape”,”double”)) Podobnie jak w przypadku funkcji read.table() w pakiecie utils dostępne są dwie funkcje o identycznym działaniu co write.table(), ale przy innej parametryzacji argumentów domyślnych. Obie funkcje przeznaczone są do zapisywania danych w formacie CSV. write.csv(x, file = „”, sep = „,”, dec=”.”. ) write.csv2(x, file = „”, sep = „;”, dec=”,”. ) W tabeli 2.3 przedstawiamy opis wszystkich parametrów funkcji write.table(), przygotowany na podstawie pliku pomocy?write.table. Poniżej na kilku przykładach pokażemy, jak zapisać wektor, liczbę lub ramkę danych do pliku. Ta instrukcja wypisze wektor liczb na ekranie zamiast do pliku: write.table(runif(100),””) Ta instrukcja wpisze wektor do schowka systemowego: write.table(1:100,”clipboard”,col.names=false, row.names=false) Ta instrukcja wpisze napis do pliku tekstowego: write.table(„poniedzialek”,”c:/najgorszydzienwtygodniu.txt”) Ta instrukcja zapisze dane do pliku w formacie CSV: write.csv2(iris, file=”doexcela.csv”). Zapisywanie dużych obiektów typu data.frame do pliku w formacie tekstowym może być czasochłonne. Jest to spowodowane przełączaniem się formatowania dla każdej kolejnej kolumny, która może być innego typu. Program R sprawdza typ dla każdej kolumny i każdego wiersza i formatuje wartości w zależności od ich typu. Aby przyśpieszyć zapis, czasem warto dane przekonwertować na macierz funkcją as.matrix().

69 58 Rozdział 2. Podstawy pracy z R Tablica 2.3. Argumenty funkcji write.table() x Obiekt do zapisania. Pole obligatoryjne. Ten obiekt to najczęściej macierz lub obiekt typu data.frame. file Wartość typu znakowego. Jest to ścieżka do pliku, w którym mają być zapisane dane. To pole może określać również połączenie lub gniazdo, tak jak w przypadku funkcji read.table(). Podobnie, jeżeli zamiast nazwy pliku podamy wartość „clipboard”, to dane będą zapisane do schowka systemowego. Wartość „” spowoduje wyświetlenie obiektu na konsoli. qmethod Wartość typu znakowego. Wskazuje, jak oznaczone mają być znaki specjalne. Wartość „escape” poleca zastosować oznaczenie w stylu C (z dodaniem znaku backslash), wartość „double” nakazuje zastosować podwójny znak backslash. sep Wartość typu znakowego. Wskazany łańcuch znaków będzie traktowany jako separator kolejnych pól (separatorem nie musi być pojedynczy znak). eol Wartość typu znakowego. Ten łańcuch będzie wstawiany jako koniec linii. W przypadku systemu Windows domyślne zakończenie linii to eol=”\r\n”. quote Wartość typu logicznego. Wartość TRUE powoduje, że pola typu factor oraz łańcuchy znaków będą otoczone znakiem ” (cudzysłów). dec Wartość typu znakowego. To pole wskazuje, jaki ma być znak dziesiętny. Domyślnie jest to „.” (kropka). Jeżeli dane mają być zapisane zgodnie z polskimi standardami, to separatorem dziesiętnym powinien być znak „,” (przecinek). row.names Wektor napisów lub wartość typu logicznego. Jeżeli jest to wektor napisów, to będzie on traktowany jako nazwy kolejnych wierszy. Jeżeli jest to wartość logiczna, to będzie ona określała, czy nazwy wierszy powinny być zapisane, czy nie. col.names Wektor napisów lub wartość typu logicznego. Jeżeli jest to wektor napisów, to będzie on traktowany jako nazwy kolejnych kolumn. Jeżeli jest to wartość logiczna, to będzie ona określała, czy nazwy kolumn powinny być zapisane, czy nie Wczytywanie i zapisywanie z zastosowaniem formatu JSON Powyżej pisaliśmy głównie o danych tabelarycznych. Jednak nie wszystkie dane można zapisać w postaci tabeli. Uniwersalnym i bardzo elastycznym formatem stosowanym do przenoszenia różnych danych jest JSON (ang. JavaScript Object Notation). Jest on szczególnie często wykorzystywany w rozwiązaniach opartych na komunikacji przez Interenet, między innymi w rozmaitych serwisach REST.

70 2.6 Jak wczytać i zapisać dane w różnych formatach 59 JSON to format tekstowy (a więc czytelny dla człowieka), opisuje dane w hierarchicznej strukturze (co jest bardzo elastycznym rozwiązaniem) i jest lekki (czyli nie zajmuje dużo miejsca). Poniżej przedstawiamy przykładowe dane w formacie JSON. Opisują one dwuelementową listę, której pierwszą wartością jest napis, a drugą wartością tabela. < "zrodlo": "Przewodnik", "wskazniki": [ <"rok": "2020", "wartosc": 15.5>, <"rok": "2020", "wartosc": 10.1>, <"rok": "2020", "wartosc": 12.2>] > W programie R jest kilka pakietów do wczytywania danych z formatu JSON i zapisywania danych do tego formatu. Trzy najpopularniejsze to RJSONIO, rjson i jsonlite. Każdy z nich ma funkcję tojson(), konwertującą dane do formatu JSON, i funkcję fromjson(), wczytującą dane zapisane w tym formacie. Najbardziej stabilny w użyciu jest pakiet jsonlite i poniżej przedstawiamy przykład tylko dla niego. Z formatu JSON do R: Wczytane dane mają początkowo strukturę listy, jeżeli jest to możliwe, to struktura jest upraszczana do ramki danych/wektora. fromjson(<"zrodlo": "Przewodnik","wskazniki": [<"rok": "2020", " wartosc": 15.5>,<"rok": "2020", "wartosc": 10.1>,<"rok": "2020", " wartosc": 12.2>]>) ## $zrodlo ## [1] „Przewodnik” ## ## $wskazniki ## rok wartosc ## ## ## Z R do formatu JSON: Poniżej przedstawiamy przykład konwersji dwóch pierwszych wierszy ramki danych koty_ptaki: tojson(koty_ptaki[1:2,]) ## [<"gatunek":"tygrys","waga":300,"dlugosc":2.5,"predkosc":60," habitat":"azja","zywotnosc":25,"druzyna":"kot">, ## <"gatunek":"lew","waga":200,"dlugosc":2,"predkosc":80,"habitat":" Afryka","zywotnosc":29,"druzyna":"Kot">]

71 60 Rozdział 2. Podstawy pracy z R Wczytywanie danych w formatach HTML i XML Źródłem danych mogą być też strony WWW. Treść takich stron jest opisana w formacie HTML. Format HTML jest formatem tekstowym opartym na znacznikach, podobnie jak format XML. Oba te formaty są do siebie podobne. Główną różnicą jest to, że pierwszy wykorzystuje się do opisu wyglądu (strony internetowej), a drugi do opisu treści (dokumentu). Aby wygodnie pracować z danymi w formacie XML, można użyć pakietu xml2. Aby wygodnie pracować z danymi w formacie HTML, można użyć pakietu rvest, który w dużej części korzysta z xml2. Dane w formatach HTML i XML mają strukturę drzewiastą. Zazwyczaj praca z takimi danymi sprowadza się do określenia wzorca, który zlokalizuje wszystkie pasujące węzły dokumentu. Następnie na takiej kolekcji wykonuje się dalsze przetwarzanie, np. wyłuskiwanie atrybutów/treści z węzłów. Poniżej przedstawiamy przykład. Używając pakietu rvest, wczytujemy stronę w formacie HTML. Funkcją html_nodes() wybieramy tylko te węzły, które mają klasę.gwt-filmpage. W końcu ze znalezionych węzłów wyciągamy treść funkcją html_text(). library(„rvest”) premiery 72 2.6 Jak wczytać i zapisać dane w różnych formatach 61 Domyślnie dane odczytywane są ze standardowego strumienia wejściowego, czyli bezpośrednio z konsoli (domyślna wartość parametru file = „”). Dzięki temu możemy w skryptach R, wraz z kodem źródłowym umieszczać nieduże zbiory danych. Poniższy skrypt inicjuje macierz mat wskazanymi 20 liczbami. dane 73 62 Rozdział 2. Podstawy pracy z R Podajemy format dla każdej linii osobno. (dane 74 2.6 Jak wczytać i zapisać dane w różnych formatach 63 Rysunek Podgląd zakładek w pliku Excela GUS_LUDN.xlsx ze strony ludnoscszeroka 75 64 Rozdział 2. Podstawy pracy z R Tablica 2.4. Wybrane funkcje do wczytywania danych z plików Excela pakiet funkcja_odczyt funkcja_zapis formaty wymaga readxl read_excel().xlsx,.xls openxlsx read.xlsx() write.xlsx().xlsx xlsx read.xlsx() write.xlsx().xlsx,.xls Java XLConnect readworksheet() writeworksheet().xlsx,.xls Java gdata read.xls().xlsx,.xls Perl WriteXLS WriteXLS().xlsx,.xls Perl Zestawienie najpopularniejszych prezentuje tabela 2.4. Część z pakietów wymaga dodatkowych programów. Wczytywanie danych z innych programów Trzy najpopularniejsze źródła danych to pliki tekstowe, pliki Excela i bazy danych. Jednak w pracy z danymi często przychodzi korzystać z danych zapisanych w innych formatach takich jak SAS, Matlab czy SPSS. W kolejnych punktach przedstawimy instrukcje, pozwalające wczytać dane również z takich programów Wczytywanie danych z SPSS a Jeżeli dane są zapisane w formacie programu SPSS, to aby je wczytać potrzebny jest pakiet Hmisc. W pakiecie Hmisc znajduje się wiele funkcji do importu danych zapisanych w plikach binarnych w formacie różnych programów. Do importu formatu SPSS służy funkcja Hmisc::spss.get(). Poniżej odczytujemy i wyświetlamy dane z formatu programu SPSS. library(„hmisc”) dane 76 2.6 Jak wczytać i zapisać dane w różnych formatach 65 Opis kolumny wiek w ramce danych. attributes(dane$wiek)$label ## wiek ## „Wiek osoby w chwili badania” Jak wyżej, tyle że funkcją label z pakietu Hmisc. label(dane$wiek) ## wiek ## „Wiek osoby w chwili badania” Rozbudowane podsumowanie zmiennej wiek. describe(dane$wiek) ## dane$wiek : Wiek osoby w chwili badania ## n missing unique Mean ## ## ## ## Frequency ## % Wiele niskopoziomowych funkcji do odczytu plików w formatach innych programów, znajduje się w pakiecie foreign. Jest tam np. funkcja read.spss(), również odczytująca dane z formatu SPSS. Funkcje z pakietu foreign są wykorzystywane przez omawiany w tym rozdziale pakiet Hmisc Wczytywanie danych z programu Matlab Pakiety programu R związane z programem Matlab to matlab (emulator Matlaba) i R.matlab (pakiet do komunikacji pomiędzy programem R a Matlabem, również do odczytywania i zapisywania plików w formacie MAT). Szczegółowej dokumentacji tych pakietów należy szukać na stronach CRAN. Poniżej podamy przykład jak odczytać pliki zapisane w formacie MAT. Wykorzystamy do tego funkcję R.matlab::readMat(). Odczytuje ona pliki MAT zapisane w wersjach V4, V5 i V6. Dane są odczytywane jako lista, której kolejne pola odpowiadają kolejnym zmiennym zapisanym w pliku MAT. Odczytujemy i wyświetlamy strukturę pliku w formacie Matlaba. library(„r.matlab”) danemat 77 66 Rozdział 2. Podstawy pracy z R W tym pliku zapisane są zmienne o nazwach normalny i wykladniczy. dim(danemat$normalny) ## [1] Osoby korzystające z Matlaba zainteresują się interfejsem RMatlab, pozwalającym na wywoływanie komend R z poziomu Matlaba i komend Matlaba z poziomu R. Więcej informacji na ten temat można znaleźć w [45] Wczytywanie danych z SAS Jest kilka sposobów na odczytanie danych zapisanych w formacie SAS. Najłatwiejszym jest skorzystanie z funkcji foreign::read.ssd(), np. w następujący sposób: library(„foreign”) dane 78 2.7 Automatyczne raporty, powtarzalne badania 67 read.dta() Wczytywanie danych z pliku w formacie Stata. read.epiinfo() Wczytywanie danych z pliku w formacie Epi (pliki.rec). read.mtp() Wczytywanie danych z pliku w formacie Minitab. read.octave() Wczytywanie danych z pliku w formacie Octave. read.spss() Wczytywanie danych z pliku w formacie SPSS. read.ssd() Wczytywanie danych z pliku w formacie SAS. read.systat() Wczytywanie danych z pliku w formacie Systat. read.xport() Wczytywanie danych w formacie SAS XPORT. sas.get() Wczytywanie plików w formacie SAS. Funkcja z pakietu Hmisc. spss.get() Wczytywanie plików w formacie SPSS. Funkcja z pakietu Hmisc. readmat() Wczytywanie plików Matlaba.MAT. Funkcja z pakietu R.matlab Automatyczne raporty, powtarzalne badania W tym rozdziale pokażemy, jak w prosty sposób wygenerować raport z analizami do pliku HTML, PDF lub DOC. Takie raporty można wykorzystać w biznesie, aby tworzyć dla klientów zautomatyzowane cykliczne zestawienia, lub na własny użytek, aby razem z kodem R trzymać komentarze do tworzonego programu. Logika opisanych poniżej rozwiązań jest trzykrokowa. 1. Tworzymy plik (najczęściej o rozszerzeniu *.Rmd lub *.Rnw). W tym pliku umieszczamy zarówno instrukcje w programie R, jak i opisy sformatowane w języku markdown lub L A TEX. 2. Plik jest przetwarzany przez parser pakietów knitr lub Sweave. Parser wykonuje instrukcje R i w dokumencie umieszcza również ich wynik. Wyniki kodu R i ich opis zapisywane są w pliku *.md lub *.tex. 3. Ostatnim krokiem jest użycie programów pandoc lub pdflatex, które budują raport w formacie HTML, PDF lub DOC. Wszystkie te kroki wykonać można praktycznie jednym przyciskiem i poniżej pokażemy, jak to zrobić. Ale najpierw kilka słów o historii tego rozwiązania. Angielski termin literate programming (przetłumaczony tutaj jako programowanie objaśniające ) został zaproponowany przez Donalda Knutha, autora między innymi języka TEX. Za tym terminem kryje się idea, którą można opisać w trzech punktach (zobacz również artykuły [20] i [42]): programy są bezużyteczne bez opisów/dokumentacji, opisy powinny wyjaśniać program, zwykłe komentarze w kodzie nie są wystarczające, przykładowe kody wykorzystane w opisach powinny być wykonywalne i kompletne.

79 68 Rozdział 2. Podstawy pracy z R W ostatnich latach programowanie objaśniające zyskało na popularności z uwagi na problem powtarzalnych badań (ang. reproducible research). W czasach gdy publikuje się coraz więcej i coraz mniejsza jest kontrola recenzenta nad pracą, coraz ważniejsze staje się zapewnienie, że wyniki z naukowych prac można powtórzyć w przyszłości. Poniżej przedstawiamy zarówno pakiet knitr, jak i Sweave. Pakiet knitr uważany jest za następcę Sweave. Jest łatwiejszy w użyciu, pozwala na wyprodukowanie plików w formatach PDF, HTML raz w wielu innych (pośrednio dzięki wykorzystaniu programu pandoc). Zaletą pakietu Sweave jest większa kontrola nad procesem przetwarzania. Poniżej prezentujemy najpierw proste zastosowanie pakietu knitr, następnie pakietu slidify, później napiszemy więcej o pakiecie Sweave Pakiet knitr, markdown a raporty w HTML Punktem wyjściowym jest przygotowanie pliku, w którym znajdą się fragmenty kodu w języku R wraz z opisami w języku naturalnym. Opisy te chcemy formatować, wytłuszczać, powiększać, tworzyć na ich podstawie rozdziały, podrozdziały, dodawać tabele czy rysunki. Jednym z najprostszych do nauczenia się języków opisujących formatowanie tekstu jest markdown. Z uwagi na prostą składnię jest często wykorzystywany na forach internetowych. Do formatowania wystarczy użyć kilku prostych schematów. Aby wyróżnić jakiś element, należy otoczyć go z obu stron znakami *. Aby dodać tytuł rozdziału lub podrozdziału, wystarczy rozpocząć linię od znaków #, ## lub ###. In więcej znaków #, tym niższy poziom w hierarchii. Aby dodać wyliczenie, należy linię z każdym elementem wyliczenia rozpocząć od znaku *. Aby dodać link do strony WWW, wystarczy ten link wkleić z prefixem lub W procesie kompilacji tego pliku odpowiednio oznaczone fragmenty kodu R zostaną wykonane, a ich wynik zostanie dodany do opisu kodu. W ten sposób czytelnik ma 100% gwarancji, że rezultat, który jest prezentowany w opisie, powstał tylko i wyłącznie w wyniku wywołania wymienionych poleceń R. Zwyczajowo pliki w których łączy się kod R i markdown, oznacza się rozszerzeniem.rmd. Mając taki plik, przetwarza się go następnie, używając funkcji knit(). Ta funkcja wykonuje instrukcje programu R (można dołączać również kod w innych językach, np. python), a następnie zarówno instrukcje jak i ich wynik zapisuje z użyciem formatu markdown. Zwyczajowo pliki w formacie markdown mają rozszerzenie.md. W wyniku przetwarzania plik o takim rozszerzeniu będzie dodany do katalogu roboczego. Plik w formacie markdown jest transformowany do pliku z rozszerzeniem.html.

80 2.7 Automatyczne raporty, powtarzalne badania 69 Jeżeli korzystamy z programu RStudio, to w oknie edytora dostępny jest przycisk Knit HTML (o ile rozszerzenie pliku to *.Rmd). Kliknięcie tego przycisku powoduje automatyczne skompilowanie raportu i wyświetlenie wynikowej strony w przeglądarce. Na rysunku 2.20 przedstawiamy przykładowy kod źródłowy raportu. Rozpoczyna go niewielki nagłówek opisany w formacie YAML (ang. YAML Ain t Markup Language). Określa on tytuł dokumentu, autora, datę powstania i format pliku wyjściowego. Rysunek Dokument źródłowy to mieszanina kodu R i markdown Rysunek Dokument pośredni zawiera tylko kod w formacie markdown

81 70 Rozdział 2. Podstawy pracy z R W tym przypadku format wyjściowy to „output: html_document”, dlatego plik zostanie przekonwertowany do formatu HTML. Aby otrzymać plik Worda jako wynik, wystarczy zmienić ten napis na „output: word_document”. W wyniku przetworzenia pliku przez funkcję knitr() wygenerowany będzie plik raport.md o zawartości przedstawionej na rysunku W kolejnym kroku plik w formacie markdown jest konwertowany do pliku HTML za pomocą programu pandoc. Wynik przetworzenia przedstawiliśmy na rysunku Format pliku wynikowego był umieszczony w nagłówku YAML. Jeżeli go zmienimy na „output: pdf_document” to przycisk Knit HTML w programie RStudio zamieni się na Knit PDF, a w wyniku kompilacji otrzymamy plik PDF. Rysunek Wynikowy dokument w postaci strony HTML utworzony na bazie skryptu Ten sam plik można przekonwertować do formatu Word lub PDF

82 2.7 Automatyczne raporty, powtarzalne badania Wstawki Fragmenty kodu R, które mają być zamienione na wynik, będziemy nazywali wstawkami, ponieważ wyniki będą wstawione w wynikowy plik. Aby parser wiedział, który fragment pliku jest kodem R, należy zastosować odpowiednie oznaczenia. Wyróżniamy tutaj dwie możliwości, nazywane krótką lub długą wstawką. Krótka wstawka to instrukcje R pomiędzy ogranicznikami `r (dwa znaki) a ` (jeden znak). Zwróćmy uwagę, że znak ` to grawis, a nie prosty pojedynczy apostrof. W zależności od klawiatury znak ` znajduje się pod znakiem Esc lub obok lewego znaku Shift. Instrukcje R w krótkiej wstawce zostaną wykonane, a ich wynik bezpośrednio wstawiony w miejsce tych instrukcji. Dlatego napis `r nrow(iris)` widoczny w przykładowym pliku Rmd został przekształcony w liczbę 150 w pliku md. Długa wstawka to ciąg instrukcji otoczony dwoma liniami. Rozpoczęcie wstawki to trzy znaki ` i literka r. Zakończenie wstawki to trzy znaki `. „` „` Po przetworzeniu długich wstawek w pliku wynikowym pojawią się bloki odpowiadające zarówno wejściowemu kodowi R, jak i rezultatom jego wykonania tekstowym (te są poprzedzone znakami ##) oraz graficznym (te umieszczane są w osobnych plikach PNG). W linii rozpoczynającej długą wstawkę można dodać dodatkowe parametry. W przykładzie powyżej te parametry określały szerokość i wysokość wygenerowanego wykresu. Takich parametrów wykonania, które można zmieniać, jest znacznie więcej. Np. można wyłączyć raportowanie ostrzeżeń lub błędów. Dokładną listę znaleźć można w pozycji [42]. Najczęściej używane z parametrów opisaliśmy poniżej: Parametr warning=true FALSE, message=true FALSE określa, czy w wynikowym pliku md umieszczać komunikaty ostrzeżeń lub powiadomień (TRUE), czy nie (FALSE). Parametr cache=true FALSE określa, czy dana wstawka ma być za każdym razem wykonywana, czy też jej wyniki mają być zapisane i odtwarzane z cache a. Domyślnie każda wstawka jest kompilowana za każdym razem. Jeżeli jednak obliczenia określonej wstawki trwają długo, a zawartość wstawki się nie zmienia, to warto włączyć korzystanie z cache a. Parametr echo=true FALSE określa, czy w wynikowym pliku mają znaleźć się instrukcje z programu R. Ustawienie tego parametru na wartość FALSE powoduje, że w pliku HTML pojawią się tylko wyniki, bez kodu R. Wygodne, gdy chcemy ten kod z jakichś powodów ukryć przed końcowym odbiorcą.

83 72 Rozdział 2. Podstawy pracy z R Parametr results= asis markup hide określa w jakim formacie wynik ma być umieszczony w pliku md. Opcja markup (domyślna) powoduje przekształcenie wyniku do formatu markdown, asis powoduje wklejenie wyniku z kodu R bez żadnego dodatkowego formatowania, hide powoduje uruchomienie kodu R, ale wynik nie zostanie zawarty w pliku md. Parametr tidy=true FALSE określa, czy kod wejściowy powinien być dodatkowo uporządkowany przed umieszczeniem go w pliku wynikowym. Wartość TRUE dodaje wcięcia, spacje i dba o to, by kod wyglądał czytelniej. Parametr highlight=true FALSE określa, czy w wynikowym pliku kod R powinien być dodatkowo kolorowany (TRUE), czy nie (FALSE). Parametr dev=pdf png. określa, w jakim formacie mają być przechowywane wykresy wygenerowane przez kod R. Parametry fig.width, fig.height, dpi określają wymiary wykresów (w calach) i rozdzielczość (liczba punktów na cal). Krótkich, jak i długich wstawek może być w plikach.rmd dowolnie dużo Prezentacje w HTML5 Powyżej pokazaliśmy jak wykorzystać pakiet knitr do tworzenia raportów, które są jedną długą stroną html. Co jeżeli zamiast raportu chcemy przygotować prezentację składającą się z serii slajdów? Można użyć L A TEXowego pakietu beamer (wymaga to jednak znajomości L A TEX) lub slidify opisanego na stronie Od roku można też bardzo prosto robić prezentacje w programie RStudio. Poniżej opiszemy jak. Treść slajdów prezentacji opisuje się w języku markdown, a same slajdy są generowane do formatu HTML5. Dokument źródłowy powinien być zapisany w pliku o rozszerzeniu *.Pres. Aby oznaczyć, w którym miejscu ma rozpocząć się kolejny slajd należy umieścić tytuł slajdu, a po nim linię składającą się wyłącznie ze znaków ================= Pracując w programie RStudio po utworzeniu pliku o rozszerzeniu Rpres z definicją prezentacji wystarczy przycisnąć przycisk Preview aby po kilku sekundach otrzymać prezentację. Na rysunku 2.23 przedstawiony jest kod definiujący te cztery slajdy: tytułowy, ze spisem treści i dwa slajdy integrujący program R i opisy. Z jednej strony mamy proste instrukcje pozwalające na wskazanie nagłówków, treści w języku naturalnym, a z drugiej strony możemy dołączyć wyniki wygenerowane na żywo przez program R. Ten kod źródłowy, należy zapisać w pliku z rozszerzeniem Rpres. Dynamiczne generowanie prezentacji pozwala na dużą kontrolę spójności wyników. Za każdym razem mamy możliwość sprawdzenia, jaki kod R został wykorzystany do otrzymania prezentowanych wyników. Unika się dzięki temu pro-

84 2.7 Automatyczne raporty, powtarzalne badania 73 blemu z pamiętaniem, jaka wersja danych, jaka wersja parametrów doprowadziła akurat do tego konkretnego wyniku. Rysunek Kod źródłowy prezentacji z użyciem pakietu Rpres Rysunek Prezentacja wygenerowana z użyciem pakietu Rpres na podstawie kodu przedstawionego na rysunku 2.23

85 74 Rozdział 2. Podstawy pracy z R Pewną wadą prezentacji w formacie HTML5 jest to, że trudno je zamienić na pdf czy pptx. Zaletą jest szybkość ich tworzenia i integracja z kodem R produkującym wyniki umieszczone w prezentacji Pakiet Sweave a raporty w języku LATEX Aby ten podrozdział był zrozumiały wymagana jest przynajmniej podstawowa znajomość programu do składu dokumentów L A TEX. Zacznijmy od przykładu. Na rysunku 2.25 przedstawiona jest zawartość pliku raportsweave.rnw. Jest to plik przypominający dokument w formacie L A TEX, ale w tym pliku znajdują się również instrukcje języka R. Taki plik można przekształcić na raport na dwa sposoby, Korzystając z funkcji Sweave lub klikając przycisk Compile PDF w programie RStudio. Wynikiem tego polecenia będzie plik raportsweave.tex. Fragmenty kodu R otoczone znacznikami >= zostały wykonane. Wyniki zostały wklejone w kod dokumentu L A TEX. Następnie ten plik zostanie skompilowany poleceniem pdflatex do formatu pdf. Wynik przykładowego docelowego dokumentu jest przedstawiony na rysunku Po uruchomieniu procesu kompilacji powinniśmy w konsoli zobaczyć następujące komunikaty. Sweave(„raportSweave.Rnw”) ## Writing to file raportsweave.rnw ## Processing code chunks. ## 1 : echo term verbatim ## 2 : term verbatim eps pdf Rysunek Kod źródłowy dokumentu Sweave

86 2.7 Automatyczne raporty, powtarzalne badania 75 Programowanie objaśniajace ze Sweave Przemyslaw Biecek Wykres pude lkowy jest bardzo popularna metoda prezentacji zmienności pojedynczej zmiennej. Można go wyznaczać również dla kilku zmiennych (dzieki czemu możemy porównać rozk lady tych zmiennych) lub dla pojedynczej zmiennej w rozbiciu na grupy obserwacji. Kszta lt tego wykresu jest bardzo charakterystyczny, przypominajacy pude lko z wasami. Poszczególne elementy wykresu przedstawiaja różne charakterystyki obserwowanej zmiennej. Środek pude lka przedstawia mediane, dolna i górna granica pude lka odpowiada kwartylom z próby (odpowiednio dolnemu i górnemu kwartylowi), kropki przedstawiaja obserwacje odstajace. Zakres zmienności (minimum i maksimum) danej zmiennej (po ominieciu wartości odstajacych) zaznaczony jest za pomoca wasów wykresu. > dane attach(dane) > print(by(wiek, plec, summary)) INDICES: kobieta Min. 1st Qu. Median Mean 3rd Qu. Max INDICES: mezczyzna Min. 1st Qu. Median Mean 3rd Qu. Max > boxplot(wiek

plec, data = dane, col = „lightgrey”) kobieta mezczyzna 1 Rysunek Strona dokumentu w formacie pdf otrzymana w sposób zautomatyzowany za pomocą pakietu Sweave

87 76 Rozdział 2. Podstawy pracy z R Ostatnia linia informuje o tym, że przetwarzanie pliku raportsweave.rnw przebiegło bez problemów. W katalogu roboczym utworzonych zostało kilka nowych plików między innymi plik raportsweave.tex. To plik wynikowy, zapisany w języku L A TEX. W tym pliku został umieszczony opis oraz wyniki wykonania komend R znajdujących się w pliku raportsweave.rnw. Przyjrzyjmy się bliżej zawartości pliku raportsweave.rnw. Wygląda on jak zwykły plik z kodem w L A TEXu, w którym występują fragmenty o składni: >= kod Określając odpowiednie argumenty wstawek, możemy określać, w jaki sposób wyniki kodu R zostaną wklejone do pliku tex. Jeżeli wynikiem poleceń R jest wykres, to aby znalazł się on w pliku wynikowym, należy za argument wstawki podać fig=true. W jednej wstawce możemy wyświetlić dowolnie wiele wykresów. Wynik każdego z nich zostanie przetworzony do dwóch plików: jednego w formacie pdf i jednego w formacie eps. Do pliku wynikowego automatycznie zostanie dodana odpowiednia instrukcja L A TEX dołączająca plik z rysunkiem. Jeżeli spodziewamy się, że wykonywana we wstawce funkcja R wyprodukuje kod w formacie L A TEX (a więc nie jest potrzebna dodatkowa transformacja wyniku), to w danej wstawce powinniśmy podać argument results=tex. Taki argument powinien być podany np. jeżeli korzystamy z funkcji xtable: :xtable(), służącej do wyświetlania tabel w formacie L A TEX. Np. następująca wstawka >= library(„xtable”) mat = matrix(1:25,5,5, dimnames=list(letters[1:5], LETTERS[6:10])) xtable(mat, caption=”tabela kolejnych zostanie przetworzona na % latex table generated in R by xtable package % Thu Jul 10 11:13: \begin

[ht] \begin
\begin & F & G & H & I & J \\ \hline \hline A & 1 & 6 & 11 & 16 & 21 \\ B & 2 & 7 & 12 & 17 & 22 \\ C & 3 & 8 & 13 & 18 & 23 \\ D & 4 & 9 & 14 & 19 & 24 \\ E & 5 & 10 & 15 & 20 & 25 \\ \hline

88 2.7 Automatyczne raporty, powtarzalne badania 77 \end \caption \end

\end

Do konwersji obiektów R do języka L A TEX można wykorzystać funkcję tolatex() lub funkcję tobibtex() przygotowującą odpowiednią tekstową reprezentacje w języku L A TEX dla obiektu będącego jej argumentem. Jeżeli chcemy w kodzie L A TEXa wykonać wyrażenie napisane z użyciem składni programu R, to zamiast używać wstawek można posłużyć się poleceniem \Sexpr. Poniżej prezentujemy przykład kodu, w którym po przetworzeniu przez Sweave() prawa strona wyrażenia (fragment w poleceniu \Sexpr<. >) zostanie zastąpiona wynikiem wyliczonym w programie R. Poniższy skrypt $$\frac<1-log(3)> <\sqrt 5>= \Sexpr<(1-log(3))/5^.5>$$ w wyniku przetwarzania zostanie zamieniony na $$\frac<1-log(3)> <\sqrt 5>= $$ Jeżeli nasz wynikowy plik ma być bardzo duży, to możemy nie chcieć, by wyniki wszystkich wstawek umieszczane były w jednym, tym samym pliku. Ustawienie we wstawce argumentu split=true spowoduje, że wynik wykonanego kodu R zostanie zapisany w osobnym pliku o nazwie w postaci plik-etykieta.tex, gdzie etykieta powinna być określona w liście argumentów. >= Ten tekst trafi do innego pliku, ktory zostanie wlaczony do glownego pliku Wynik z wykonania skryptów R umieszczany jest w pliku wynikowym w jednym z dwóch środowisk Sinput (dla instrukcji R) i Soutput (dla wyników tych instrukcji). Aby L A TEX potrafił rozpoznać te środowiska musi znać ich definicje. Znajdują się one w pliku Sweave.sty, który jest w katalogu pakietu Sweave Ilustracje / winietki Programowanie objaśniające nadaje się świetnie do przedstawiania konkretnych rozwiązań/poleceń/funkcji w R. Opis rozwiązania połączony jest z kodem, który to rozwiązanie generuje, a również z wynikiem wykonania tego kodu. Czytelnik może więc szczegółowo porównać wynik z argumentami wywoływanych poleceń, mając pewność, że autor nie pominął jakiegoś ważnego parametru.

89 78 Rozdział 2. Podstawy pracy z R Takie przykładowe rozwiązania są dostępne w programie R w postaci ilustracji (ang. vignette). Do pakietów R, poza funkcjami, zbiorami danych i opisami, dołączane są również ilustracje rozwiązań określonych problemów. Ilustracja składa się z kodu R prezentującego rozwiązanie oraz pliku przedstawiającego wynik tego rozwiązania. Dostęp do ilustracji rozwiązań odbywa się z użyciem funkcji vignette(). Poniżej przedstawiamy przykładowe wywołania tej funkcji. Wyświetlmy listę ilustracji dostępnych w zainstalowanych pakietach. Zobaczmy jedną konkretną ilustrację, dotyczącą wielowymiarowej oceny gęstości. Poniższe polecenie otworzy plik PDF z opisem funkcjonalności funkcji ks::kde() oraz opisem przykładów wykorzystania tej funkcji w programie R. Kolejne polecenie otworzy okno edytora z kodami w języku R, których wyniki zostały przedstawione w powyższej ilustracji. vignette(all = TRUE) library(„ks”) ilustracja 90 Rozdział 3 Niezbędnik programisty The point is, ladies and gentleman, that r programming for lack of a better word is good. R Programming is right. R Programming works. R Programming clarifies, cuts through, and captures the essence of the evolutionary spirit. R Programming, in all of its forms R Programming for life, for money, for love, knowledge has marked the upward surge of mankind. Random R Hacker rfoaas::greed( R Programming, Random R Hacker ) Dane są coraz większe i coraz bardziej złożone. Trudno jest dzisiaj być biegłym w analizie danych bez przyzwoitej umiejętności programowania. Tylko ono daje wystarczająco dużą elastyczność w przetwarzaniu danych. Program R jest wyposażony w pełnoprawny język programowania, który umożliwia tworzenie bardzo rozbudowanych profesjonalnych rozwiązań programistycznych. W tym rozdziale przedstawiamy wybrane zaawansowane możliwości tego języka programowania. Po lekturze tego rozdziału czytelnik będzie gotów do tworzenia aplikacji internetowych, własnych pakietów oraz rozbudowanych funkcji. Kolejnym krokiem może być lektura zaawansowanych pozycji, takich jak [36]. W podrozdziale 3.1 omawiamy, jak tworzyć funkcje, pętle i instrukcje warunkowe w programie R. Opanowanie tego materiału jest niezbędne, by budować bardziej złożone rozwiązania. W podrozdziale 3.2 omawiamy, w jaki sposób korzystać z danych dostępnych w bazach danych. Pozwalają one wyjść poza największe ograniczenie R konieczność przechowywania danych roboczych w pamięci RAM. W podrozdziale 3.3 opisujemy, jak budować aplikacje internetowe oparte na programie R. Omawiany pakiet shiny dosłownie zrewolucjonizował sposób, w jaki przygotowuje się obecnie rozwiązania wykorzystujące dane. W drodze do poznawania coraz bardziej zaawansowanych możliwości programu R w podrozdziale 3.4 wskazujemy, jak tworzyć własne pakiety w programie R. W podrozdziale 3.6 omawiamy narzędzia do identyfikacji oraz na- 79

91 80 Rozdział 3. Niezbędnik programisty prawiania błędów. W podrozdziale 3.7 opisujemy natomiast narzędzia do przyśpieszania kodu. Kolejne podrozdziały poświęcone są innym przydatnym funkcjom Instrukcje sterujące W trzech kolejnych podrozdziałach omawiamy, jak tworzyć funkcje w programie R, jak sterować kodem, a wiec jak budować instrukcje warunkowe, oraz przedstawiamy kilka różnych podejść do tworzenia pętli w programie R. Po lekturze tego podrozdziału czytelnik będzie umiał tworzyć całkiem złożone programy Jak tworzyć funkcje W większych programach pewne fragmenty kodu często powtarzają się wielokrotnie i/lub są używane w różnych miejscach. Czasem należy wykonać pewien schemat instrukcji, być może z niewielką różnicą w argumentach. W takich sytuacjach wygodnie jest napisać funkcję, która uprości program i zwiększy jego czytelność. Generalnie rzecz biorąc, zamykanie kodu w funkcjach jest dobrym zwyczajem, zwiększa to czytelność i zazwyczaj skraca kod, a tym samym wpływa na zmniejszenie liczby błędów, które zawsze gdzieś w kodzie się znajdą. Istnieje wiele wskazówek, jak pisać dobre funkcje, elastyczne, z możliwością ponownego wykorzystania, robiące jedną rzecz, a więc łatwe do opisania i zapamiętania, do czego dana funkcja służy. Ponieważ jednak nie jest to podręcznik do programowania, poprzestanę na dwóch uwagach. Funkcje powinny być tak tworzone, by nie korzystały ze zmiennych globalnych (parametry do działania powinny być przekazane poprzez argumenty, używanie zmiennych globalnych najczęściej prowadzi do trudnych w wykryciu błędów), dzięki temu stają się izolowane i łatwiej je wykorzystywać w różnych kontekstach, różnych programach. Funkcje powinny być możliwie krótkie, ułatwi to ich modyfikacje i śledzenie poprawności, łatwiej też zrozumieć, co dana funkcja robi. Jeżeli jakaś funkcja znacznie się rozrosła, to z pewnością można i warto podzielić ją na mniejsze funkcje. Z punktu widzenia użytkownika każda funkcja posiada listę argumentów oraz tak zwane ciało funkcji. Ciałem nazywa się zbiór instrukcji, które mają być wykonane przy każdym wywołaniu funkcji. Przyjrzyjmy się obu elementom na przykładzie funkcji dodającej pierwszy argument do kwadratu drugiego. function(a, b) a + b^2

92 3.1 Instrukcje sterujące 81 W nawiasach po słowie kluczowym function wymienione są argumenty funkcji. Po nawiasach znajduje się ciało, czyli sekwencja instrukcji określających, co funkcja ma robić. W ogólnym przypadku sekwencja instrukcji powinna być zamknięta w blok za pomocą nawiasów <>. Gdy mamy do czynienia tylko z jedną instrukcją, to te nawiasy nie są niezbędne i można je pominąć. W programie R każda funkcja jest zwykłym obiektem, takim jak liczba czy napis. Jako obiekt może istnieć bez nazwy. Nawet gdy nie ma nazwy, można ją wywołać za pomocą operatora (), tak jak w poniższym przykładzie: (function(a, b) a + b^2 )(1, 2) ## [1] 5 Gdy po definicji funkcji pojawił się napis (1, 2), wtedy interpreter R wykonał tę funkcję z parametrami a=1 i b=2. Funkcje mogą przekazywać (potocznie mówiąc: zwracać) wartości. Za wynik funkcji przyjmowana jest wartość wyznaczona w ostatniej linii ciała funkcji. Innym sposobem przekazywania wartości jest wykorzystanie instrukcji return(). Powoduje ona przerwanie wykonywania funkcji oraz przekazanie jako wyniku wartości będącej argumentem polecenia return() Nazywanie funkcji Tak jak widzieliśmy, funkcja nie musi mieć nazwy. Znacznie prościej się jednak z niej korzysta, gdy ma nazwę. W tym celu wystarczy przypisać funkcję do dowolnego symbolu. Nazwa funkcji, podobnie jak nazwa dowolnej zmiennej, musi rozpoczynać się literą, może zawierać litery, cyfry lub inne znaki. Najlepiej też, by nazwa funkcji wyjaśniała, co funkcja robi. ab2 93 82 Rozdział 3. Niezbędnik programisty Argumenty funkcji Funkcja nie musi mieć argumentów. Przykładem użytecznej funkcji niepotrzebującej żadnego argumentu jest Sys.time(). Jako wynik zwraca ona aktualny czas. Sys.time() ## [1] ” :27:09 CEST” Funkcje mogą mieć dowolną liczbę argumentów. Każdy argument musi mieć unikalną nazwę. Dla każdego argumentu możemy też wskazać wartość domyślną, czyli wartość, która będzie zastosowana, jeżeli dany argument nie zostanie użyty przy wywołaniu funkcji. Przy wywołaniu funkcji można przez nazwę wskazać, który argument jest określany. Jeżeli wywołujemy funkcję z wartościami, ale bez podawania nazw argumentów, to wartości będą przypisane do kolejnych argumentów. ab2 94 3.1 Instrukcje sterujące 83. Nazwy argumentów funkcji potrafią być długie, jednak nie trzeba ich całych podawać! Zamiast pełnej nazwy argumentu wystarczy podać fragment nazwy, który jednoznacznie identyfikuje argument. funkcja(po = „duzy”) ## 5 duzy funkcja(p = „maly”, li = 1313) ## 1313 maly Leniwe argumenty W programie R argumenty są przypisywane jako wyrażenia, a nie przez wartość. Wartość przypisanego wyrażenia jest wyznaczana dopiero, gdy jest potrzebna. Mechanizm ten pozwala pominąć obliczenia, które nie są niezbędne. Przyjrzyjmy się poniższemu przykładowi. Funkcja skaluj przyjmuje argumenty center i scale, które są wyznaczane jako wartość średnia i standardowe odchylenie z próby. Jednak te argumenty w ciele funkcji są wykorzystywane tylko, gdy argument trans ma wartość TRUE. W przeciwnym wypadku nie są one używane i nawet nie są wyznaczane ich wartości (ponieważ nie są potrzebne). Dzięki temu skracamy czas obliczeń, nie wyznaczając wartości zbędnych argumentów. skaluj 95 84 Rozdział 3. Niezbędnik programisty Funkcja zwracająca jako wynik inną funkcję Ponieważ w programie R funkcja jest zwykłą wartością, więc może być zarówno argumentem funkcji, jak i jej wynikiem. Przyjrzyjmy się obu sytuacjom oddzielnie. Często wykorzystywaną funkcją jest ecdf(), czyli funkcja wyznaczająca empiryczną dystrybuantę. Ale empiryczna dystrybuanta jest funkcją! library(„przewodnik”) dystrybuantacen 96 3.1 Instrukcje sterujące 85 Możemy sami stworzyć funkcję, która przyjmie inną funkcję jako argument. Przykładowo poniższa funkcja jako pierwszy argument przyjmuje generator liczb losowych i wywołuje go z wartością 10 oraz ewentualnymi dodatkowymi argumentami. losuj10 97 86 Rozdział 3. Niezbędnik programisty Jeżeli blok_instrukcji_1 lub blok_instrukcji_2 składa się tylko z jednej instrukcji, to można pominąć nawiasy klamrowe <>. Zobaczmy, jak to wygląda na poniższym przykładzie. Zapis: liczba %% 2 == 0 oznacza sprawdzenie, czy reszta z dzielenia przez 2 ma wartość 0, jeżeli tak jest, to to wyrażenie przyjmuje wartość TRUE, w przeciwnym razie wartość FALSE. liczba 98 3.1 Instrukcje sterujące 87 Wynik będzie miał wartości opisane przez instrukcja_1 w pozycjach odpowiadających wartości TRUE wektora warunek_logiczny oraz wartości opisane przez instrukcja_2 w pozycjach odpowiadających wartości FALSE wektora warunek_logiczny. Prześledźmy wyniki poniższych przykładów. Najpierw przykład, w którym tylko pierwszy argument jest wektorem: ifelse(1:7 0, (1:5)^2, (1:5)^3) ## [1] A tutaj wszystkie argumenty to pojedyncze wartości. ifelse(1==2, „cos jest nie tak”, „uff”) ## [1] „uff” Funkcja switch() W przypadku omówionych powyżej instrukcji warunkowych mieliśmy do czynienia z warunkiem logicznym, który mógł być prawdziwy lub fałszywy. Jednak w pewnych sytuacjach zbiór możliwych akcji, które chcemy wykonać, jest większy. W takich sytuacjach sprawdza się instrukcja warunkowa switch(), o następującej składni: switch(klucz, wartosc1 = akcja1, wartosc2 = akcja2. ) Pierwszy argument powinien być typu znakowego lub typu wyliczeniowego factor. W zależności od wartości tego argumentu jako wynik zostanie zwrócona wartość otrzymana w wyniku wykonania odpowiedniej akcji. W poniższym przykładzie sprawdzamy, jaka jest klasa danej zmiennej, i w zależności od tego wykonujemy jedną z wielu możliwych akcji. W bloku klucz sprawdzana jest klasa zmiennej liczba. Wiemy, że ta klasa to numeric, ponieważ zmienna liczba przechowuje wartość Dlatego też zostanie wykonana wyłącznie druga akcja. liczba 99 88 Rozdział 3. Niezbędnik programisty Jeżeli wartość klucza (pierwszego argumentu funkcji switch()) nie pasuje do etykiety żadnego z kolejnych argumentów, to wynikiem instrukcji switch() jest wartość argumentu nienazwanego (czyli domyślną akcją w powyższym przykładzie jest wyświetlenie napisu „trudno okreslic”). Jeżeli wartość klucza zostanie dopasowana do etykiety jednego z kolejnych argumentów, ale nie jest podana żadna związana z nim akcja, to wykonana zostanie akcja dla kolejnego argumentu. Innymi słowy, jeżeli klucz miałby wartość „logical”, to ponieważ nie jest wskazana wartość dla argumentu logical, zostanie wykonana akcja wskazana przy kolejnej z etykiet, czyli „numeric”. Argumenty funkcji switch() korzystają z mechanizmu leniwego wartościowania (ang. lazy evaluation, więcej informacji nt. tego mechanizmu przedstawimy w podrozdziale 3.8.4). W językach z gorliwą ewaluacją, takich jak Java czy C++, przekazywanie argumentów funkcji polega na wyznaczeniu wartości kolejnych argumentów i na przekazaniu do funkcji wyłącznie wyznaczonych wartości. Gdyby tak było w powyższym przykładzie, to przed wywołaniem funkcji switch() określone byłyby wartości wszystkich argumentów, czyli wykonane byłyby wszystkie funkcje cat(). Jak budować pętle W tym rozdziale omawiamy różne podejścia do powtarzania określonych instrukcji kilkukrotnie, czyli do tworzenia tak zwanych pętli. Bardzo często zachodzi potrzeba wykonania jakiejś operacji dla każdego modelu, każdego kraju lub określoną liczbę razy. W zależności jednak od tego, ilukrotnie chcemy wykonać zadaną operację, wygodniej będzie nam wykorzystać inny mechanizm R do tworzenia pętli. Omawiamy te różne podejścia poniżej jedno po drugim. Do ilustracji, które podejście jest bardziej przydatne, wykorzystujemy przykład ubezpieczeniowy. Poniżej przedstawiamy definicję funkcji strata(), która symuluje wysokość straty w określonym czsie. Najpierw z rozkładu Poissona wyznacza liczbę strat, a następnie zadaną liczbę strat losuje z rozkładu log-normalnego. Wynikiem funkcji jest suma strat. strata 100 3.1 Instrukcje sterujące Funkcja replicate() Funkcja replicate(n, expr) może być wykorzystana, by powtórzyć określony blok operacji (expr) zadaną liczbę razy (n). Przykładowo, aby poznać rozkład strat, możemy chcieć powtórzyć proces losowania wysokości straty razy. Z pomocą funkcji replicate można to zrobić w jednej linii. Wynikiem jest wektor wartości wyznaczonych przez kolejne wywołania funkcji strata. straty 101 90 Rozdział 3. Niezbędnik programisty lista_obiektow 102 3.1 Instrukcje sterujące 91 x 103 92 Rozdział 3. Niezbędnik programisty Działanie tej pętli polega na powtarzaniu blok_instrukcji tak długo aż. Właśnie, nie ma tu żadnego warunku stop! Działanie zostanie przerwane wyłącznie w wyniku wygenerowania błędu lub użycia instrukcji break (ta instrukcja przerywa wykonywanie wszystkich rodzajów pętli, również pętli for i while). Przyjrzyjmy się poniższemu przykładowi: repeat < x ) break >x ## [1] Instrukcję break można wykorzystywać w każdym rodzaju pętli, podobnie w każdej pętli można wykorzystywać instrukcję next. Pierwsza przerywa działanie pętli, druga powoduje przerwanie wykonywania aktualnej iteracji pętli oraz przejście do kolejnej iteracji Jak pracować z bazami danych Zdecydowana większość funkcji w programie R wymaga, aby dane na których pracujemy, były w pamięci RAM. Ale jeżeli chcemy korzystać z dużych zbiorów danych, które zajmują dużo miejsca, to mamy dwie możliwości: pracować na tłustych komputerach, z dużą ilością RAM (jednak obecnie trudno wyjść poza 1 TB RAM, chyba że ma się baaardzo duży budżet), trzymać dane poza R, możliwie dużo przetwarzania wykonywać poza R, a do R wczytywać tylko takie dane, które są naprawdę niezbędne. W tym rozdziale przyjrzymy się tej drugiej możliwości. Trzymanie danych poza R oznaczać będzie przechowywanie ich w bazie danych. W takiej bazie możemy szybko wyznaczyć niezbędne agregaty lub pobrać losową próbkę do dalszych analiz. Nawet jeżeli danych nie jest bardzo dużo, to warto rozważyć korzystanie z bazy. Pozwala to na jednolity sposób dostępu do danych z różnych narzędzi przez różne osoby. Umożliwia zarządzanie prawami dostępu do danych oraz zapewnia skalowalność operacji na danych. Poniżej przedstawiamy dwa przykłady komunikacji R z bazami danych. Pierwszy przykład dotyczy prostej bazy danych SQLite. Cała baza jest jednym plikiem. Prezentujemy elementarne przykłady pozwalające na przećwiczenie podstawowych operacji. Drugi przykład dotyczy pracy z popularną bazą PostgreSQL. Sposób pracy z taką bazą jest bardzo podobny do większości popularnie stosowanych baz relacyjnych.

104 3.2 Jak pracować z bazami danych Jak pracować z bazą danych SQLite SQLite (patrz [54]) to lekka baza danych przechowująca całe dane w jednym pliku. Ma ona dosyć ograniczone funkcjonalności, ale jej główną zaletą jest prostota użycia. Tak łatwo ją zainstalować, że wręcz trudno powiedzieć, w którym momencie się to robi. Ponieważ jest to jeden plik, łatwo tę bazę skopiować czy komuś wysłać. Dlatego pomimo ograniczonych możliwości ma ona sporo zastosowań, w których ważniejsza jest prostota niż skalowalność. Aby użyć tej bazy danych w programie R, potrzebny jest pakiet RSQLite. Korzystanie z tej bazy składa się z poniższych kroków Należy wczytać sterownik do łączenia się z bazą danych. To można zrobić funkcją dbdriver(). Należy nawiązać połączenie z bazą danych, najczęściej funkcją dbconnect(). W przypadku bazy SQLite wystarczy wskazać ścieżkę do pliku z bazą danych. Do bazy danych wysyła się instrukcje oparte na języku SQL. W wyniku otrzymuje się tabele z danymi. Po zakończeniu pracy z bazą danych należy zwolnić połączenie (funkcja dbdisconnect()) i sterownik. Przykładowa sesja z bazą danych jest następująca. Ładujemy sterownik do bazy danych i inicjujemy połączenie z serwerem. Jeżeli wskazany plik nie istnieje, to zostanie stworzona pusta baza danych. Plik wykorzystany w tych przykładach można pobrać ze strony library(„rsqlite”) sterownik 105 94 Rozdział 3. Niezbędnik programisty Używając funkcji dbgetquery(), możemy wykonać na bazie zapytanie SQL: pierwsze5 106 3.2 Jak pracować z bazami danych 95 O ile te bazy różnią się funkcjonalnością, skalowalnością i prędkością, to z perspektywy użytkownika R używanie ich jest dosyć podobne. Poniżej pokażemy, jak korzystać z bazy PostgreSQL. Na potrzeby przykładu użyjemy działającej bazy PostgreSQL dostępnej na serwerze services.mini.pw.edu.pl. PostgreSQL pozwala na zarządzanie wieloma użytkownikami i wieloma bazami danych, tutaj wykorzystamy bazę sejmrp, przechowującą dane z Sejmu RP 7. i 8. kadencji (głosowania i stenogramy). Dane te są uzupełniane za pomocą pakietu sejmrp [47]. Aby korzystać z bazy danych, potrzebny jest użytkownik i hasło. Poniżej prezentujemy przykład dla użytkownika reader i hasła qux Ten użytkownik ma wyłącznie uprawnienia do czytania, można więc pracować z nim bez obaw, że coś zostanie usunięte. Aby połączyć się z bazą PostgreSQL potrzebujemy sterownika, który jest dostępny w pakiecie RPostgreSQL. Wczytajmy ten pakiet i nawiążmy połączenie z bazą danych: library(„rpostgresql”) dbname 107 96 Rozdział 3. Niezbędnik programisty Na koniec pracy należy rozłączyć się z bazą danych i zwolnić połączenie. dbdisconnect(polaczenie) ## [1] TRUE Jak używać pakietu dplyr w pracy z bazami danych Standardów i implementacji SQL-a jest tak wiele, że zastanawiające jest, dlaczego nazywane są standardami. Praktycznie każda baza danych różni się listą zaimplementowanych funkcjonalności czy agregatów. Jeżeli pracujemy z jedną bazą danych, to ta różnorodność nie będzie nam doskwierać. Ale jeżeli przyjdzie nam jednocześnie korzystać z baz MSSQL, MySQL, RedShift i Postgres? Lub gdy okaże się, że dane zostały zmigrowane do nowej bazy danych? Wielu problemów można sobie oszczędzić, używając pośrednika do komunikacji z bazą danych. Takim pośrednikiem może być pakiet dplyr, omówiony w poprzednim rozdziale. Pozwala on na pracę z danymi bez zastanawiania się, gdzie te dane aktualnie są i jak nazywa się w tym systemie bazodanowym potrzebna nam funkcja. W pakiecie dplyr połączenia ze źródłem danych (tabelą z liczbami lub bazą danych) tworzy się dzięki funkcjom src_*. Poniżej korzystamy z funkcji src_sqlite() i src_postgres(). Zainicjujmy połączenie z bazą SQLite i pobierzmy kilka pierwszych wierszy z tabeli auta2020: library(„dplyr”) polaczenie % head(2) ## Cena Waluta Cena.w.PLN Brutto.netto KM kw Marka ## PLN brutto Kia ## PLN brutto Mitsubishi A teraz pokażmy przykład dla bazy PostgreSQL. Połączymy się z bazą, wyświetlimy dostępne tabele i stworzymy połączenie do tabeli votes. polaczenie 108 3.2 Jak pracować z bazami danych 97 Zdefiniowawszy połączenie, możemy pracować na tej tabeli, używając funkcji z pakietu dplyr. glosy %>% group_by(club, vote) %>% summarise(liczba = n()) -> liczba_glosow class(liczba_glosow) ## [1] „tbl_postgres” „tbl_sql” „tbl” Wynikiem tych operacji jest obiekt klasy tbl_sql. Nie przechowuje on danych, ale instrukcje pozwalające na dostęp do danych (zapytanie SQL). Można to zapytanie i plan zapytania wyłuskać: liczba_glosow$query ## SELECT „club”, „vote”, „liczba” ## FROM (SELECT „club”, „vote”, count(*) AS „liczba” ## FROM „votes” ## GROUP BY „club”, „vote”) AS „zzz3” ##

explain(liczba_glosow) ## ## SELECT „club”, „vote”, „liczba” ## FROM (SELECT „club”, „vote”, count(*) AS „liczba” ## FROM „votes” ## GROUP BY „club”, „vote”) AS „zzz3” ##

## HashAggregate (cost= rows=52 width=9) ## -> Seq Scan on votes (cost= rows= width =9) Dane wskazywane przez to połączenie nie są materializowane, o ile nie muszą być materializowane (użytkownik wprost tego nie zażąda). Pozwala to jak najwięcej operacji przeprowadzić zdalnie, jeszcze w bazie danych, i do R pobrać jedynie końcowe agregaty. Zazwyczaj jest to dużo szybsze rozwiązanie niż pobieranie całych danych i praca z nimi lokalnie. Gdy już jest jasne, co użytkownik chce zrobić, i gdy jawnie zażąda wyniku, wszystkie operacje są wykonywane w możliwie małej liczbie kroków (jednym). Materializować wyniki można na dwa sposoby: collect() wyznacza wynik oraz pobiera go do R, compute() wyznacza wynik i zapisuje go w tymczasowej tabeli w bazie danych. Poniższa instrukcja pobiera wyliczone agregaty ze zbioru danych: collect(liczba_glosow) ## Source: local data frame [60 x 3] ## Groups: club [15]

109 98 Rozdział 3. Niezbędnik programisty ## club vote liczba ## (chr) (chr) (dbl) ## 1 ZP Przeciw 8448 ## 2 PO Przeciw ## 3 KPSP Przeciw 5659 ## 4 niez. Nieobecny ## 5 PO Wstrzymal sie 3291 ## 6 ZP Wstrzymal sie 3472 ## 7 Kukiz15 Za 4495 ## 8 niez. Za ## 9 KPSP Wstrzymal sie 2699 ## 10 Kukiz15 Nieobecny 893 ## Więcej informacji o funkcjach z pakietu dplyr, które można stosować do baz danych, znaleźć można na stronie [35] Budowa aplikacji WWW z pakietem shiny W poprzednim rozdziale pokazaliśmy, jak tworzyć automatyzowalne raporty z użyciem pakietów knitr i Sweave. Jednym z częstych zastosowań raportów jest przygotowanie zbioru zestawień statystycznych dla innej osoby (klienta, przełożonego, recenzenta, kolegi z zespołu). Wadą raportu jest jego statyczność i liniowość. Raz wygenerowany raport ma określoną treść (statyczną), którą zazwyczaj przegląda się strona po stronie (liniowość). Co jednak, gdybyśmy chcieli w interaktywny sposób eksplorować dane? Dać odbiorcy możliwość wyboru interesujących go parametrów i wyznaczenia opisu dla zadanych parametrów? Obecnie najlepszym sposobem zrobienia tego w programie R jest przygotowanie aplikacji internetowej z użyciem pakietu shiny (patrz też [25]). Aplikacje Shiny to strony internetowe tworzone i zasilane przez działający na serwerze program R. Użytkownicy aplikacji mogą poprzez stronę HTML wybierać parametry przetwarzania. Przetwarzanie danych i parametrów ma miejsce na serwerze, a jego wynik jest przedstawiany ponownie na stronie internetowej. Galeria interesujących przykładów aplikacji wykonanych z użyciem biblioteki shiny znajduje się na stronie Zastosowania są najróżniejsze, od hobbystycznych aplikacji do oglądania małych zbiorów danych po złożone serwisy internetowe dostarczające informacji rzeszom użytkowników. Poniżej pokażemy, jak zbudować aplikację shiny krok po kroku.

110 3.3 Budowa aplikacji WWW z pakietem shiny Jak wygląda model akcja reakcja Aplikacje Shiny działają zgodnie z modelem akcja reakcja (ang. reactive programming). Jest to model znany np. z arkuszy kalkulacyjnych. Zazwyczaj takie arkusze poza danymi zawierają również formuły określające, jak ma być wyznaczona wartość danej komórki w zależności od innych komórek. Jeżeli zmienimy wartość w jednej komórce (akcja) to automatycznie zmienią się wartości w komórkach zależnych (reakcja). Podobnie wygląda reakcja w aplikacji zbudowanej z wykorzystaniem biblioteki shiny. Na stronie WWW umieszczamy kontrolki wskazujące pewne wartości oraz wyniki działania funkcji na tych wartościach. Gdy zmienimy kontrolkę, to odświeżone zostaną wszystkie wyniki, które od danej kontrolki zależą. Takie inteligentne odświeżanie wartości, które mogą się zmienić, pozwala na budowę szybkich i jednocześnie złożonych aplikacji. Model akcja reakcja wymaga oprogramowania sposobu, w jaki elementy wejściowe wpływają na wygląd/stan/wartość elementów wyjściowych. Jeżeli w trakcie pracy zmieniona zostanie wartość jakiegoś elementu wejściowego (kliknięty przycisk, wpisana wartość liczbowa, przesunięty suwak), to przeliczone zostaną odpowiednie elementy wyjściowe Jak opisać interfejs użytkownika Aplikacja Shiny składa się z dwóch części, które zazwyczaj opisuje się w dwóch osobnych plikach. Jedna część zawiera opis interfejsu użytkownika, układu elementów graficznych (zapisuje się ją w pliku ui.r), druga opisuje sposób przetwarzania danych (zapisuje się ją w pliku server.r). Pierwsza aplikacja, którą przedstawiamy, jest dostępna pod adresem Nie ma w niej jeszcze żadnej interakcji, ale pokazana jest budowa elementów interfejsu graficznego. Ekran tej aplikacji zaprezentowany jest na rysunku 3.1. Plik ui.r opisuje strukturę wyglądu ekranu. Zagnieżdżona struktura funkcji odpowiada zagnieżdżeniu elementów HTML w aplikacji. Rysunek 3.1. Ekran pierwszej z prezentowanych aplikacji Shiny

111 100 Rozdział 3. Niezbędnik programisty Funkcja titlepanel() odpowiada za określenie tytułu, a sidebarlayout() odpowiada za stworzenie podziału strony na lewy i prawy panel. Funkcje p() i br() tworzą następnie HTML-owe tagi

oraz
. W pakiecie shiny znajdują się funkcje odpowiadające wszystkim tagom HTML-a. # Plik ui.r — interfejs library(shiny) shinyui(fluidpage( titlepanel(„moja pierwsza aplikacja”), sidebarlayout( sidebarpanel( p(„tutaj jest lewy panel”) ), mainpanel( br(), p(„tutaj jest prawy panel”) ) ) )) Każda aplikacja potrzebuje też instrukcji odpowiadających za przetwarzanie po stronie serwera. Zazwyczaj umieszcza się je w pliku server.r. W tej aplikacji nie ma żadnej interakcji, więc i opis strony serwerowej jest pusty: # Plik server.r — logika biznesowa shinyserver(function(input, output) < >) Aby odtworzyć tę aplikacje na własnym komputerze, należy w katalogu stworzyć dwa pliki: ui.r i server.r, a następnie przekopiować do nich powyżej przedstawione treści. Po otwarciu tych plików w programie RStudio w prawym górnym rogu powinna pojawić się ikonka Run App, której kliknięcie uruchomi aplikację. Inną możliwością jest wywołanie funkcji shiny::runapp() ze wskazaniem katalogu, w którym znajdują się oba pliki. Uruchomienie aplikacji przez program RStudio spowoduje, że działa ona na lokalnym komputerze. Wgranie obu plików na serwer, na którym zainstalowana jest aplikacja Shiny Server, spowoduje, że będziemy mogli naszą aplikację udostępnić również innym użytkownikom Jak opisać przetwarzanie na serwerze Zbudujmy teraz aplikację, która coś liczy i wyświetla efekt swej pracy na ekranie. W przypadku poniższej aplikacji wynikiem będą dwa elementy: wykres i opis modelu liniowego.

112 3.3 Budowa aplikacji WWW z pakietem shiny 101 Pod adresem można obejrzeć opisaną poniżej aplikację. Dodanie wyników do aplikacji wymaga zmiany obu jej części. W pliku ui.r należy określić, gdzie ma zostać umieszczony wynik, a w pliku server.r należy podać sposób jego wyliczenia. Ekran tej aplikacji przedstawiony jest na rysunku 3.2. Rysunek 3.2. Ekran aplikacji Shiny wyświetlającej wykres. Wykres jest za każdym razem generowany przez R umieszczony na serwerze. Cała aplikacja jest dostępna na stronie Zacznijmy od pliku ui.r. W miejscu, gdzie tworzony jest prawy panel, znalazły się wywołania dwóch nowych funkcji: plotoutput(), wskazującej, gdzie ma zostać umieszczony wykres zapisany w obiekcie o nazwie trend, verbatimtextoutput(), wskazującej, gdzie ma zostać umieszczony opis zapisany w obiekcie o nazwie model. Funkcje osadzające obiekty w interfejsie HTML mają nazwy określające, co jest osadzane (wykres, tabela, opis obiektu, strona HTML), i kończące się słowem Output.

118 3.4 Budowanie własnych pakietów 107 Rysunek 3.4. Struktura przykładowego pakietu proton plik DESCRIPTION, z opisem podstawowych informacji o pakiecie (nazwa pakietu, krótki opis, autor, zależności), plik NAMESPACE, z opisem funkcji udostępnionych przez pakiet, katalog R, z listą funkcji w programie R, katalog data, z listą zbiorów danych udostępnionych przez pakiet, katalog man, z plikami dokumentacji Rd do udostępnionych funkcji i zbiorów danych, katalog vignettes, z listą przewodników opisujących funkcjonalności pakietu, katalog tests, z listą testów weryfikujących poprawność funkcji. W kolejnych sekcjach omawiamy zawartość poszczególnych plików i katalogów Jak stworzyć nowy pakiet Nowy pakiet najwygodniej zbudować, używając funkcji create() z biblioteki devtools. Pierwszym argumentem tej funkcji jest ścieżka do katalogu, w którym ma być założony pakiet. Ostatni człon tej nazwy jest traktowany jako nazwa pakietu. Na potrzeby tego rozdziału stworzymy nowy pakiet kuppanauto i zbudujemy go w obecnym roboczym katalogu. library(devtools) create(„kuppanauto”) ## Creating package kuppanauto in. ## No DESCRIPTION found. Creating with values: ## Package: kuppanauto ## Title: What the Package Does (one line, title case) ## Version: ## person(„first”, „Last”, = „, role = c(„aut”, „cre”))

119 108 Rozdział 3. Niezbędnik programisty ## Description: What the package does (one paragraph). ## Depends: R (>= 3.3.2) ## License: What license is it under? ## LazyData: true ## Adding RStudio project file to kuppanauto Powyższa instrukcja w aktualnym katalogu tworzy podkatalog o nazwie kuppanauto z minimalną liczbą niezbędnych plików. Początkowa zawartość katalogu jest przedstawiona na rysunku 3.5. Rysunek 3.5. kuppanauto Struktura plików i katalogów w nowo utworzonym pakiecie Funkcja create() tworzy automatycznie plik konfiguracyjny projektu RStudio. Jest on zapisany w pliku *.proj. Otwarcie takiego pliku w programie RStudio spowoduje otwarcie projektu z katalogiem roboczym automatycznie ustawionym na katalog pakietu Plik DESCRIPTION Każdy pakiet musi mieć plik DESCRIPTION, który zawiera podstawowe informacje o pakiecie. Do informacji tych należą: nazwa, opis, informacja o autorach i lista zależności od innych pakietów. Nowo stworzony przez funkcję create() pakiet ma plik DESCRIPTION. Pierwszą rzeczą, którą należy zrobić po zbudowaniu pakietu, jest uzupełnienie informacji w tym pliku. W sekcji Package wpisujemy nazwę pakietu, w sekcji Title jednozdaniowy opis pakietu, w sekcji Authors informację o autorach oraz ich roli przy tworzeniu pakietów. W sekcji Description uzupełniamy szerszy opis pakietu. Szczególnie istotne są sekcje Imports i Suggests, które opisują zależności od innych pakietów. Sekcja Imports wskazuje pakiety niezbędne do działania Twojego pakietu. Program R będzie je instalował przy instalacji Twojego pakietu. Sekcja Suggests wskazuje pakiety dodatkowe, które mogą rozszerzać możliwości Twojego pakietu, ale nie są niezbędne do działania kluczowych funkcjonalności. Na rysunku 3.6 przedstawiamy przykładowy uzupełniony plik DESCRIPTION. Jeżeli w naszym pakiecie chcemy korzystać z funkcji lub danych z innych pakietów, powinniśmy dodać odpowiednią zależność do pliku DESCRIPTION.

120 3.4 Budowanie własnych pakietów 109 Rysunek 3.6. Uzupełniony plik DESCRIPTION przykładowego pakietu proton Możemy w tym celu wykorzystać funkcję use_package(), która dodaje informacje o zależnościach od wskazanych pakietów. use_package(package = „PogromcyDanych”, pkg = „kuppanauto”) ## Adding PogromcyDanych to Imports ## Refer to functions with PogromcyDanych::fun() use_package(package = „dplyr”, pkg = „kuppanauto”) ## Adding dplyr to Imports ## Refer to functions with dplyr::fun() Jak dodawać funkcje do pakietu Najczęstszym zastosowaniem pakietów jest udostępnianie zbioru użytecznych funkcji. Aby dodać funkcję do pakietu, wystarczy jej treść dodać w pliku o rozszerzeniu R do podkatalogu o nazwie R. Podczas ładowania pakietu wczytywane są wszystkie instrukcje z plików *.R umieszczonych w katalogu R. Nazwa pliku *.R nie musi być taka sama jak nazwa funkcji. Jednak dobrze jest stosować te same lub podobne nazwy, aby łatwiej było znaleźć miejsce, gdzie znajduje się opis funkcji. Przykładowo, poniżej przedstawiamy definicję funkcji jakiprzebieg(), liczącej średni przebieg aut z danego rocznika. Definicję tej funkcji należy wkleić do dowolnego pliku z rozszerzeniem R w podkatalogu o nazwie R.

121 110 Rozdział 3. Niezbędnik programisty jakiprzebieg 122 3.4 Budowanie własnych pakietów 111 Rysunek 3.7. Przykładowa dokumentacja funkcji jakiprzebieg Gdy już zbudujemy i włączymy pakiet, opis funkcji jakiprzebieg() będzie dostępny po uruchomieniu instrukcji?jakiprzebieg. Powyżej przedstawiony kod zostanie przekształcony na dokumentację przedstawioną na rysunku 3.7. Na rysunku 3.8 przedstawiliśmy przykładowy plik z opisem dokumentacji bardziej rozbudowanej funkcji Jak dodawać zbiory danych do pakietu W pakietach możemy również przechowywać dane. Jest to wygodne, jeżeli chcemy jeden lub kilka zbiorów danych udostępnić współpracownikom, studentom lub całej reszcie świata. Wiele zbiorów danych stało się bardzo popularnymi właśnie dzięki temu, że łatwo było do nich sięgnąć i coś z nimi zrobić. Dane do pakietu dodać można na dwa sposoby: zapisując ten zbiór danych z użyciem funkcji save() do pliku z rozszerzeniem rda lub RData. Następnie ten plik należy wkopiować do katalogu data w pakiecie, używając funkcji use_data() z pakietu devtools. Poniższe linijki wyznaczają wektor ze średnimi cenami różnych marek aut, a następnie zapisują ten wektor do pakietu kuppanauto. library(„pogromcydanych”) srednieceny 123 112 Rozdział 3. Niezbędnik programisty Obiekty zapisane w pliku sysdata.rda (w jednym pliku można zapisać więcej niż jeden obiekt) są widoczne wyłącznie dla funkcji wewnątrz pakietu. Są na swój sposób prywatne. Pozostałe obiekty będą widoczne globalnie. Umieszczenie zbioru danych w pakiecie to jedno, opisanie użytkownikowi, jak z niego korzystać to drugie. Podobnie jak w przypadku funkcji, aby dodać dokumentację zbioru danych, należy przygotować plik o rozszerzeniu Rd w katalogu man. Ale zamiast robić to ręcznie, lepiej skorzystać z pakietu roxygen2, który na bazie metaopisu wygeneruje nam poprawny plik Rd. Pakiet roxygen2 wymaga, by odpowiedni opis dokumentowanego pakietu umieścić w pliku o rozszerzeniu R w katalogu R, a więc tam, gdzie znajdują się opisy funkcji. Rysunek 3.8. Przykładowy opis funkcji proton Rysunek 3.9. Przykładowa dokumentacja zbioru danych

124 3.4 Budowanie własnych pakietów 113 Pierwsza linia opisu traktowana jest jako tytuł pliku pomocy. Aby zaznaczyć, że jest to opis zbioru z danymi, należy dodać data. wskazuje, pod jakim hasłem należy szukać danego pliku pomocy, zazwyczaj jest to nazwa zbioru danych. Inne parametry pozwalają na określenie struktury danych i opisanie zawartości poszczególnych składowych. Przykładową dokumentację zbioru danych przedstawia rysunek Jak dodawać testy do pakietu Bardzo ważną i jednocześnie zaniedbywaną składową tworzenia pakietów jest przygotowywanie testów weryfikujących, czy funkcjonalności (wciąż) działają. Dla programu R przygotowano kilka różnych rozwiązań pozwalających na proste budowanie testów. W przypadku budowania pakietów lekkim i wygodnym rozwiązaniem umożliwiającym tworzenie testów jest pakiet testthat, który omawiamy poniżej. Testy dodajemy w plikach R do katalogu tests/testthat w pakiecie. Aby dodać ten katalog do naszego pakietu, wraz z potrzebnymi zależnościami, wystarczy wykonać instrukcję use_testthat() z pakietu devtools. Przygotuje ona całą niezbędną infrastrukturę dla testów w pakiecie. use_testthat(„kuppanauto”) Nazwa testy jednostkowe bierze się stąd, że testy weryfikują poprawność poszczególnych jednostek/modułów. Zazwyczaj wykorzystuje się je, by przetestować poszczególne funkcje. Każdy test to wywołania funkcji test_that(), która przyjmuje argumenty: Pierwszym jest nazwa testu. Gdyby podczas wykonania pojawił się błąd, ta nazwa ułatwi określenie, co nie działa. Drugi to lista oczekiwań, czyli funkcji rozpoczynających się od expect_. Funkcje te sprawdzają, czy wywołanie funkcji kończy się oczekiwanym rezultatem, wartością, błędem, ostrzeżeniem, napisem itp. Trzy przykładowe testy przestawione są poniżej: test_that(„result is a number”,< expect_true(is.numeric(jakacena("kia", 2020))) >) test_that(„an invalid number of parameters”,< expect_error(jakacena()) expect_error(jakacena("kia")) >) test_that(„results are correct”,< expect_equal(round(jakacena("kia", 2020)), 44544) expect_equal(round(jakacena("kia", 2020)), 65989) >)

125 114 Rozdział 3. Niezbędnik programisty Aby uruchomić wszystkie testy z katalogu tests, wystarczy wywołać funkcję test() z pakietu devtools. Jeżeli test zostanie wykonany bez błędów, wyświetli się jako kropka. Jeżeli w teście wystąpi błąd, wyświetli się informacja o tym, co to za test. I poniżej przykład takiego działania: library(devtools) test(„kuppanauto”) Loading kuppanauto Testing kuppanauto Error: Result is a number could not find function „jakacena” I believe in you! Swoiste testy wykonywane są również przy przyjęciu pakietu do publicznych repozytoriów. Np. aby pakiet został przyjęty do CRAN, nie wystarczy, że funkcje działają poprawnie. Pakiet musi spełniać listę określonych warunków dotyczących formatowania (tzw. Camel Case dla tytułów, niezbyt długie linie, poprawna dokumentacja, wykonywalne przykłady) czy spójności opisu. Do weryfikacji, czy pakiet jest zgodny z wszystkimi wymogami, można wykorzystać funkcję check(). check(„kuppanauto”) ## Updating kuppanauto documentation ## Loading kuppanauto ##. ## * checking dependencies in R code. OK ## * checking S3 generic/method consistency. OK ## * checking replacement functions. OK ## * checking foreign function calls. OK ## * checking R code for possible problems. NOTE ## * checking Rd files. WARNING ## * checking Rd metadata. OK ## * checking Rd line widths. OK ## * checking Rd cross-references. OK ## * checking Rd \usage sections. OK ## * checking Rd contents. OK ## * checking examples. NONE ## * DONE Wszystko, co nie jest oznaczone jako OK, należy poprawić.

126 3.4 Budowanie własnych pakietów Jak budować stworzony pakiet Cykl życia pakietu składa się z kilku kroków: 1. Funkcje i zbiory danych do pakietu są dostępne jako katalog na dysku twórcy. 2. Funkcje, zbiory danych i ich dokumentacja w formacie Rd są dostępne jako katalog na dysku twórcy. 3. Pakiet jest dostępny jako plik źródłowy tar.gz lub binarny zip/tgz. 4. Pakiet jest zainstalowany na komputerze, a więc znajduje się w katalogu z bibliotekami. 5. Pakiet włączony w aktualnej sesji R. Opisy z poprzednich rozdziałów pozwalają na zbudowanie pakietu w stanie z punktu 1. Poniżej pokazujemy, jak przejść do kolejnych kroków Budowanie dokumentacji (-> 2.) W rozdziale pisaliśmy o tym, jak dodawać dokumentację do funkcji i zbiorów danych w pakiecie. Aby zamienić tak przygotowany opis w dokumentację w formacie Rd, należy użyć funkcji document() z pakietu devtools. Tworzy ona pliki Rd w katalogu man na podstawie opisów roxygen oraz uzupełnia plik NAMESPACE. document(„kuppanauto”) ## Updating kuppanauto documentation ## Loading kuppanauto ## First time using roxygen Upgrading automatically Budowanie pakietu do postaci źródłowej (-> 3.) Aby zbudować katalog z wszystkimi częściami pakietu do jednego pliku postaci źródłowej pakietu, należy wykorzystać funkcję build() z pakietu devtools. Parametrem funkcji build() jest katalog, w którym znajduje się pakiet do zbudowania. Domyślnie jest to aktualny katalog roboczy. Poniższa instrukcja stworzy plik źródłowy kuppanauto_ tar.gz (do nazwy pakietu dodawany jest automatycznie numer wersji) z zawartością pakietu: build(„kuppanauto”) ## /Library/Frameworks/R.framework/Resources/bin/R \ ## –no-site-file –no-environ –no-save \ ## –no-restore CMD build \ ## /Users/pbiecek/GitHub/Przewodnik/inne/kupPanAuto \ ## –no-resave-data –no-manual ##

127 116 Rozdział 3. Niezbędnik programisty ## * checking for file /Users/pbiecek/GitHub/Przewodnik/inne/ kuppanauto/ DESCRIPTION. OK ## * preparing kuppanauto: ## * checking DESCRIPTION meta-information. OK ## * checking for LF line-endings in source and make files ## * checking for empty or unneeded directories ## * building kuppanauto_ tar. gz ## ## [1] „/Users/pbiecek/GitHub/Przewodnik/inne/kupPanAuto_ tar.gz” Instalacja pakietu (-> 4.) Pakiety instalowane są w katalogu z bibliotekami R. Ścieżkę do tych katalogów można odczytać przy użyciu funkcji.libpaths():.libpaths() ## [1] „/Library/Frameworks/R.framework/Versions/3.2/Resources/ library” Aby zainstalować pakiet z pliku źródłowego lub z katalogu, można wykorzystać polecenie install(). Parametrem funkcji install() jest katalog, w którym znajduje się pakiet do zbudowania. Domyślnie jest to katalog roboczy. install(„kuppanauto”) ## Installing kuppanauto ## /Library/Frameworks/R.framework/Resources/bin/R –no-site-file –no-environ –no-save –no-restore CMD \ ## INSTALL /Users/pbiecek/GitHub/Przewodnik/inne/kupPanAuto \ ## –library= /Library/Frameworks/R.framework/Versions/3.2/ Resources/library –install-tests ## ## * installing *source* package kuppanauto. ## ** R ## ** preparing package for lazy loading ## ** help ## *** installing help indices ## ** building package indices ## ** testing if installed package can be loaded ## * DONE (kuppanauto) Poleceniem install.packages() można instalować pakiety z repozytorium CRAN, a poleceniem install_github() z repozytoriów GitHub. Poniższa instrukcja zainstaluje pakiet proton ze strony install_github(„betaandbit/pieczarapietraszki/protoneng”)

128 3.5 Git, GitHub i kontrola wersji Włączanie pakietu (-> 5.) Aby skorzystać z danych lub funkcji pakietu, należy go włączyć poleceniem require() lub library(). Ewentualnie można wykorzystać operator dostępu :: (lub . w przypadku funkcji, które nie są publiczne). library(„kuppanauto”) 3.5. Git, GitHub i kontrola wersji W tym podrozdziale omawiamy narzędzia pozwalające na wersjonowanie kodu, w szczególności oparte na systemie Git. Jest wiele powodów, dla których warto je poznać i stosować, wymieńmy cztery. System kontroli kodu pozwala na śledzenie wszystkich zmian w kodzie. Jeżeli okaże się, że pewne zmiany trzeba jednak wycofać, to zawsze jest możliwość powrotu stanu kodu do określonego punktu w przeszłości. W przypadku pracy w zespole można zawsze sprawdzić, kto wprowadził jakie zmiany. Gdyby trzeba było później ten kod poprawić, wiadomo, kogo o to zapytać. W przypadku awarii jednego komputera lub pracy na kilku komputerach dostępność repozytorium pozwala odtworzyć kod z kopii. Bardzo często nowe pakiety są umieszczane i instalowane z repozytoriów Git. W porównaniu z repozytorium CRAN daje to większą swobodę w aktualizacji kolejnych wersji pakietów. Jednym z najpopularniejszych systemów kontroli wersji jest Git. Dzięki serwisowi GitHub można z niego korzystać bezpłatnie, o ile godzimy się na niewielkie ograniczenia. Na stronie można utworzyć nowego użytkownika, jak również stworzyć nowe repozytorium z kodem. Po utworzeniu nowego repozytorium będzie ono pełniło funkcję centralnego zdalnego repozytorium Jak kopiować repozytorium clone Kod zazwyczaj jest rozwijany na lokalnym komputerze. Pierwszym krokiem, by rozpocząć pracę nad kodem, jest utworzenie na lokalnym komputerze kopii zdalnego repozytorium. Obsługa systemu Git jest znacznie uproszczona dzięki programowi RStudio. Operację kopiowania repozytorium najłatwiej przeprowadzić, wybierając w menu New project. /version control. Pojawi się okno jak na rysunku 3.10, w którym można określić parametry globalnego repozytorium do klonowania.

129 118 Rozdział 3. Niezbędnik programisty Na dysku zostanie utworzona kopia repozytorium we wskazanym katalogu. Na tej kopii możemy teraz pracować, modyfikując, dodając i usuwając z niej pliki. Rysunek Okno programu RStudio z parametrami do kopiowania repozytorium ze zdalnego serwera git. W tym przypadku kopiowane jest repozytorium PrzewodnikParkiet z GitHuba Rysunek Okno programu RStudio z zaznaczonymi plikami do dodania zmian (prawy górny panel)

Najlepsi brokerzy opcji binarnych 2020:
  • Binarium
    Binarium

    1 miejsce w rankingu! Najlepszy wybor dla poczatkujacego!
    Bezplatne konto szkoleniowe i demo!
    Bonus za rejestracje!

  • FinMax
    FinMax

    Uczciwy i niezawodny broker! Dobre recenzje!

Like this post? Please share to your friends:
Jak zarabiać na opcjach binarnych?

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: