Biecek R Basics

User Manual: Biecek-R-basics

Open the PDF directly: View PDF PDF.
Page Count: 82

DownloadBiecek-R-basics
Open PDF In BrowserView PDF
●

●

●

●

●
●
●

PRZEMYSŁAW BIECEK

Przewodnik po pakiecie

1.6

R

V

V

użytkownika

1.4

1.2

dla żółtodziobów
dla zawodowców

V

problemu

dla pasjonatów

V

użytkownika

problemu

1.0

0.8

●

●

●

●
●

0.2

●

●
●
●●
●
●
●

ANALIZA DANYCH

●●
●

●
●
●

●
●

STATYSTYKA

●

●

●

● ●●

●
●

GRAFIKA

PROGRAMOWANIE

●

●
●
●

●

6

●
●
●

●
●
●
●
● ●●
● ●

●

x

●

●

●

●

2

●

2

●

●

●● ●

y=1−

●
●
●
●●

●

x
x
1−
1−
y=

● ●●
●

●

●●
●

y=

●

6

●

●

x

●

x
x
1−
1−
y=

●
●

●

y=

●

●

0.4

y=1−

●

0.6

Recenzent
Dr hab. Jan Mielniczuk
Instytut Podstaw Informatyki PAN
Projekt okładki i skład
Przemysław Biecek
Wnioski, skargi i zażalenia kierować do
Przemysław Biecek
http://www.biecek.pl
Instytut Matematyczny Polskiej Akademii Nauk
Zakład Genomiki Wydziału Biotechnologii Uniwersytetu Wrocławskiego

Książka została przygotowana, aby ułatwić poznanie i codzienna pracę
z pakietem R. Przyda się ona tym wszystkim, którzy w pracy lub w szkole
zajmują się analizą danych. Książka może być wykorzystana, jako pomoc
w nauce pakietu R. Może być również wykorzystana, jako encyklopedyczna
ściągawka przydatna w codziennej pracy z tym pakietem.
Pod adresem http://www.biecek.pl/R/ czytelnik znajdzie dodatkowe informacje
o książce, rozwiązania zadań umieszczonych w tej książce, oraz odnośniki do
innych materiałów wspomagających naukę pakietu R.
Osoby zainteresowane zakupem książki powinny skontaktować się z autorem.

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 zgody wydawcy.

© Copyright by Przemysław Biecek
Wrocław 2008

Spis treści
Przeczytaj zanim kupisz

ix

1 Łagodne wprowadzenie do R
1.1 Jak korzystać z tej książki? . . . . . . . . . . . .
1.2 Słów kilka o projekcie R . . . . . . . . . . . . . .
1.3 Instalacja . . . . . . . . . . . . . . . . . . . . . .
1.3.1 Instalacja środowiska . . . . . . . . . . . .
1.3.2 Instalacja i ładowanie pakietów . . . . . .
1.4 EdytoR . . . . . . . . . . . . . . . . . . . . . . .
1.5 Startujemy . . . . . . . . . . . . . . . . . . . . . .
1.5.1 Pierwsze uruchomienie . . . . . . . . . . .
1.5.2 Przegląd opcji w menu . . . . . . . . . . .
1.5.3 Gdzie szukać pomocy? . . . . . . . . . . .
1.5.4 kalkuRator . . . . . . . . . . . . . . . . .
1.5.5 Kilka przykładowych sesji w R . . . . . . .
1.5.6 Podstawy składni języka R . . . . . . . . .
1.5.7 Wyświetlanie i formatowanie obiektów . .
1.6 Przyśpieszamy . . . . . . . . . . . . . . . . . . . .
1.6.1 Instrukcje warunkowe i pętle . . . . . . . .
1.6.2 Funkcje . . . . . . . . . . . . . . . . . . .
1.6.3 Zarządzanie obiektami w przestrzeni nazw
1.6.4 Wprowadzenie do grafiki . . . . . . . . . .
1.6.5 Operacje na plikach i katalogach . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

1
1
2
4
4
5
6
10
10
11
18
20
23
27
39
42
42
47
55
56
59

2 pazuRrry
2.1 Typy zmiennych i operacje
2.1.1 Typ czynnikowy . .
2.1.2 Wektory . . . . . .
2.1.3 Listy . . . . . . . .
2.1.4 Ramki danych . . .
2.1.5 Macierze . . . . . .
2.1.6 Obiekty . . . . . .
2.1.7 Klasy . . . . . . .

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

63
63
63
67
70
72
74
81
82

na nich
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .

iii

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

iv

Spis treści

2.2
2.3

2.4
2.5

2.6

2.1.8 Formuły . . . . . . . . . . . . . . . . . . . . . . . . . .
2.1.9 Leniwa ewaluacja . . . . . . . . . . . . . . . . . . . . .
Tryb wsadowy . . . . . . . . . . . . . . . . . . . . . . . . . . .
Operacje wejścia/wyjścia (zapisywanie i odczytywanie danych)
2.3.1 Pliki . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3.2 Zapisywanie grafiki . . . . . . . . . . . . . . . . . . . .
2.3.3 Inne sposoby odczytywania i zapisywania danych . . .
2.3.4 Baza danych . . . . . . . . . . . . . . . . . . . . . . . .
Programowanie objaśniające i Sweave . . . . . . . . . . . . . .
Debugger i profiler . . . . . . . . . . . . . . . . . . . . . . . .
2.5.1 Debugger . . . . . . . . . . . . . . . . . . . . . . . . .
2.5.2 Profiler . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5.3 Inne przydatne funkcje systemowe . . . . . . . . . . . .
2.5.4 Obiekty wywołań funkcji . . . . . . . . . . . . . . . . .
Wybrane funkcje matematyczne . . . . . . . . . . . . . . . . .
2.6.1 Wielomiany . . . . . . . . . . . . . . . . . . . . . . . .
2.6.2 Bazy wielomianów ortogonalnych . . . . . . . . . . . .
2.6.3 Funkcje Bessela . . . . . . . . . . . . . . . . . . . . . .
2.6.4 Operacje na zbiorach . . . . . . . . . . . . . . . . . . .
2.6.5 Szukanie maksimum/minimum/zer funkcji . . . . . . .
2.6.6 Rachunek różniczkowo–całkowy . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

85
86
88
89
89
99
101
103
104
109
109
114
116
117
118
118
119
121
121
122
123

3 Wybrane procedury statystyczne
124
3.1 Statystyki opisowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
3.1.1 Liczbowe statystyki opisowe . . . . . . . . . . . . . . . . . . . 125
3.1.2 Graficzne statystyki opisowe . . . . . . . . . . . . . . . . . . . 129
3.2 Liczby losowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
3.2.1 Generatory liczb losowych . . . . . . . . . . . . . . . . . . . . 138
3.2.2 Popularne rozkłady zmiennych losowych . . . . . . . . . . . . 140
3.3 Przetwarzanie wstępne . . . . . . . . . . . . . . . . . . . . . . . . . . 146
3.3.1 Brakujące obserwacje . . . . . . . . . . . . . . . . . . . . . . . 146
3.3.2 Normalizacja, skalowanie i transformacje nieliniowe . . . . . . 149
3.4 ANOVA, regresja liniowa i logistyczna . . . . . . . . . . . . . . . . . 153
3.4.1 Analiza wariancji . . . . . . . . . . . . . . . . . . . . . . . . . 154
3.4.2 Analiza jednoczynnikowa . . . . . . . . . . . . . . . . . . . . . 154
3.4.3 Analiza wielokierunkowa . . . . . . . . . . . . . . . . . . . . . 163
3.4.4 Regresja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
3.4.5 Regresja logistyczna . . . . . . . . . . . . . . . . . . . . . . . 182
3.5 Testowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
3.5.1 Testowanie zgodności . . . . . . . . . . . . . . . . . . . . . . . 198
3.5.2 Testowanie hipotezy o równości parametrów położenia . . . . 205
3.5.3 Testowanie hipotezy o równości parametrów skali . . . . . . . 209
3.5.4 Testowanie hipotez dotyczących prawdopodobieństwa sukcesu 211
3.5.5 Testy istotności dla wybranych współczynników zależności pomiędzy dwoma zmiennymi . . . . . . . . . . . . . . . . . . . . 213
3.5.6 Testowanie zbioru hipotez . . . . . . . . . . . . . . . . . . . . 222

Spis treści
3.6
3.7

Bootstrap . . . . . . . . . . . . . . . . . . . . . . .
3.6.1 Ocena rozkładu oraz przedziałów ufności dla
3.6.2 Testowanie hipotez . . . . . . . . . . . . . .
Analiza przeżycia . . . . . . . . . . . . . . . . . . .
3.7.1 Krzywa przeżycia Kaplana-Meyera . . . . .
3.7.2 Model Coxa . . . . . . . . . . . . . . . . . .

. . . . . . .
estymatora
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .

4 gRrrafika
4.1 Funkcje graficzne . . . . . . . . . . . . . . . . . . . . . .
4.1.1 Wykres paskowy . . . . . . . . . . . . . . . . . .
4.1.2 Dwuwymiarowy histogram . . . . . . . . . . . . .
4.1.3 Wykres róża wiatrów . . . . . . . . . . . . . . . .
4.1.4 Wykres słonecznikowy . . . . . . . . . . . . . . .
4.1.5 Trójwymiarowy wykres rozrzutu . . . . . . . . . .
4.1.6 Wykres kołowy . . . . . . . . . . . . . . . . . . .
4.1.7 Wykres słupkowy . . . . . . . . . . . . . . . . . .
4.1.8 Wykres kropkowy . . . . . . . . . . . . . . . . . .
4.1.9 Wykres otoczkowy . . . . . . . . . . . . . . . . .
4.1.10 Wykres torbowy . . . . . . . . . . . . . . . . . .
4.1.11 Wykresy rozrzutu . . . . . . . . . . . . . . . . . .
4.1.12 Warunkowe wykresy rozrzutu . . . . . . . . . . .
4.1.13 Macierze korelacji . . . . . . . . . . . . . . . . . .
4.1.14 Kwantyle wielowymiarowego rozkładu normalnego
4.1.15 Wykresy diagnostyczne . . . . . . . . . . . . . . .
4.1.16 Wykres koniczyny . . . . . . . . . . . . . . . . . .
4.1.17 Wielowymiarowy, jądrowy estymator gęstości . .
4.1.18 Wykresy konturowe . . . . . . . . . . . . . . . . .
4.1.19 Mapa ciepła . . . . . . . . . . . . . . . . . . . . .
4.1.20 Wykres zmian . . . . . . . . . . . . . . . . . . . .
4.1.21 Interaktywna grafika z pakietem iplots . . . . . .
4.1.22 Wykres radarowy i twarze Chernoffa . . . . . . .
4.2 Dla tych którym wciąż mało . . . . . . . . . . . . . . . .
4.3 Pełna kontrola . . . . . . . . . . . . . . . . . . . . . . . .
4.3.1 Funkcja plot() . . . . . . . . . . . . . . . . . . . .
4.3.2 Rysowanie zbioru wykresów . . . . . . . . . . . .
4.3.3 Grafiki . . . . . . . . . . . . . . . . . . . . . . . .
4.3.4 Rysowanie osi . . . . . . . . . . . . . . . . . . . .
4.3.5 Legenda wykresu . . . . . . . . . . . . . . . . . .
4.3.6 Wyrażenia matematyczne . . . . . . . . . . . . .
4.3.7 Kolory . . . . . . . . . . . . . . . . . . . . . . . .
4.3.8 Właściwości linii . . . . . . . . . . . . . . . . . .
4.3.9 Właściwości punktów/symboli . . . . . . . . . . .
4.3.10 Atomowe funkcje graficzne . . . . . . . . . . . . .
4.3.11 Interaktywne odczytywanie wartości z ekranu . .
4.3.12 Elementy wykresu . . . . . . . . . . . . . . . . .
4.3.13 Wiele wykresów na ekranie/na jednym rysunku .
4.3.14 Parametry funkcji graficznej par() . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

224
225
227
228
229
231

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

234
. 234
. 234
. 235
. 235
. 236
. 236
. 238
. 238
. 239
. 240
. 240
. 240
. 242
. 242
. 243
. 243
. 243
. 244
. 244
. 246
. 247
. 247
. 250
. 250
. 252
. 252
. 252
. 253
. 255
. 256
. 257
. 257
. 258
. 259
. 260
. 261
. 262
. 263
. 264

v

vi

Spis treści
Zbiory
4.4
4.5
4.6

danych
Zbiór danych daneO . . . . . . . . . . . . . . . . . . . . . . . . . .
Zbiór danych mieszkania . . . . . . . . . . . . . . . . . . . . . . . .
Zbiór danych daneSoc . . . . . . . . . . . . . . . . . . . . . . . . .

273
. 273
. 274
. 274

Zadania

275

Bibliografia

283

Skorowidz

285

Przeczytaj zanim kupisz
Szanowny Czytelniku, trzymasz właśnie w ręku książkę od początku do końca poświęconą pakietowi R. Książka ta powstała po to, by zaprezentować szeroki wachlarz
możliwości pakietu R i ułatwić poznanie jego prostych i zaawansowanych aspektów.
W sposób systematyczny przedstawia język R, na licznych przykładach opisuje podstawowe funkcje, prezentuje przydatne biblioteki dostępne w tym środowisku, opisuje
popularne procedury statystyczne oraz funkcje do tworzenia grafiki.
Pozycja ta zaczęła powstawać w roku 2006, zaczynając jako materiały pomocnicze dla moich studentów dzielnie poznających tajniki statystyki i analizy danych.
Została rozbudowana i uzupełniona, aby mogła z niej skorzystać szersza grupa odbiorców. Starałem się wybrać materiał tak, by tę książkę chciały przeczytać:
• osoby, które chcą poznać pakiet R od podstaw, słyszały że warto i szukają
łagodnego wprowadzenia dla zupełnych laików,
• osoby korzystające już z R, znające podstawy i chcące swoją wiedzę usystematyzować, uzupełnić, rozszerzyć, pogłębić,
• osoby pracujące z R na co dzień (eksperci), szukające podręcznej ściągawki
(trudno spamiętać nazwy wszystkich argumentów graficznych) lub też chcące
upewnić się, że o R wiedzą już (prawie) wszystko.
Innymi słowy, mam nadzieje, że każdy znajdzie tu coś dla siebie.
Książka podzielona jest na cztery części. Pierwsza część, to skrótowe przedstawienie możliwości pakietu R. Rozpoczyna się od wprowadzenia dla zupełnych nowicjuszy, ale w miarę upływu stron przedstawiane są kolejne, coraz bardziej zaawansowane
informacje o języku oraz pakiecie R. Ta część jest przygotowana z myślą o osobach
początkujących i o osobach chcących swoją wiedzę o R uzupełnić. Nie jest zakładana jakiejkolwiek wstępna wiedza o pakiecie R. Zaczynamy od podstaw, ale jestem
pewien, że również spore grono zaawansowanych użytkowników znajdzie tutaj coś
nowego. Dlatego warto przejrzeć tę część bez względu na stopień zaawansowania.
Kolejne części mają charakter encyklopedyczny i można je czytać w dowolnej kolejności. Część druga „pazuRrry” przedstawia możliwości języka R, o których warto
wiedzieć i z których warto korzystać, a które nie znalazły się w innych częściach.
Najsilniejszą stroną R jest potężne wsparcie dla szeroko pojętych analiz statystycznych. W części trzeciej pt. „Wybrane procedury statystyczne” przedstawiono listę funkcji statystycznych wykorzystywanych przy najpopularniejszych procedurach
statystycznych wraz z informacją, jak z tych funkcji korzystać i jak interpretować ich
wyniki. Pakiet R świetnie nadaje się do tworzenia dobrze wyglądających rysunków,
dlatego część czwarta „gRrrafika” poświęcona jest mechanizmom R umożliwiającym
tworzenie i modyfikacje dobrze wyglądających wykresów (zarówno podstawowych
jak i bardzo wymyślnych), schematów, grafik itp. Część czwarta kończy się prezenvii

viii

Przeczytaj zanim kupisz
tacją funkcji i argumentów graficznych, dzięki którym użytkownik ma pełną kontrolę
nad tym co, jak i gdzie jest rysowane.
Pakiet R rozwija się dynamicznie i nieustannie. Ma tak wiele możliwości, że nie
sposób wszystkich opisać. Dołożyłem wszelkich starań, by ta pozycja była zrozumiała dla początkujących użytkowników i ciekawa dla użytkowników zaawansowanych. Będę zobowiązany czytelnikom za wszelkie uwagi i komentarze, które pozwolą
uczynić tę pozycję czytelniejszą lub ciekawszą zarówno te dotyczące zawartości jak
i te dotyczące formy. Pod adresem http://www.biecek.pl/R/R.pdf znajdują się
(w postaci elektronicznej) pierwsze 64 strony tej książki. Jest to, mam nadzieję,
wystarczający fragment, by przekonać czytelnika, że warto bliżej zapoznać się z pakietem R. Ten fragment może być drukowany i kopiowany na użytek własny. Mam
nadzieje, że pomoże on wielu osobom w pierwszym kontakcie z R, a także zachęci
do nabycia całej książki w postaci drukowanej.
Książka ta mogła powstać wyłączenie dzięki mniejszej i większej pomocy bardzo
wielu osób, którym serdecznie dziękuję. Szczególnie gorąco dziękuję żonie Karolinie
za jej wsparcie, wyrozumiałość, wytrwałość przy wielokrotnym czytaniu kolejnych
wersji i moc cennych uwag. Wiele cennych wskazówek, sugestii, propozycji i uwag
do kolejnych wersji otrzymałem od prof. dra hab. Jana Mielniczuka, za co serdecznie
mu dziękuję. Za cenne uwagi merytoryczne chciałbym też podziękować dr Janowi
Ćwikowi i dr hab. Pawłowi Mackiewiczowi a również Grzegorzowi Hermanowiczowi
i moim studentom, którzy czasem dzielili się uwagami czy wątpliwościami. Za pomoc
przy wydawaniu tej książki chcę podziękować prof. dr hab. Jackowi Koronackiemu.
Korzystając z okazji dziękuję moim wieloletnim współpracownikom dr inż. Adamowi Zagdańskiemu i dr inż. Arturowi Suchwałce za „zarażenie” mnie pakietem R
i za wiele wspólnie realizowanych projektów wykonanych w R i nie tylko. Specjalne
podziękowania składam również moim przełożonym: prof. dr hab. Teresie Ledwinie
i prof. dr hab. Stanisławowi Cebratowi za pozostawienie mi swobody w wyborze
zadań do realizacji.
To tyle tytułem wstępu. Życzę owocnej pracy oraz wielu sukcesów w pracy z użyciem pakietu R.
Przemysław Biecek, Wrocław 2008

Rozdział 1
Łagodne wprowadzenie do R
1.1

Jak korzystać z tej książki?

Aby ułatwić wyszukiwanie informacji, pewne fragmenty tekstu zostały wyróżnione. Kod w języku R oraz przykłady wyników wykonania podanych instrukcji będą
przedstawiane w następujących ramkach:
# komentarz: mój pierwszy program
for (i in 1:10) {
cat("Hello world !!!\n")
}

Czasem tak bywa, że aż się prosi o komentarz do tekstu, nawet jeżeli nie jest to
komentarz merytoryczny. Takie komentarze będą umieszczane na marginesie. Część
z zamieszczonych na marginesie komentarzy to wybrane cytaty znanych użytkowników R. Te i więcej cytatów znaleźć można w pakiecie fortunes.
Fragmenty tekstu zasługujące na szczególną uwagę oraz komentarze do przedstawianego zagadnienia będą oznaczane krzywą opisaną równaniem w układzie biegunowym G = {(ρ, φ) : ρ = 1 + 1/|φ|, −π ¬ φ ¬ π} (przykład poniżej):

!!

!!

!!!

Pamiętaj, żeby nie wychodzić z mokrą głową, gdy wieje silny wiatr!

Odnośniki do interesujących pozycji (zarówno w postaci papierowej jak i elektronicznej) zostały zgromadzone na końcu tej książki. Do pozycji literaturowych
będziemy odnosili się następująco: [1].
Przy nauce nowych rzeczy bardzo przydatne są zadania, które można samodzielnie rozwiązać. Tak jest też w przypadku pakietu R, dlatego do każdego rozdziału
przygotowana została lista zadań weryfikujących zdobytą wiedzę. Zadania umieszczone są w ostatnim załączniku, pliki z przykładowymi odpowiedziami znajduje się
w Internecie pod adresem http:\\www.biecek.pl\R\. Pod tym adresem umieszczane będą również dodatkowe materiały ułatwiające poznawanie pakietu R.
1

Tym też sposobem
kultowy przykład
z „Hello world”
mamy już za sobą.

Autor żyje w świecie
liczb, wybaczcie mu
brak poczucia
humoru. Przyp.
żony.

2

Łagodne wprowadzenie do R

1.2

R is the lingua
franca of statistical
research. Work in all
other languages
should be
discouraged.
Jan de Leeuw
fortune(78)

Overall, SAS is
about 11 years
behind R and
S-Plus in statistical
capabilities (last
year it was about 10
years behind) in my
estimation.
Frank Harrell (SAS
User, 1969-1991)
fortune(10)

Słów kilka o projekcie R

R to zarówno nazwa języka programowania, nazwa platformy programistycznej wyposażonej w interpretator tego języka oraz nazwa projektu, w ramach którego rozwijany jest zarówno język jak i środowisko. W dalszej części książki będziemy korzystali
z nazwy R, mając na myśli tak język programowania, platformę programistyczną jak
i zbiór bibliotek (pakietów), w które wyposażona jest ta platforma.
R jest często nazywany pakietem statystycznym. Jest tak z uwagi na olbrzymią
liczbę dostępnych funkcji statystycznych. Możliwości R są jednak znacznie większe. W Internecie można znaleźć przykłady wykorzystania R do automatycznego
generowania raportów, wysyłania maili, rysowania fraktali, czy renderowania trójwymiarowych animacji. W tej książce skupimy się wyłącznie na najpopularniejszych
możliwościach R. Jednak czytelnik, który dobrze pozna przedstawione w tej książce podstawy, z pewnością nie będzie miał żadnych problemów przy opanowywaniu
kolejnych pakietów.
Pierwsza wersja R została napisana przez Roberta Gentlemana i Ross Ihake
(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 nazywanych core team. W zespole tym byli 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 aktualnie rozwojem R kieruje
fundacja „The R Foundation for Statistical Computing” z dziesiątkami aktywnych
uczestników. Ponadto w rozwój R mają wkład setki osób z całego świata publikujące
własne biblioteki najróżniejszych funkcji z bardzo różnych dziedzin.
Język R był wzorowany na języku S, który został opracowany w laboratoriach
Bell’a. Z tego też powodu język R jest podobny do języka S. Programy w S działają
pod R lub można je prosto zmodyfikować tak, by działały. Wiele funkcji w R ma
dodatkowe argumenty dodane po to, by zapewnić zgodność z S. Dzięki temu, że
języki R i S są do siebie podobne możemy wykorzystywać liczne książki do pakietu
S do nauki języka R jak i do poznania dostępnych funkcji statystycznych. Bardzo
dobrą książką do nauki języka S jest książka Johna Chambersa [6] a do nauki funkcji
statystycznych w pakiecie S polecam pozycję Briana Everitta [3]. Uzupełnieniem do
pozycji literaturowych jest olbrzymia liczba stron internetowych oraz dokumentów
elektronicznych szczegółowo przedstawiających rozmaite aspekty R. Pod koniec roku 2007 ukazała się bardzo obszerna i godna polecenia książka Michaela Crawleya
[4] przedstawiająca zarówno język R jak i wiele procedur statystycznych zaimplementowanych w R. Pojawiają się też i będą się pojawiały liczne książki poświęcone
wybranym aspektom pakietu R, jak np. świetna pozycja przygotowana przez Paula
Murrella poświęcona grafice [33], książka autorstwa Juliana Farawaya poświęcona
modelom liniowym [22], czy kolejna pozycja Briana Everitta przedstawiająca podstawowe koncepty statystyki [21].
Przejście z języka S na język R jest bardzo proste. Również osoby korzystające
z innych platform statystycznych takich jak Matlab, Octave, SPSS, SAS itp. nie
będą miały większych problemów z przestawieniem się na pakiet R. Istnieje wiele
dokumentów przedstawiających różnice pomiędzy danym językiem a R oraz zawierających rady dla użytkowników innych pakietów jak szybko zacząć korzystać z R.
Listę wielu przydatnych rad znajdziemy pod adresem [2].

Słów kilka o projekcie R
R jest projektem GNU opartym o licencje GNU GPL. W uproszczeniu oznacza
to, iż jest w zupełności darmowy zarówno do zastosowań edukacyjnych jak i biznesowych. Więcej o licencji GNU GPL można przeczytać pod adresem [5]. Platforma
R wyposażona jest w świetną dokumentację, dostępną w postaci dokumentów pdf,
dokumentów chm lub stron html. Aktualnie dokumentacja ta jest angielskojęzyczna,
jednak trwają prace nad różnymi lokalizacjami.
Język R jest językiem interpretowanym a nie kompilowanym. Korzystanie z R sprowadza się do podania ciągu komend, które mają zostać wykonane. Kolejne komendy
mogą być wprowadzane linia po linii z klawiatury lub też mogą być wykonywane
jako skrypt (czyli plik tekstowy z zapisaną listą komend do wykonania). Skrypty
można wykonywać niezależnie od platformy sprzętowej. Wiele osób uważa (często
słusznie), że języki interpretowane są wolne i wymagają dużo pamięci, jednak obecne możliwości komputerów pozwalają w standardowych zastosowaniach zupełnie się
tym nie przejmować.
Osoby, które nie chcą pamiętać składni komend R mogą skorzystać z istniejących
nakładek i GUI. Przykładowo, korzystając z okienkowego interfejsu pakietu Rcmdr
można wyklikać wiele różnych procedur statystycznych, podsumowań i wykresów.
Zdecydowanie jednak zachęcam takie osoby do przełamania niechęci do pamiętania
i wpisywania komend. Naprawdę warto samodzielnie przygotowywać i modyfikować
skrypty! Po pewnym czasie staje się to proste i umożliwia dużą automatyzację pracy
oraz znaczne zaoszczędzenie czasu.
Pierwszy podrozdział zakończę przedstawieniem czterech głównych (ale nie jedynych) zalet platformy R. Dzięki tym zaletom deklasuje ona konkurencję.

3

Programy napisane
w językach takich
jak C, C++, Pascal
itp. można
kompilować.
Programy
skompilowane do
rozkazów
rozumianych
bezpośrednio przez
procesor są z reguły
szybsze, ale
programy z reguły
trudniej napisać
i trwa to dłużej.
Języki
interpretowane
(skryptowe) nadają
się świetnie do
szybkiego pisania
programów,
w sytuacji, gdy czas
wykonania nie jest
kluczowy.
GUI to skrót od
ang. Graphical User
Interface, czyli
graficznego
interfejsu
użytkownika.

• R pozwala na tworzenie i upowszechnianie pakietów zawierających nowe funkcjonalności. Obecnie dostępnych jest blisko 1000 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 popularnie wykorzystywanymi w psychometrii, geoR z funkcjami geostatystycznymi, Sweave do generowania raportów w języku LATEX
i wiele, wiele innych. Każdy możne napisać swój własny pakiet i udostępnić go
dla innych.
• R pozwala na wykonywanie funkcji z bibliotek dostępnych w innych językach
(C, C++, Fortran) oraz na wykonywanie funkcji dostępnych w R z poziomu
innych języków (Java, C, C++ 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.
• 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 darmowych i dostępnych w ramach licencji GNU GPL lub GNU GPL 2.0.
• W R można wykonać wykresy o wysokiej jakości, co jest bardzo istotne przy
prezentacji wyników. Wykresy te już na pierwszy rzut oka wyglądają lepiej
od tych przygotowanych w innych pakietach.
Jedną z niewielu rzeczy których nie można zrobić na platformie R jest cappucino.

Panie, takie rzeczy
to tylko w eRze

4

Łagodne wprowadzenie do R

1.3

Instalacja

Instalacja pakietu R składa się z dwóch etapów. Pierwszy, to zainstalowanie podstawowego środowiska (tzw. base) wraz z podstawowymi bibliotekami. Ten podstawowy
zestaw już 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ń. Drugi etap,
to uzupełnianie wersji podstawowej przez doinstalowanie pakietów z przydatnymi
funkcjami. Aktualnie dostępnych jest około tysiąca pakietów! Nie ma jednak potrzeby instalowania wszystkich od razu. Z reguły w miarę używania okazuje się, że
przydałaby się nam jakaś dodatkowa funkcja, która jest już dostępna w pewnym
pakiecie i dopiero wtedy warto taki pakiet doinstalować.
Poniżej znajduje się krótka informacja jak łatwo przebrnąć przez oba etapy instalacji.

1.3.1

Instalacja środowiska

Dla większości systemów operacyjnych, w tym wszystkich dystrybucji Linuxa, Unixa,
dla wersji Windowsa począwszy od Windowsa 95 a nawet dla MacOSa, pakiet R jest
dostępny w postaci źródłowej oraz skompilowanej. Łatwiej oczywiście zainstalować R
korzystając ze skompilowanego pliku instalacyjnego. Instalacja jest prosta, wystarczy
wybrać jeden z serwerów mirror, na którym umieszczony jest plik instalacyjny,
ściągnąć ten plik, uruchomić go a następnie postępować zgodnie z instrukcjami.
Adresy mirrorów z kopiami plików instalacyjnych pakietu R znaleźć można pod
adresem http://cran.r-project.org/mirrors.html). W większości przypadków
najszybciej ściągniemy pakiet z jednego z polskich mirrorów.
Szczegółową instrukcję instalacji można znaleźć pod adresem [8], przyda się ona
osobom chcącym zainstalować nietypową konfigurację R. W dalszej części będzie opisywana wersja pakietu R przygotowana dla systemu Windows. Jej najnowszą wersję
(na dzień dzisiejszy 2.7.1) można ściągnąć np. z wrocławskiego serwera [7]. Aby przystąpić do instalacji należy uruchomić plik R-2.7.1-win32.exe. Cała instalacja ogranicza się praktycznie do klikania przycisku „Next”. Po zainstalowaniu R utworzy we
wskazanym miejscu (najczęściej będzie to katalog c:/Program Files/R/R-2.7.1)
strukturę podkatalogów z plikami potrzebnymi do działania.
Po instalacji w utworzonej strukturze znajdą się różne podkatalogi. W tym: katalog bin (z plikami wykonywalnymi R), doc (z ogólną dokumentacją R), library
(w którym instalowane są kolejne pakiety) i innymi, mniej ważnymi. Platformę
R można uruchomić w trybie tekstowym (uruchamiając plik R.exe) lub też w trybie
z prostym okienkowym GUI (uruchamiając plik Rgui.exe). Oba pliki do uruchomienia środowiska znajdują się w katalogu bin. Wersja tekstowa może się przydać,
jeżeli w tle chcemy wykonać jakieś większe symulacje i nie potrzebujemy interfejsu
graficznego. Wybór trybu uruchomienia proponujemy oprzeć na prostej zasadzie:
jeżeli nie wiesz czym te tryby się różnią, to uruchom Rgui.exe.

!!

!!!

!!

Mirror to serwer,
w którym znajduje
się dokładna
(lustrzana) kopia
plików. Jeżeli
chcemy ściągnąć
pliki z serwera,
który jest daleko od
naszego komputera
i z którego korzysta
wiele osób to
ściąganie będzie
wolne. Dlatego
warto wybrać serwer
położony możliwie
blisko, o małym
obciążeniu.

Osoby używające platformy R do bardzo wymagających obliczeniowo
analiz powinny raczej używać Linuxowej lub Unixowej wersji R. W tych
systemach operacyjnych zarządzanie pamięcią jest wydajniejsze przez co
R działa (odrobinę) szybciej.

Instalacja
Trudno jest podać minimalne wymagania sprzętowe niezbędne do działania R.
Jeszcze nie zdarzyło mi się nie móc uruchomić tego pakietu na napotkanym komputerze. Można śmiało przyjąć, że 256MB RAM, procesor klasy Pentium lub wyższej
i kilkadziesiąt MB miejsca na dysku twardym w zupełności wystarczą. Do pełnego komfortu przyda się szybszy procesor, 2GB RAM i tyle samo miejsca na dysku
twardym (bioinformatyczne zbiory danych potrafią zajmować bardzo dużo miejsca
na dysku i w RAM).

!!

1.3.2

!!

!!!

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
pendriv lub dysk przenośny i uruchamiać na dowolnym komputerze bez
potrzeby instalacji.

Instalacja i ładowanie pakietów

Jak już pisaliśmy, po zainstalowaniu podstawowego zbioru bibliotek platforma R ma
już spore możliwości. Prawdziwa potęga kryje się w setkach dodatkowych pakietów,
w których znajdują się tysiące różnych funkcji (funkcje w R pogrupowane są w pakietach/bibliotekach). Po uruchomieniu systemu R kolejne pakiety można zainstalować
funkcją install.packages(utils).
# zainstaluj pakiet Rcmdr wraz z wszystkimi pakietami wymaganymi do jego
działania
install.packages("Rcmdr", dependencies = TRUE)

lub też wybierając z menu opcję packages\install package(s).... Przy instalacji
pierwszego pakietu R zapyta z jakiego serwera mirror chcemy skorzystać.
Po zainstalowaniu nowego pakietu, pliki z danymi, funkcjami i plikami pomocy
znajdą się na dysku twardym komputera. Wszystkie pakiety są wgrywane jako podkatalogi do katalogu library. Aby 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(base).
# włącz pakiet Rcmdr
library(Rcmdr)
# gdyby ten pakiet nie był zainstalowany, to pojawiłby się komentarz
# Error in library(Rcmdr) : there is no package called ’Rcmdr’

Jak już pisaliśmy, aktualnie dostępnych jest blisko 1000 pakietów, które możemy
dodatkowo zainstalować. W tym zbiorze trudno czasem odnaleźć pakiet z interesującą nas funkcjonalnością. Dlatego też, przedstawiając nowe funkcje będziemy korzystać z notacji nazwaFunkcji(nazwaPakietu). Tak więc zapis wilcox.test(stats)
będzie oznaczać, iż funkcja wilcox.test() znajduje się w pakiecie stats. Również
w skorowidzu, znajdującym się na końcu książki, dla każdej wymienionej funkcji
określamy w jakim pakiecie jest ona dostępna. Jeżeli znamy nazwę funkcji i chcemy

5

6

Łagodne wprowadzenie do R
dowiedzieć się w jakim pakiecie ta funkcja się znajduje, to możemy skorzystać z funkcji help.search(utils). 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 napiszemy w podrozdziale 1.5.3.
Po załadowaniu odpowiedniego pakietu możemy korzystać z dostępnych w nim
funkcji podając ich nazwę. Możemy też ręcznie 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() (w każdym o innym działaniu). Aby wskazać
z którego pakietu chcemy wybrać funkcję należy użyć operatora ::.
Jeżeli nie użyjemy tego operatora a dojdzie do kolizji nazw to środowisko R zapyta, z którego pakietu chcemy uruchomić daną funkcję. Obie poniższe linie wywołają
funkcję seq() z pakietu base.
# oba wywołania dotyczą funkcji seq() z pakietu base, drugi sposób jest
szczególnie przydatny, gdy występuje kolizja nazw funkcji z różnych
pakietów
seq(10)
base::seq(10)

1.4

EdytoR

Jeżeli wykorzystujemy R do prostych obliczeń, nie piszemy własnych funkcji i nie
zależy nam na powtarzaniu wykonywanych analiz, to możemy komendy wpisywać
bezpośrednio w linii komend R. Jednak przy większych programach lub gdy zależy
nam na możliwości powtarzania analiz potrzebny nam będzie edytor, w którym
będziemy mogli tworzyć i edytować skrypty R.
Do edycji skryptów można wykorzystać dowolny edytor obsługujący pliki tekstowe (począwszy od najprostszego z możliwych, czyli programu Notatnik z systemu
Windows). Po napisaniu skryptu możemy cały kod programu lub jego fragment skopiować do schowka i przekopiować do konsoli R (poprzez schowek, a więc skrótami
klawiszowymi Ctrl-C, Ctrl-V). Oczywiście zamiast Notatnika możemy wykorzystać
dowolny inny edytor, z którym lubimy pracować. Takie rozwiązanie jest wygodne gdy
piszemy krótkie skrypty, wprowadzamy niewielkie zmiany lub gdy korzystamy z R
uruchomionego zdalnie, np. na unixowym serwerze. W takich sytuacjach najczęściej
nie potrzebujemy żadnych specjalistycznych edytorów.
Jeżeli chcemy uruchomić w R cały skrypt z przygotowanym kodem programu, to
zamiast kopiować ten kod przez schowek możemy skorzystać z funkcji source(base).
Ten sam efekt wyklikamy z menu poleceniem File/Source R code.... Jeżeli argumentem funkcji source() będzie ścieżka do pliku, to cały ten plik zostanie wczytany
i wykonany w R. Jeżeli argumentem będzie napis "clipboard", to wykonane zostaną
polecenia znajdujące się w schowku systemowym. Oba te rozwiązania są lepsze niż
wklejanie kodu bezpośrednio do konsoli ponieważ ekran nie jest zaśmiecany wklejanym kodem.
O ile notatnik nie ma żadnego wsparcia do R, to minimalne wsparcie ma wbudowany w RGui edytor. Można go otworzyć poleceniem File/New script z menu

EdytoR

7

Rysunek 1.1: Przykładowe okno wbudowanego edytora RGui. Skrótem Ctrl-R można
wysłać zaznaczony fragment kodu do konsoli R

(otwiera się pusty skrypt), poleceniem File/Open script (otwieramy istniejący
skrypt do edycji) lub funkcją edit(utils). Ten wbudowany edytor ma kilka udogodnień. Przykładowo po zaznaczeniu fragmentu kodu skrótem klawiszowym Ctrl-R
kopiujemy ten fragment kodu (lub aktualną linię kodu, jeżeli nic nie jest zaznaczone) do konsoli R. Typowe okno tego edytora przedstawiamy na rysunku 1.1. Jest to
wygodne narzędzie do tworzenia krótkich programów jak i wprowadzania drobnych
modyfikacji do już napisanych skryptów.
Jeżeli podczas pracy z R zachodzi potrzebna zmodyfikowania wartości jakiegoś
obiektu (np. funkcji lub tabeli danych), to drobne modyfikacje wygodnie jest wykonywać używając funkcji fix(base). Powoduje ona otwarcie okna edytora R z aktualną wartością obiektu będącego argumentem tej funkcji. Po zakończeniu edycji tej
wartości, zamykając okno edytora zmieniana jest również wartość danego obiektu
w środowisku.
Aby wygodnie pracować przy dużych projektach, gdzie kod rozmieszczony jest
w wielu plikach, potrzebujemy lepszego wsparcia do R. Wiele popularnych edytorów zawiera makra lub pliki definicji pozwalające na podstawowe wsparcie, takie
jak np. kolorowanie składni. Osoby używające edytora Emacs z pewnością ucieszy
informacja, że do Emacsa przygotowano wtyczkę pozwalającą na edycje skryptów
R. Wtyczka nazywa się ESS (skrót od Emacs Speaks Statistics), wspiera ona edycję
i uruchamianie skryptów dla wielu pakietów statystycznych w tym tych z rodziny
języka S. Więcej informacji o tej wtyczce można znaleźć pod adresem [9].
Dla programistów programujących w Javie lub C++ dobrym wyborem będzie
platforma Eclipse [10]. Jest to platforma do programowania w Javie, jednak kolejne wersje wspierają też wiele innych języków programowania, a dostępna wtyczka
(plug-in) „StatET” [11] umożliwia wygodną współpracę Eclipse ze środowiskiem R.
Środowisko Eclipse zostało napisane w Javie, dzięki temu można je uruchamiać zarówno pod Linuxem jak i pod Windowsem.
Przykładowe okno edytora Eclipse z zainstalowaną wtyczką StatET przedstawione jest na rysunku 1.2. Co może być przydatne w Eclipse możemy mieć jednocześnie
otwarte projekty w R, Javie czy innych językach programowania.

Funkcja fix()
umożliwia zmianę
wartości dowolnego
obiektu, także na
edycje ciała funkcji!

8

Łagodne wprowadzenie do R

Rysunek 1.2: Przykładowe okno edytora Eclipse. Po lewej stronie jest okno projektów.
Po prawej stronie widać przykład zwiniętych funkcji, zwiększa to czytelność kodu

Wtyczka „StatET” oferuje programistom R wiele usprawnień ułatwiających tworzenie dużych projektów i pracę z wieloma plikami, wystarczy wspomnieć o najważniejszych udogodnieniach:
• zarządzanie wieloma plikami/projektami.
• podświetlanie składni,

• domykanie otwartych nawiasów, cudzysłowów, wraz z inteligentnym zaznaczaniem zawartości (dwukrotne kliknięcie we wnętrze nawiasu, zaznacza cała
zawartość nawiasu),
• zwijanie ciała funkcji, bardzo wygodne jeżeli piszemy dużo funkcji,

• inteligentne wstawianie wcięć połączone z rozpoznawaniem składni (czyli nowe
wcięcie dodawane jest w pętlach, funkcjach itp),
• możliwość automatycznego wysyłana całego skryptu lub fragmentu kodu do
konsoli R (wykorzystywana jest zintegrowana konsola R (Rterm), działa to jak
na razie jedynie pod systemem Windows).
Minusem, o którym trzeba uczciwie powiedzieć, jest duża objętość platformy Eclipse. Ta platforma to prawdziwy kombajn, profesjonalna platforma programistyczna z bardzo zaawansowanymi możliwościami, dlatego też jej podstawowa instalacja
wymaga przynajmniej 220MB na dysku twardym. Ponieważ Eclipse napisane jest
w Javie to również intensywnie wykorzystuje pamięć operacyjną. Na szczęście ta
uciążliwość odczuwalna będzie jedynie na starszych komputerach. W zamian otrzymujemy wiele rozwiązań przydanych w pracy grupowej (np. wsparcie do CVS) oraz
w zarządzaniu dużymi fragmentami kodu.

EdytoR

Rysunek 1.3: Przykładowe okno edytora Tinn-R. Po prawej stronie widać zakładkę
R Card z pogrupowaną listą przydatnych funkcji wraz z krótkim ich opisem

Innym, bardzo popularnym edytorem jest Tinn-R. To nieduży (w porównaniu do
platformy Eclipse) edytor ze wsparciem dla R oraz kilku innych języków. Przykładowe okno tego edytora jest przedstawione na rysunku 1.3. Tinn-R powstał po to, by
umożliwić łatwą współpracę z R, jest też z R najsilniej zintegrowany. Dokładniejszy
opis jego możliwości znaleźć można na stronie internetowej [12]. Warto wymienić
kilka udogodnień, które ten edytor zawiera:
• podświetlanie składni,

• możliwość automatycznego wysyłania całego skryptu lub fragmentu kodu do
R (poprzez Rgui),
• zakładka R Card, z listą użytecznych funkcji opatrzonych krótkimi opisami,

• baza podpowiedzi (tipsów), pisząc jakieś polecenie skrótem klawiszowym Ctrl-D
wyświetlamy podpowiedź informującą o liście argumentów, opisie działania
itp.,
• uzupełnianie kodu, uzupełniane są nazwy zmiennych, funkcji i innych obiektów
z przestrzeni roboczej R,
• monitoring listy obiektów ze środowiska R, możemy na bieżąco kontrolować
jakie obiekty znajdują się w pamięci, mamy też możliwość podglądnięcia oraz
zmiany ich wartości.
Z opisanych powyżej edytorów największe wsparcie dla platformy R ma Tinn-R.
Z uwagi na wbudowaną pomoc zdecydowanie polecam go osobom początkującym
oraz średniozaawansowanym. Do pracy z dużymi projektami polecam Eclipse.

9

10

Łagodne wprowadzenie do R

1.5

Startujemy

Zakładamy, że czytelnik ma już zainstalowany na dysku pakiet R. Warto na bieżąco
i własnoręcznie sprawdzać na komputerze reakcje R na opisywane w tej książce polecenia. Jeżeli jakiś fragment nie jest zrozumiały, proszę pominąć go i czytać dalej.
Niektóre komentarze i uwagi przeznaczone są dla odrobinę bardziej zaawansowanych czytelników, nie ma się więc co zrażać, jeżeli nie wszystko będzie jasne przy
pierwszym czytaniu.

1.5.1

Pierwsze uruchomienie

Po zainstalowaniu pakietu R, czas na pierwsze jego uruchomienie. W systemie Windows najlepiej uruchomić plik Rgui.exe z katalogu bin. Uruchamia on R z wbudowanym interfejsem graficznym. Platformę R można uruchomić również w trybie
wsadowym lub trybie tekstowym, ale to jest temat, który omówimy w rozdziale 2.2.
Polecenie Rgui nie działa pod systemem Linux w tym przypadku R możemy uruchomić poleceniem R lub korzystając z innego interfejsu graficznego. W tym i kolejnym
podrozdziale będą przedstawiane przykłady działania programu Rgui.exe w wersji
dla Windows XP, dla innych systemów nazwy funkcji i argumentów są takie same.
Po uruchomieniu R pojawi się ekran powitalny oraz wyświetli się znak zachęty
>. Znak ten oznacza, że platforma R jest gotowa do realizacji kolejnego polecenia.
Efekt uruchomienia okienkowej wersji R przedstawiony jest na Rysunku 1.4.
Znak > jest znakiem zachęty do wprowadzenia kolejnych poleceń. Jest
wyświetlany tylko gdy platforma zakończyła już wykonywanie polecenia wprowadzonego w poprzedniej linii. Jeżeli nowa linia rozpoczyna się
znakiem + (znakiem kontynuacji), to znaczy, że polecenie wpisane w poprzedniej linii nie zostało jeszcze zakończone i platforma czeka na dalszą jego część
(np. rozpoczęta jest pętla, otwarty jest nawias lub cudzysłów). Jeżeli nowa linia nie
rozpoczyna się żadnym znakiem, to znaczy, że R jest w trakcie wykonywania jakiegoś
czasochłonnego polecenia lub też czeka na reakcje użytkownika (kliknięcie myszką
lub naciśnięcie któregoś klawisza na klawiaturze). Jeżeli nie wiemy na co R czeka,
to klawiszem ESC przerywamy aktualnie wykonywaną przez R czynność i wracamy
do znaku zachęty.

!!

!!

!!!

Pierwsze polecenie, które warto przećwiczyć to
q()
Jeszcze nic nie
zrobiliśmy, więc
można śmiało nie
zachowywać stanu
pracy.

czyli zamknięcie platformy R. Po wykonaniu tego polecenia zostaniemy zapytani,
czy zachować aktualny stan pracy a następnie środowisko R zostanie zamknięte.
Jeżeli nie mamy już problemu z zamykaniem platformy R, to spróbujmy znaleźć
motywacje do dalszej nauki. Dla wielu pakietów oraz funkcji dostępnych w R zostały przygotowane prezentacje, pokazujące możliwości danego pakietu lub funkcji.
Takie prezentacje uruchamia się funkcją demo(utils). Zobaczmy kilka ciekawszych
prezentacji! Aby to zrobić należy wpisać do konsoli jedną z następujących linii a następnie nacisnąć klawisz ENTER.

Startujemy

11

Rysunek 1.4: Okno powitalne, otrzymane po uruchomieniu pliku Rgui.exe

# poniższym poleceniem uruchamiamy graficzny interfejs, pozwalający na
wyklikanie większości podstawowych statystyk
library(Rcmdr)
demo(persp)
# prezentacja
demo(graphics)
# prezentacja
demo(Japanese)
# znaki Kanji
library(lattice)
demo(lattice)
# prezentacja
library(rgl)
demo(rgl)
# prezentacja
demo(lm.glm)
# prezentacja
modeli liniowych

funkcji persp, rysowanie rzutów
pakietu graphics, funkcji graficznych

pakietu lattice
pakietu rgl
wykresów diagnostycznych dla uogólnionych

Teraz powinniśmy być już wystarczająco zmotywowani. Kolejny podrozdział
przedstawia poszczególne opcje menu w okienkowej wersji R.

1.5.2

Przegląd opcji w menu

W menu dostępnym dla okienkowej wersji R jest sporo opcji. Zawartość menu zależy
od tego, czy aktywne jest okno z konsolą do wpisywania poleceń, okno graficzne
(okno, w którym R wyświetla wyniki funkcji graficznych), okno edytora, czy okno
z pomocą. Poniżej przedstawiamy opcje dla menu widocznego gdy aktywna jest
konsola poleceń lub okno graficzne. Menu dostępne gdy aktywne są inne okienka ma
podobne opcje. Zacznijmy od menu dla konsoli poleceń.

Być może będzie
trochę nudno, ale
warto choć przejrzeć
listę pozycji
w menu. Znajomość
niektórych opcji
może nam
zaoszczędzić sporo
czasu.

12

Łagodne wprowadzenie do R

• File
– Source R code...
Tym poleceniem możemy
wskazać plik tekstowy
z listą komend w języku R
do uruchomienia w konsoli.
Podobny efekt można uzyskać
funkcją source().
– New script
Polecenie otwiera wbudowany edytor skryptów R do edycji nowego pliku.
– Open script...
Polecenie otwiera wskazany plik R w wbudowanym edytorze skryptów R.
– Display file(s)...
Polecenie wyświetla zawartość wskazanych plików (każdy otwiera się w innym okienku).
– Load Workspace...
Odczytuje zapisany obszar roboczy. Terminem obszar roboczy określa się
informacje o wszystkich obiektach, znajdujących się aktualnie w pamięci
R. Odczytując zapisany obszar roboczy wracamy do zapisanego stanu
wszystkich obiektów.
– Save Workspace...
Zapisuje obszar roboczy do wskazanego pliku.
– Load History...
Odczytuje informacje o historii wykonywanych poleceń.
– Save History...
Zapisuje informacje o historii wykonywanych poleceń.
– Change dir...
To polecenie służy do zmiany aktualnego katalogu.
– Print...
Drukuje zawartość konsoli.
– Save to File...
Zapisuje do pliku tekstowego zawartość konsoli.
– Exit
Zamyka program R (zazwyczaj pytając uprzednio o to, czy nie zapisać
obszaru roboczego).

Startujemy

13

• Edit

– Copy, Paste, Paste
commands only, Copy
and Paste, Select all
Standardowe (windowsowe)
operacje do kopiowania
i wklejania informacji do
i ze schowka.
– Clear console
Polecenie czyści okno konsoli R, to bardzo przydatna opcja. Można ją
wywołać skrótem klawiszowym Ctrl+L.

– Data Editor
To polecenia otwiera wbudowany edytor do danych w postaci tabelarycznej. Można w nim edytować macierze i obiekty typu data.frame,
znajdujące się w pamięci R.
– GUI Preferences
To polecenie pozwala na zmianę różnych właściwości (głównie wyglądu)
konsoli R.
• View
W tym menu można włączyć
lub wyłączyć wyświetlanie
paska stanu oraz paska
z narzędziami.
• Misc

– Stop current computation
Ta komenda pozwala
przerwać aktualne
wykonywane polecenie,
pętlę lub instrukcję
warunkową.
Skrót klawiszowy to ESC.
– Stop all computations
Przerywa wykonywanie wszystkich poleceń, które są wykonywane lub czekają w kolejce na wykonanie. Jeżeli kopiujemy do konsoli więcej poleceń
niż jedno (np kilka pętli), to klawiszem ESC przerywamy wykonywanie
tylko jednej, aktualnej pętli. Polecenie Stop all computations przerywa wykonywanie wszystkich poleceń, również tych czekających w kolejce
do uruchomienia.

Przydatna opcja,
gdy już nie chcemy
czekać na wynik,
który liczy się dłużej
niż się
spodziewaliśmy.

14

Łagodne wprowadzenie do R
– Buffered output
Ta opcja określa, czy konsola ma być buforowana czy nie. Buforowanie
może przyspieszyć odrobinę działanie, ale powoduje, że niektóre wyniki
(np. wyświetlone funkcją cat()) nie ukazują się natychmiast na ekranie.
– Word completion
Uzupełnianie poleceń. Bardzo przydatna opcja! Wystarczy napisać kilka
początkowych liter i nacisnąć klawisz TAB, a R uzupełni nazwę funkcji lub
obiektu. W sytuacji, gdy jest kilka możliwości uzupełnienia polecenia R,
wyświetla na ekranie wszystkie możliwości.
– Filename completion
Uzupełnianie ścieżek do plików. Działa podobnie jak uzupełnianie poleceń. Bardzo wygodne przy wprowadzaniu ścieżek do plików znajdujących
się poza aktualnym katalogiem roboczym.
– List objects
Działa jak funkcja ls(), czyli wyświetla nazwy wszystkich obiektów w aktualnej przestrzeni roboczej R.
– Remove all objects
Usuwa wszystkie obiekty z przestrzeni roboczej R.
– List search path
Wyświetla nazwy pakietów oraz przestrzeni nazw, w których przeprowadzane będzie wyszukiwanie przez funkcje search().
• Packages
– Load package...
Odpowiednik funkcji
library(). Powoduje
włączenie (załadowanie)
wybranego pakietu R.
Wybierać możemy z listy wszystkich zainstalowanych pakietów.
– Set CRAN mirror
Umożliwia wybór serwera mirror CRAN, czyli miejsca, z którego ściągane
będą pakiety. Domyślne, przy instalacji pierwszego pakietu, R pyta się
z jakiego serwera CRAN korzystać i zapamiętuje ten wynik przy kolejnych
próbach instalowania pakietów.

Repozytoria to duże
zbiory
specjalizowanych
programów/pakietów/bibliotek.

– Select repositories
Wskazuje repozytoria, w których wyszukiwane mają być pakiety. Trzy
duże repozytoria z pakietami dla R to CRAN (Comprehensive R Archive Network – zbiór serwerów z pakietami i innymi materiałami o R),
Omegahat (serwisy poświęcone komunikacji R z innymi językami programowania oraz pakietami do obliczeń statystycznych) oraz Bioconductor
(zbiór pakietów dla bioinformatyków, wyspecjalizowanych do analizy danych genomicznych, głównie mikromacierzowych).

Startujemy
– Install package(s)...
Instaluje nowe pakiety. Można wybierać z listy pakietów znajdujących się
we wskazanych repozytoriach.
– Update packages
Uaktualnia wskazane pakiety (o ile są dostępne nowsze wersje).
– Install packages from local zip files
Instaluje pakiety z plików zip dostępnych lokalnie. Możemy z serwera
CRAN ściągnąć pakiet na przenośny dysk, gdzieś gdzie mamy szybki
dostęp do Internetu, a następnie przy pomocy tego polecenia zainstalować
na domowym komputerze pakiety ze ściągniętych plików zip.
• Windows

– Cascade, Title, Arrange
Icons
Różne sposoby ułożenia
otwartych okien. Przydatne, gdy tych okien jest wiele.
– R console, ....
Lista otwartych okien. Możemy wybrać, które okno ma zostać uaktywnione.

• Help

– Console
Lista skrótów klawiszowych.
Warto ją przeczytać,
znajomość tych skrótów
może znacznie przyśpieszyć
pracę. Przydatne skróty
to między innymi:
Ctrl+U (kasowanie
zawartości aktualnej linii); Ctrl+L (czyszczenie zawartości okienka konsoli); Ctrl+T (zamiana miejscami dwóch sąsiednich znaków); Ctrl+Tab
(przełączanie do kolejnego otwartego okna R); ESC (przerwanie obliczeń).
– FAQ on R
Lista odpowiedzi na najczęściej zadawane pytania dotyczące R.
– FAQ on R for Windows
Lista odpowiedzi na najczęściej zadawane pytania dotyczące R w środowisku Windows.
– Manuals
Zbiór dokumentów w pdf dotyczących wybranych zagadnień wykorzystywania R.

15

16

Łagodne wprowadzenie do R
– R functions (text)
Pomoc dotycząca wybranej funkcji.
– HTML help
Strona z pomocą w formacie HTML. Format HTML jest bardzo wygodny
do przegladania plików pomocy do pakietów oraz funkcji.
– Search help
Odpowiednik funkcji help.search(), czyli wyszukiwania informacji na
dany temat w zainstalowanych pakietach.
– Search.r-project.org
Odpowiednik funkcji Rsitesearch(), czyli wyszukiwania informacji na
dany temat w stronach związanych z platformą R.
– Apropos
Odpowiednik funkcji apropos(). Powoduje wyświetlenie listy funkcji zawierających zadany ciąg znaków.
– R project home page
Otwiera w przeglądarce stronę domową R, czyli stronę o adresie
http://www.r-project.org/.
– CRAN home page
Otwiera w przeglądarce wybrane repozytorium CRAN. Adres wrocławskiego repozytorium to http://r.meteo.uni.wroc.pl/.
– About
Informacja o uruchomionej wersji R.
Powyższe opcje w menu są dostępne, gdy aktywna jest konsola do wprowadzania
poleceń. Jeżeli aktywne jest okno graficzne, to menu jest takie jak przedstawiono
poniżej.
• File

– Save as
To polecenie umożliwia
zapis rysunku z okna
graficznego do pliku w jednym z wielu dostępnych formatów graficznych
(pdf, ps, png, bmp, jpg). Rozdzielczość zapisanego rysunku będzie taka,
jak wielkość aktualnie otwartego okna graficznego.
– Copy to clipboard
To polecenie umożliwia skopiowanie rysunku z okna graficznego do schowka Windows. Następnie możemy ten rysunek wkleić do innej aplikacji (np.
Word, paint).
– Print
To polecenie umożliwia wydrukowanie rysunku.

Startujemy
– Close device
To polecenie zamyka aktualne okno graficzne.
• History

– Recording..
Włączenie tej opcji
powoduje, że R zapamiętuje
rysunki, które będą
pojawiały się w oknie
graficznym. Używając
poniżej opisanych poleceń, można przeglądać kolejne rysunki z historii
wyświetleń. Przydatna opcja, szczególnie w sytuacji, gdy jakaś funkcja
rysuje dwa rysunki, jeden po drugim. Dzięki historii możemy powrócić
do poprzedniego rysunku.
– Add, Replace, Previouse, Next
Te polecenia umożliwiają poruszanie się po historii wyświetleń rysunków w oknie graficznym. Dwóm ostatnim opcjom odpowiadają skróty
klawiszowe PgUp (przełącz na poprzedni rysunek), PgDown (przełącz na
następny rysunek).
– Save to variable, get from variable
Umożliwia zapisanie i odtworzenie informacji o oknie graficznym ze zmiennej dostępnej w przestrzeni roboczej R. Przydaje się, jeżeli zawartość okna
graficznego ma zostać zmieniona, ale chcielibyśmy zapisać jego aktualny
stan.
– Clean history
Usunięcie informacji o historii wyświetlanych rysunków.

• Resize
Pozwala na określenie wymiarowania rysunku względem rozmiarów
okienka graficznego.
• Windows
Identyczne z menu „Windows”, gdy aktywna jest konsola do wprowadzania
poleceń.

17

18

R will always be
arcane to those who
do not make
a serious effort to
learn it. It is
**not** meant to be
intuitive and easy
for casual users to
just plunge into. It
is far too complex
and powerful for
that. But the
rewards are great
for serious data
analysts who put in
the effort.
Berton Gunter
fortune(196)

Łagodne wprowadzenie do R

1.5.3

Gdzie szukać pomocy?

Jest prawdą absolutną, że w przypadku, gdy nie wiemy jak coś zrobić, to najłatwiej i najszybciej będzie zapytać się kogoś kto to wie i chce nam podpowiedzieć.
W sytuacji, gdy nie mamy takiej osoby pod ręką R oferuje bogaty system pomocy.
Pierwszym źródłem pomocy są wbudowane funkcje R ułatwiające wyszukiwanie
informacji. Oto lista najbardziej przydatnych:
• Funkcja help() bez argumentów. Wyświetla stronę powitalną systemu pomocy R. Na tej stronie opisane są szczegółowo wymienione poniżej funkcje.
• Funkcja help("nazwaFunkcji") lub ?nazwaFunkcji. Wyświetla stronę z pomocą dla funkcji o nazwie nazwaFunkcji. Format opisów funkcji jest ujednolicony, tak aby łatwiej było z nich korzystać. Kolejne sekcje pomocy zawierają:
zwięzły opis funkcji (sekcja Description), deklaracje funkcji (sekcja Usage),
objaśnienie poszczególnych argumentów (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 określimy argument package, to uzyskamy pomoc dotyczącą konkretnego pakietu.
Przykładowo polecenie help(package=MASS) wyświetla opis dla pakietu MASS.
• Funkcja args(nazwaFunkcji). Wyświetla listę argumentów dla danej funkcji.

• Funkcja apropos(slowo) lub find(slowo). Wypisuje listę funkcji (oraz obiektów), które w swojej nazwie mają podciąg slowo.
• Funkcja example(nazwaFunkcji). Uruchamia skrypt z przykładowymi wywoływaniami poszczególnych funkcji. Dzięki przykładom można szybko zobaczyć
jak korzystać z danej funkcji, a także jakich wyników się należy spodziewać.
Na dobry początek warto sprawdzić wynik polecenia example(plot).
• Funkcja help.search("slowoKluczowe"). Przegląda opisy funkcji znajdujących się w zainstalowanych pakietach i wyświetla te pozycje, w których znaleziono wskazane slowoKluczowe. W tym przypadku slowoKluczowe może
oznaczać również kilka słów lub zwrot. W liście wyników znajduje się również
informacja, w którym pakiecie znajdują się znalezione funkcje.
Poniżej przykładowa sesja w pakiecie R, poszukujemy dodatkowych informacji
o funkcji plot() oraz o funkcjach do testowania statystycznego.
# wyświetl pomoc dotyczącą funkcji plot()
?plot
# wyświetl przykłady użycia funkcji plot()
example(plot)
# wyświetl nazwy funkcji ze słowem "test" w nazwie
apropos("test")
# wyświetl nazwy funkcji ze zwrotem ’normality test’ w opisie
help.search("normality test")

Powyżej przedstawione funkcje wyszukują informacje na dany temat wśród pakietów, 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ę

Startujemy
potencjalnie interesująca nas funkcja), to możemy skorzystać z zasobów dostępnych
w Internecie. W szczególności warto wiedzieć gdzie znaleźć:
• Poradniki (manuale, ang. manuals) do R’a, poświęcone różnym aspektom programowania w R lub analizie danych w R. Dostępne są bezpośrednio z menu Help w R (gdy aktywna jest konsola) oraz w Internecie pod adresem
http://cran.r-project.org/manuals.html.
• Książki poświęcone pakietowi R oraz o analizie danych z użyciem tego pakietu.
Aktualizowana lista książek na ten temat znajduje się online pod adresem
http://www.r-project.org/doc/bib/R-books.html.
• Encyklopedia Rwiki dostępna pod adresem http://wiki.r-project.org/rwiki/.
Jest to Wiki o R, czyli masa ciekawych informacji w mniej lub bardziej kontrolowanej formie (szczególnie warto przejrzeć sekcje zatytułowaną „R graph
galery”).
• Wyszukiwarka Rseek dostępna pod adresem http://www.rseek.org/. Jest to
potężna wyszukiwarka funkcji, obiektów, komentarzy i innych informacji. Jeżeli
nie znajdzie się tego czego się szuka, to zawsze można też zapytać wyszukiwarkę
google przeglądając tylko podstrony serwisu o R. Tak ustawiona wersja google
znajduje się np. pod adresem http://www.r-project.org/search.html.
• Lista dyskusyjna poświęcona rozwiązywaniu problemów w korzystaniu z R. Jej
archiwum znajduje się pod adresem http://www.r-project.org/mail.html.
W razie problemów ze znalezieniem odpowiedzi na frapujący nas problem można tu zadać pytanie i cierpliwie czekać na odpowiedź. W 99% przypadków już
ktoś zadał takie pytanie i uzyskał odpowiedź, warto wiec najpierw przejrzeć
archiwum listy.
• Zbiór porad FAQ dostępne pod adresem http://www.r-project.org/faqs.html.
Tysiące lub setki tysięcy osób używa R, więc pewne pytania zostały już zadane
setki razy. FAQ, to miejsce, w którym znajdziesz odpowiedzi na najczęstsze
pytania (stąd też nazwa FAQ, skrót od Frequently Asked Question).
• Galeria grafik dostępna pod adresem http://addictedtor.free.fr/graphiques/.
To strona internetowa ze zbiorem różnych ciekawych wykresów wykonanych
w R. Warto zerknąć, bo z pewnością robi wrażenie. Co więcej kody R wykorzystane do wykonania poszczególnych wykresów można ściągnąć i samodzielnie
przeanalizować.
Powyższe źródła są bez wyjątku angielskojęzyczne. Poza nimi w Internecie można
znaleźć też wiele materiałów polskojęzycznych. W szczególności warto przejrzeć dokument „Wprowadzenie do środowiska R” autorstwa Łukasza Komsty [13] dostępny
pod adresem http://cran.r-project.org/doc/contrib/Komsta-Wprowadzenie.pdf.
W polskim Internecie można też znaleźć wiele notatek do wykładów lub laboratoriów
prowadzonych z użyciem pakietu R.
W razie wątpliwości lub problemów zawsze można zadać pytanie na którymś
z polskich forów, na którym pojawiają się użytkownicy pakietu R, np. na forum
poświęcone statystyce, znajdujące się pod adresem http://www.statystycy.pl/
lub na forum dedykowane pakietowi R i jego użytkownikom, które jest dostępne
pod adresem https://www.im.uj.edu.pl/gur/.

19

20

Łagodne wprowadzenie do R

1.5.4

kalkuRator

R to bardzo potężny, zaawansowany i rozbudowany pakiet statystyczny. Ale można
korzystać z niego tak, jak z bardzo rozbudowanego kalkulatora. Zacznijmy od kilku
prostych działań. Poniższa ramka przedstawia wynik przykładowej sesji z R. Po znaku zachęty ">" znajdują się wprowadzone komendy. Naciśnięcie klawisza ENTER powoduje zakończenie linii i (o ile to możliwe) wykonanie polecenia.
Poniżej przedstawiamy przykładową sesję z pakietem R w roli kalkulatora.

> 2+2
# na początek coś postego
[1] 4
> 2^10 -1
# dwie operacje, potęgowanie ma wyższy priorytet
[1] 1023
> 1/5
[1] 0.2
> sin(pi/2)
# funkcje trygonometryczne operują na radianach
[1] 1
> sin(pi/3)^2 + cos(pi/3)^2 # pamiętamy z trygonometrii skąd ten wynik?
[1] 1
> (3+7)^(4-2)
[1] 100
> atan2(1,1)
# wywołanie funkcji arcus tangens, patrz tabela 1.1
[1] 0.7853982
> pi/4
[1] 0.7853982
> log(1024,2)
[1] 10
> choose(6,2)
# symbol Newtona, nie każdy kalkulator potrafi go wyliczyć
[1] 15

Napis [1] rozpoczynający linię z wynikiem związany jest ze sposobem
działania funkcji wyświetlającej liczby. Mianowicie, jeżeli wyświetlane
są wartości długiego wektora liczb, to w nawiasie kwadratowym znajduje się indeks elementu wyświetlanego bezpośrednio za tym nawiasem.
W prezentowanych przypadkach wynikiem jest jedna liczba, która jest traktowana
przez R jako jednoelementowy wektor, stąd napis [1]. Jeszcze do tego wrócimy.

!!

Można też grupować
wyrażenia
arytmetyczne
nawiasami
klamrowymi {}, co
prawda R inaczej
interpretuje oba
typy nawiasów, ale
efekt końcowy
będzie taki sam.

!!

!!!

Jak widać liczenie w R to nic trudnego. Do dyspozycji mamy wszystkie popularne
operatory arytmetyczne (ich lista znajduje się w tabeli 1.1). Wyrażenia arytmetyczne
można grupować wykorzystując nawiasy (). W R dostępne są również popularne
funkcje arytmetyczne (ich lista znajduje się w tabeli 1.3), oraz najpopularniejsze
funkcje trygonometryczne (wymienione w tabeli 1.2). Z funkcji tych korzysta się
intuicyjnie (patrz przykład powyżej). Warto pamiętać, że implementacja tych funkcji
często jest bardzo zaawansowana po to, by wyniki numeryczne były wyznaczane
z możliwie największą precyzją.

Startujemy
Warto zwrócić uwagę na funkcje expm1(base) i log1p(base). Ze względu na ograniczoną możliwość przechowywania i operowania przez procesor na liczbach rzeczywistych, wykonywanie dodawania lub odejmowania na liczbach różniących się o kilka lub kilkanaście rzędów prowadzi do sporych błędów numerycznych. Z tego też powodu w praktycznie każdym
kalkulatorze (i również w większości pakietów statystycznych) wartość wyrażenia
1-exp(0.1^15) jest wyznaczana z błędem względnym rzędu 10%. Podobnie wyrażenie log(1+0.1^20) jest wyliczane jako 0 (a więc z błędem względnym wynoszącym
100%). W tych sytuacjach dużo dokładniejsze wyniki będą wyznaczone, gdy użyjemy
funkcji expm1() i log1p().

!!

!!

!!!

> 1-exp(0.1^15)
[1] -1.110223e-15
> expm1(0.1^15)
[1] 1e-15
> log(1+0.1^20)
[1] 0
> log1p(0.1^20)
[1] 1e-20

# Opis tych funkcji znajduje się w tabeli 1.3

To jeszcze nie koniec możliwości kalkuRatora. Dostępnych jest znacznie więcej
funkcji, które ucieszą każdego inżyniera. Listę bardziej popularnych zamieszczamy
w tabeli 1.4. Wybrane bardziej specjalistyczne funkcje w tym: funkcje Bessela, bazy
wielomianów ortogonalnych itp. zostaną opisane w kolejnych rozdziałach.
Tabela 1.1: Lista operatorów arytmetycznych
x
x
x
x
x

x
+ y (x - y)
* y (x / y)
^ y
%% y
%/% y

Zmiana znaku x.
Suma (różnica) dwóch liczb x i y.
Iloczyn (iloraz) dwóch liczb x i y.
Liczba x do potęgi y.
Reszta z dzielenia x przez y (tzw. dzielenie modulo).
Część całkowita z dzielenia x przez y.

Tabela 1.2: Lista funkcji trygonometrycznych z pakietu base
cos(x)
sin(x)
tan(x)
acos(x)
asin(x)
atan(x)
atan2(y, x)

Wartość funkcji cosinus w punkcie x.
Wartość funkcji sinus w punkcie x.
Wartość funkcji tangens w punkcie x.
Wartość funkcji arcus cosinus w punkcie x.
Wartość funkcji arcus sinus w punkcie x.
Wartość funkcji arcus tangens w punkcie x.
Funkcja wyznaczająca kąt (w radianach) pomiędzy osią OX
a wektorem o początku w punkcie (0,0) a końcu w punkcie
(x,y). Wygodna funkcja do zamiany współrzędnych w układzie
kartezjańskich, na współrzędne w układzie biegunowym.

21

22

Łagodne wprowadzenie do R

Tabela 1.3: Lista funkcji arytmetycznych z pakietu base
round(x)
signif(x,k)
floor(x)
ceiling(x)
trunc(x)
abs(x)
log(x)
log(x, base)
log10(x)
log2(x)
exp(x)
expm1(x)
log1p(x)
sqrt(x)

Liczba całkowita najbliższa wartości x.
Wartość x zaokrąglona do k miejsc znaczących.
Podłoga, czyli największa liczba całkowita nie większa od x.
Sufit, czyli najmniejsza liczba całkowita nie mniejsza od x.
Wartość x po odcięciu części rzeczywistej, dla liczb dodatnich
działa jak floor(), dla ujemnych jak ceiling.
Wartość bezwzględna z x.
Logarytm naturalny z x.
Logarytm o podstawie base z x.
Logarytm o podstawie 10 z x.
Logarytm o podstawie 2 z x.
Funkcja wykładnicza (eksponenta) z x.
Funkcja równoważna wyrażeniu exp(x)-1, ale wyznaczona
z większą dokładnością dla |x|<<1.
Funkcja równoważna wyrażeniu log(1+x), ale wyznaczona
z większą dokładnością dla |x|<<1.
Pierwiastek kwadratowy z x, równoważne poleceniu x^0.5.

Tabela 1.4: Lista funkcji specjalnych i do operacji na liczbach zespolonych (pakiet base)
beta(a,b)
lbeta(a,b)
gamma(x)
lgamma(x)
digamma(x)
trigamma(x)
psigamma(x, deriv)
combn(n,k)
choose(n,k)
lchoose(n,k)
factorial(x)
lfactorial(x)
convolve(x,y)
complex(real=0,
imaginary=0,
modulus=1,argument=0)
as.complex(x, ...)
is.complex(x)
Re(x)
Im(x)
Mod(x)
Arg(x)
Conj(x)

Wartość funkcji B(a, b) o argumentach a i b.
Wartość logarytmu z funkcji B(a, b).
Wartość funkcji Γ(x).
Wartość logarytmu z funkcji Γ(x).
Druga pochodna z logarytmu funkcji Γ(x).
Trzecia pochodna z logarytmu funkcji Γ(x).
Pochodna rzędu deriv z logarytmu funkcji Γ(x).
Lista wszystkich kombinacji k elementowych ze zbioru
n elementowego.
Liczba kombinacji k elementowych ze zbioru n elementowego.
Logarytm z liczby kombinacji k elementowych ze zbioru n elementowego.
Silnia z x.
Logarytm z silni z x.
Splot wektorów x i y.
Funkcja do konstruowania liczb zespolonych. Liczby
możemy określać podając część rzeczywistą i urojoną
lub podając moduł i argument.
Konwersja x na liczbę zespoloną.
Test, czy argument x jest liczbą zespoloną.
Część rzeczywista liczby zespolonej x.
Część urojona liczby zespolonej x.
Moduł liczby zespolonej x.
Argument liczby zespolonej x.
Sprzężenie liczby zespolonej x.

Startujemy

1.5.5

23

Kilka przykładowych sesji w R

W dalszej części tej książki na przykładach pokażemy, co można robić w R, na jakich
obiektach i w jaki sposób można pracować oraz jakie efekty można uzyskać. W tym
podrozdziale nakreślimy wyłącznie kilka ogólnych idei oraz pokażemy kilka przykładów pracy z R, tak by łatwiej było przedzierać się przez późniejsze, sformalizowane
opisy. Aby zdobyć biegłość w programowaniu w R trzeba ćwiczyć i eksperymentować
(tak jak i w nauce każdego języka, czy to języka programowania czy języka naturalnego). Dlatego po przeczytaniu tego podrozdziału warto spróbować samodzielnie
napisać kilka programów w R. Osoby nie lubiące uczenia się na przykładach powinny
ten podrozdział ominąć i przejść do kolejnego.
Przykłady rozpocznijmy od operacji na zmiennych. Poniższe przykłady warto
samodzielnie uruchomić w R. W tym celu należy wpisać zawartość wszystkich linijek
rozpoczynających się od znaku > (znaku zachęty > nie przepisujemy, jedynie to co
jest za nim).
> #
> a
> b
> #
> a
[1]
> #

zaczynamy od przypisania wartości do zmiennych a i b
= 3
= 5
teraz możemy wykonać operacje na tych zmiennych
+ b
8
jeżeli nie wiemy dlaczego na ekranie pojawiła się cyfra 8 to należy
rozpocząć lekturę tego rozdziału od początku
> # wykonajmy bardziej zaawansowaną operację i wynik przypiszmy do
zmiennej c
> c = a/b + 2*b + 1
> # podając tylko nazwę zmiennej powodujemy wyświetlenie jej wartości
> c
[1] 11.6
> # jeżeli przypisanie otoczymy nawiasami to zmuszamy R do wypisania
wyniku przypisania
> (napis = "Ala ma kota")
[1] "Ala ma kota"

Bez względu na to jak zaawansowane analizy będą wykonywane, jednym z efektów, które na pewno pojawi się na ekranie jest komunikat o błędzie. Należy się zawczasu oswoić z reakcją pakietu R na błędy, w podrozdziale 2.5.1 poznamy bardziej
zaawansowane sposoby radzenia sobie z błędami.
> # gdy użyjemy nazwy zmiennej, która nie została zadeklarowana to
zgłoszony będzie taki błąd, najczęściej oznacza on złe wpisanie nazwy
zmiennej, literówkę itp.
> brakZmiennej + 2
Error: object "brakZmiennej" not found
> # błąd pojawi się również przy próbie wywołania nieistniejącej funkcji,
jeżeli napotkamy taki błąd, to być możne funkcja, której chcemy użyć
jest w pakiecie, który nie został jeszcze załadowany
> brakFunkcji()
Error: could not find function "brakFunkcji"

Zakładam, że
czytelnik wie czym
są zmienne i do
czego się ich używa.
Jeżeli nie, to bez
wdawania się
w szczegóły może
przyjąć, że zmienna
reprezentuje pewne
wirtualne, nazwane
pudełko, w którym
możemy
przechowywać
wartości.

24

Łagodne wprowadzenie do R

> # jeżeli nie podamy wszystkich wymaganych argumentów funkcji to też
możemy się spodziewać błędu
> cov(1)
Error in cov(1) : supply both ’x’ and ’y’ or a matrix-like ’x’
> # częstym błędem jest nie dokończenie polecenia, nie zamknięcie nawiasu
lub nie zamknięcie łańcucha znaków, w tej sytuacji R sygnalizuje, że
czeka na resztę polecenia
> lancuch = "
+ "
> 2 +
+ 2
[1] 4

Jeżeli nie wiemy, co
to liczby zespolone,
to pomijamy ten
przykład.

Możemy też operować na liczbach zespolonych (trzeba to robić z uwagą, patrz poniższy przykład). Lista funkcji do operowania na liczbach zespolonych umieszczona
jest w tabeli 1.4.
> # pierwsza próba, niestety bez powodzenia
> sqrt(-17)
[1] NaN
Warning message:
In sqrt(-17) : NaNs produced
> # nie tak miało być, jeżeli chcemy korzystać z arytmetyki na liczbach
zespolonych, trzeba to wyraźnie dać do zrozumienia platformie R
> sqrt(-17+0i)
[1] 0+4.123106i
> (2+4i)*(3-2i)
[1] 14+8i

A teraz skonstruujemy wektor liczb i wykonamy na nim kilka operacji. Prześledźmy uważnie wyniki poniższych instrukcji.
> # wektor tworzy się korzystając z funkcji c()
> (wektor = c(11, 13, 10.5, -3, 11))
[1] 11.0 13.0 10.5 -3.0 11.0
> # na takim wektorze możemy wykonywać operacje arytmetyczne
> wektor^2
[1] 121.00 169.00 110.25
9.00 121.00
> 1/wektor
[1] 0.09090909 0.07692308 0.09523810 -0.33333333 0.09090909
> wektor -2
[1] 9.0 11.0 8.5 -5.0 9.0
> # wektory można łączyć w jeszcze większe wektory
> c(wektor, 0, 3:5, wektor)
[1] 11.0 13.0 10.5 -3.0 11.0 0.0 3.0 4.0 5.0 11.0 13.0 10.5 -3.0
11.0
> # zamiast wpisywać długie sekwencje liczb ręcznie możemy je generować
automatycznie
> 1:10
[1] 1 2 3 4 5 6 7 8 9 10

Startujemy

> # funkcja rep() replikuje wektor określoną liczbę razy
> rep(1:2, times=5)
[1] 1 2 1 2 1 2 1 2 1 2
> rep(1:2, each=5)
[1] 1 1 1 1 1 2 2 2 2 2
> # możemy operować na wektorze wartości logicznych (o tym jeszcze będzie)
> wektor = c(11, 13, 10.5, -3, 11)
> wektor > 0
[1] TRUE TRUE TRUE FALSE TRUE

W powyższych przykładach wykonywaliśmy operacje na całym wektorze. Możemy również manipulować fragmentami lub poszczególnymi elementami wektora.
Poniżej kilka przykładów jak to zrobić. Więcej o tym jak korzystać z elementów
wektora będzie w następnym podrozdziale.
> # co jest w pierwszym elemencie wektora
> wektor[1]
[1] 11
> # co jest w elemencie 2 i 3 wektora
> wektor[2:3]
[1] 13.0 10.5
> # fragment wektora też jest wektorem możemy więc na nim swobodnie
wykonywać dowolne operacje
> wektor[2:3] + 4
[1] 17.0 14.5
> # co jest w elemencie 1, 3 i 5
> wektor[c(1,3,5)]
[1] 11.0 10.5 11.0
> # wypiszmy wartości dodatnie z wektora (wartości o indeksach
odpowiadającym wartościom dodatnim)
> wektor[wektor>0]
[1] 11.0 13.0 10.5 11.0

Strukturą bardziej złożoną od wektora jest macierz. W poniższym przykładzie
zadeklarujemy macierz o wymiarach 2 × 3 i wykonamy na niej kilka operacji arytmetycznych.
>
>
>
>

# tworzymy nową macierz złożoną z samych zer
macierz = matrix(0,2,3)
# wyświetlmy ją
macierz
[,1] [,2] [,3]
[1,]
0
0
0
[2,]
0
0
0
> # tak jak w przypadku wektora na macierzy możemy wykonywać operacja
arytmetyczne
> macierz+1
[,1] [,2] [,3]
[1,]
1
1
1
[2,]
1
1
1

25

26

Łagodne wprowadzenie do R

> # a teraz tworzymy inną, ciekawszą macierz, której elementami są kolejne
liczby całkowite
> macierz = matrix(1:6,2,3)
> macierz
[,1] [,2] [,3]
[1,]
1
3
5
[2,]
2
4
6
> # wyświetlmy tylko drugą kolumnę tej macierzy
> macierz[,2]
[1] 3 4
> # a teraz drugi wiersz
> macierz[2,]
[1] 2 4 6

Z algebry znamy ciekawsze operacje na macierzach. Zobaczmy więc jak mnożyć
macierze, jak liczyć ich wyznaczniki, odwrotności i iloczyny.
> # zacznijmy od zdefiniowania dwóch macierzy o wymiarach 2x2
> (A = B = matrix(1:4,2,2))
[,1] [,2]
[1,]
1
3
[2,]
2
4
> # pierwsza próba mnożenia, mnożone są elementy macierzy pierwszy z
pierwszym, drugi z drugim itp.
> A * B
[,1] [,2]
[1,]
1
9
[2,]
4
16
> # mnożenie macierzowe wykonuje się operatorem %*%, wynik jest inny
> A %*% B
[,1] [,2]
[1,]
7
15
[2,]
10
22
> # policzmy wyznacznik z macierzy A
> det(A)
[1] -2
> # i macierz odwrotną do A
> solve(A)
[,1] [,2]
[1,]
-2 1.5
[2,]
1 -0.5
> # na koniec wyznaczmy jeszcze wartości własne i wektory własne
> eigen(A)
$values
[1] 5.3722813 -0.3722813
$vectors
[,1]
[,2]
[1,] -0.5657675 -0.9093767
[2,] -0.8245648 0.4159736

To tyle tytułem rozgrzewki, nadszedł czas na trochę teorii.

Startujemy

1.5.6

27

Podstawy składni języka R

Poniżej przedstawimy podstawy składni języka R. Przedstawimy też takie pojęcia
jak typ, obiekt, konwersja itp. Opanowanie tych pojęć i poniżej opisanych informacji
jest niezbędne, by móc sprawnie poruszać się po kolejnych rozdziałach.
1.5.6.1

Obiekty

Wszystko czym można operować w języku R jest obiektem. Obiekty można podzielić
(nie wdając się w formalne szczegóły) na kilka typów (rodzajów):
• Typ liczbowy. Ten typ nie wymaga komentarza. Obiekty tego typu przechowują liczby, zarówno całkowite jak i rzeczywiste. Wpisując liczby dozwolona
jest notacja naukowa (np. 2.5e3). Kropką dziesiętną w R jest kropka. Wyróżnioną wartością jest NaN (to skrót rozwijający się w „not a number”, czyli
„nie liczba”). Ta wartość może pojawić się w wyniku wykonania niepoprawnego działania (np. próby logarytmowania liczby ujemnej). Literały Inf i -Inf
określają plus i minus nieskończoność.
> 1
[1] 1
> 1.5
[1] 1.5
> 1.5e5
[1] 150000

• Typ czynnikowy (nazywany również wyliczeniowym lub kategorycznym). Ten typ jest przydatny do przechowywania wektorów wartości występujących na kilku poziomach (w kilku kategoriach). Przykładowo płeć występuje na dwóch poziomach, tzn. może przyjmować tylko dwie wartości, dlatego
przechowując w R wektor danych opisujących płeć, najlepiej użyć typu czynnikowego. Zmienne tego typu są najczęściej wykorzystywane do definiowania
grup. Gdy możemy, warto używać tego typu dla poprawienia efektywności.
Zmienne typu czynikowego zajmują mniej miejsca w pamięci niż odpowiadające im łańcuchy znaków, można na nich szybciej wykonywać określone funkcje.
Ponadto wiele funkcji R (szczególnie statystycznych) jest w stanie rozpoznać,
że argument jest typu wyliczeniowego i zastosować odpowiednie działania, np.
wyznaczyć liczebności poszczególnych grup itp.
Konstruktorem tego typu jest funkcja factor(). Na poniższym przykładzie
konstruujemy wektor elementów typu wyliczeniowego z dwoma poziomami.
> (nz = factor(c("sierzant", "kapitan", "sierzant", "sierzant")))
[1] sierzant kapitan sierzant sierzant
Levels: kapitan sierzant
> # zobaczmy opis tego wektora
> summary(nz)
kapitan sierzant
1
3

W tej książce
będziemy korzystać
przemiennie
z różnych nazw dla
typu czynnikowego,
zdając sobie sprawę,
że przez różne grupy
użytkowników jest
on różnie nazywany.
Programiści języków
typu C++ i
niższego poziomu,
przyzwyczajeni są
do nazwy typ
wyliczeniowy.
Nazwa typ
kategoryczny bierze
się z nazywania
możliwych wartości
zmiennej danego
typu kategoriami.
Nazwa typ
czynnikowy jest
najczęściej używana
wśród statystyków,
gdzie możliwe
wartości
odpowiadają
różnym poziomom
pewnego czynnika.

28

Łagodne wprowadzenie do R
• Typ znakowy. Wartościami obiektów tego typu są napisy (będziemy też używać nazwy łańcuchy znaków). W R napisy rozpoczynane są znakiem ’ lub
" oraz kończone takim samym znakiem. W łańcuchu znaków mogą występować dowolne znaki w tym znaki specjalne (rozpoczynające się od znaku \).
Wybrane znaki specjalne to: \n – znak nowej linii, \t – znak tabulacji, \\ –
oznaczający znak \, znak \" – oznaczający " itp.
Z łańcuchów znaków można wycinać fragmenty, sklejać, wyszukiwać podciągi
znaków i wykonywać wiele innych operacji, o których napiszemy w kolejnych
podrozdziałach.
> "To jest napis"
[1] "To jest napis"
> ’To tez jest napis’
[1] "To tez jest napis"
> "To jest napis ’a to jest napis wewnetrzny’"
[1] "To jest napis ’a to jest napis wewnetrzny’"
> # funkcja cat() wyświetla napis w sposób niesformatowany
> cat(" co \t to \\ teraz\"\n\n bedzie?")
co
to \ teraz"
bedzie?
> # napisy można sklejać
> paste("Napis", "napis doklejony", 12)
[1] "Napis napis doklejony 12"

• Typ logiczny. Obiekty tego typu przechowują jedną z dwóch wartości, logiczną prawdę (oznaczaną przez literał T lub TRUE) albo logiczny fałsz (oznaczany
przez literał F lub FALSE). Na tych obiektach można wykonywać operacje logiczne oraz arytmetyczne (o tym w kolejnych podrozdziałach).
Jeżeli wartości logiczne znajdą się w wyrażeniu arytmetycznym, to zostaną
skonwertowane na liczby, odpowiednio, 1 i 0.
> TRUE
[1] TRUE
> T
[1] TRUE
> # testowanie równości
> 1==2
[1] FALSE
> 2==2
[1] TRUE
> # wyrażenie arytmetyczne, następuje automatyczna konwersja wartości
typu logicznego na liczbę
> (2==2) + 2
[1] 3
> # wyrażenie logiczne, w użyciu operatory sumy logicznej i negacji
> (1==0) | !(1==0)
[1] TRUE

Startujemy
• Wektor elementów. Wektor to uporządkowany zbiór obiektów tego samego
typu. Do tworzenia wektora z pojedynczych elementów lub innych wektorów
służy funkcja c(). Poniżej przedstawiamy konstrukcje wektora składającego
się z trzech liczb oraz wektora - sekwencji 30 liczb. Tak długie wektory wyświetlane są w kilku wierszach. Kolejne wiersze rozpoczynają się od, otoczonego nawiasami kwadratowymi, indeksu pierwszego elementu wyświetlonego
w danej linii.
> c(1, 3, 4)
[1] 1 3 4
> (1:30)*2
[1] 2 4 6 8 10 12 14 16 18 20
[11] 22 24 26 28 30 32 34 36 38 40
[21] 42 44 46 48 50 52 54 56 58 60
> # elementy wektora mogą mieć nazwy
> c(pierwszy = 12, drugi = 10, trzeci = 18)
pierwszy
drugi
trzeci
12
10
18

Język R został tak zaprojektowany, by operacje na wektorach były możliwie
najefektywniejsze. Nawet pojedyncza wartość jest traktowana jako wektor jednoelementowy.
Wszystkie elementy wektora muszą mieć ten sam typ. Wyjątkiem jest umieszczanie w wektorze dowolnego typu wartości NA (not avaliable) oznaczającej
brak wartości. Wykonywanie działań arytmetycznych na wartości NA daje
w wyniku również wartość NA. Niektóre funkcje mają możliwość podania argumentu na.rm, który, gdy jest ustawiony na T pozwala na usuwanie brakujących obserwacji przed kontynuowaniem obliczeń.
> wektor = c(1, 2, NA, 40, 51)
> # funkcja mean() liczy średnią arytmetyczną, ale co ma zrobić z
brakującą obserwacją?
> mean(wektor)
[1] NA
> # dodanie argumentu na.rm=T rozwiązuje problem
> mean(wektor, na.rm=T)
[1] 23.5

Jeżeli chcemy usunąć z wektora wartości brakujące, to możemy posłużyć się
funkcją na.omit(stats) (jej wynikiem jest wektor bez elementów NA) lub
funkcją complete.cases(stats) (jej wynikiem jest wektor wartości logicznych, TRUE gdy nie ma NA lub FALSE gdy jest). Argumentami obu funkcji
mogą być wektory, macierze lub ramki danych. Jeżeli argumentem jest ramka danych, to funkcja na.omit() usunie cały wiersz, w którym znajdują się
brakujące obserwacje a complete.cases() określi dla każdego wiersza, czy
znajdują się w nim brakujące obserwacje. Związana z wartościami brakującymi jest również funkcja na.fail(stats) generująca błąd, jeżeli w argumencie
tej funkcji znajdują się brakujące obserwacje.

29

I don’t like to see
the use of c() for its
side effects. In this
case Marc’s
as.vector seems to
me to be
self-explanatory,
and that is a virtue
in programming
that is too often
undervalued.
Brian D. Ripley (on
how to convert
a matrix into
a vector)
fortune(185)

30

Łagodne wprowadzenie do R
• Lista. Podobnie jak wektor, lista to również uporządkowany zbiór elementów.
W przeciwieństwie do wektora, elementy listy mogą mieć różne typy. Podobnie
jak w przypadku wektora poszczególne elementy mogą mieć nazwy. Konstruktorem listy jest funkcja list(). Do elementów listy możemy się odwoływać jak
do elementów wektora lub korzystając z nazw poszczególnych pól. W poniższym przykładzie konstruujemy listę złożoną czterech obiektów różnych typów.
> list(imie=c("Jan","Tomasz"), nazwisko="Kowalski", wiek=25,
czyWZwiazku=T)
$imie
[1] "Jan"
"Tomasz"
$nazwisko
[1] "Kowalski"
$wiek
[1] 25
$czyWZwiazku
[1] TRUE

• Macierz. Konstruktorem macierzy dwuwymiarowej jest funkcja matrix().
Parametrami tej funkcji jest wektor liczb inicjujących wartości macierzy oraz
dwie liczby określające wymiary macierzy. W poniższym przykładzie konstruujemy macierz o wymiarach 4x2 wypełnioną zerami.
> matrix(0,2,4)
[,1] [,2] [,3] [,4]
[1,]
0
0
0
0
[2,]
0
0
0
0

Można też konstruować macierze o większej liczbie wymiarów, ten temat poruszymy w kolejnych podrozdziałach.
• Ramka danych. Szczególnym typem obiektu jest ramka danych, którą można
traktować jak listę wektorów o tej samej długości. Ramka danych może być
wyświetlana jako macierz, w której elementy w kolumnie są tego samego typu,
ale mogą różnić się typem pomiędzy kolumnami. Konstruktorem ramki danych
jest funkcja data.frame(). Poniżej konstruujemy ramkę danych składającą się
z trzech trzyelementowych zmiennych.
> # konstruujemy ramkę danych podając wartości dla każdej z kolumn
> (ramka = data.frame(id=c(100,101,102), wiek=c(25,21,22), czy.
chlopiec=c(T,T,F)))
id wiek czy.chlopiec
1 100
25
TRUE
2 101
21
TRUE
3 102
22
FALSE

Startujemy
Do elementów ramki danych możemy odwoływać się tak jak do elementów
macierzy a także tak jak do elementów list.
> # dwa różne sposoby odwołania się do drugiej kolumny
> ramka$wiek
[1] 25 21 22
> ramka[,2]
[1] 25 21 22

• Typ funkcyjny. Do konstrukcji obiektów tego typu wykorzystuje się słowo
kluczowe function. Więcej o funkcjach, w tym o pisaniu własnych funkcji,
znaleźć można w podrozdziale 1.6.2.
1.5.6.2

Konwersja

Typ zmiennej nie jest przypisany do zmiennej (czy jej wartości) na stałe. Możemy zmieniać typy nie podając nowej wartości dla zmiennej. Proces zmiany typu
nazywamy konwersją typu.
Najczęstsze konwersje to zamiana na typ znakowy (funkcja as.character(base))
lub na typ liczbowy (funkcja as.numeric(base)). Konwertować można pojedyncze
wartości jak również złożone struktury takie jak lista lub macierz. W przypadku
konwersji struktury konwertowany jest każdy element tej struktury (listy, macierzy
itp.) lub też konwertowana jest cała struktura, np. lista może być zamieniana na
wektor. Lista funkcji konwertujących typ zmiennej jest przedstawiona w tabeli 1.5.
Tabela 1.5: Funkcje pozwalające na sprawdzenie lub konwersję typu zmiennej
is.numeric(base)
is.integer(base)
is.double(base)
is.complex(base)
is.logical(base)
is.character(base)
is.factor(base)
is.na(base)
is.nan(base)
as.numeric(base)
as.integer(base)
as.double(base)
as.complex(base)
as.logical(base)
as.character(base)
as.factor(base)
as.list(base)
unlist(base)
as.matrix(base)
as.data.frame(base)

Test czy argument jest liczbą.
Test czy argument jest liczbą całkowitą.
Test czy argument jest liczbą rzeczywistą.
Test czy argument jest liczbą zespoloną.
Test czy argument jest wartością logiczną.
Test czy argument jest znakiem lub łańcuchem znaków.
Test czy argument jest typu wyliczeniowego.
Test czy argument jest nieokreślona (NA).
Test czy argument jest niewłaściwą liczbą (NaN).
Konwersja na wartość liczbową.
Konwersja na wartość całkowitoliczbową. Liczby rzeczywiste są zaokrąglane w dół.
Konwersja na wartość rzeczywistą.
Konwersja do liczby zespolonej.
Konwersja na wartość logiczną.
Konwersja na typ znakowy.
Konwersja na typ wyliczeniowy.
Konwersja do listy.
Konwersja z listy do wektora.
Konwersja na macierz.
Konwersja na ramkę danych.

31

Łagodne wprowadzenie do R

!!

!!

!!!

Konwertując obiekty typu wyliczeniowego na typ liczbowy należy być
ostrożnym, aby nie być zaskoczonym wynikiem takiej konwersji.
W przykładzie poniżej widzimy, co złego może się stać przy nieostrożnym
konwertowaniu liczb.

> (wektor = factor(c(-2,2)))
[1] -2 2
Levels: -2 2
> # nie takiego wyniku się spodziewaliśmy
> as.numeric(wektor)
[1] 1 2

Konwersja typu factor na numeric polega na tym, że kolejnym poziomom przypisywane są kolejne liczby naturalne. Stąd w powyższym przykładzie wynik 1 2. Bardziej
oczekiwany wynik uzyskamy konwertując „po drodze” wektor na typ znakowy.
> as.character(wektor)
[1] "-2" "2"
> # tak miało być
> as.numeric(as.character(wektor))
[1] -2 2

Jeżeli nie jesteśmy pewni jakiego typu jest zmienna, to możemy jej typ sprawdzić
funkcją class() lub mode(). Możemy też wykorzystać funkcje z tabeli 1.5.
Proszę zwrócić uwagę, że dwie przedstawione w tej tabeli funkcje: is.na()
i is.nan() testują wartości a nie typ, tak jak pozostałe funkcje z tej tabeli.
> wektor = 1:6
> # klasa zmiennej wektor zwraca klasę elementów tego wektora
> class(wektor)
[1] "integer"
> # tryb przechowywania elementów wektora to tryb liczbowy
> mode(wektor)
[1] "numeric"
> is.numeric(wektor)
[1] TRUE
> # ten wektor nie jest wektorem znaków
> is.character(wektor)
[1] FALSE
> # i żadna z jego wartości nie jest NA
> is.na(wektor)
[1] FALSE FALSE FALSE FALSE FALSE FALSE

Klasę obiektu „widzianą” przez funkcję class() można dowolnie zmieniać, o czym jeszcze powiemy więcej w kolejnych rozdziałach. Funkcja
mode() informuje o wewnętrznej reprezentacji danej zmiennej i nie możemy na wynik tej funkcji bezpośrednio wpływać. Więcej o tych funkcjach
przeczytać można w podrozdziale 2.1.6.

!!

!!!

!!

32

Startujemy
1.5.6.3

Zmienne

Zmienne służą do przechowywania wprowadzonych danych lub wyników wykonanych
poleceń. Najczęściej te wartości chcemy przechować, aby móc je później ponownie
wykorzystać. Do wartości zmiennych odwołujemy się podając nazwę zmiennej. Nazwa zmiennej powinna rozpoczynać się literą, może składać się z liter, cyfr i kropek.
Istotna jest wielkość liter, więc zmienne x i X to dwie różne zmienne.
Do zmiennej można przypisać wartość jednym z trzech operatorów przypisania
(można też inaczej, ale o tym w uwadze na koniec tego podrozdziału):
• operator = przypisuje wartość znajdującą się z prawej strony do zmiennej znajdującej się po lewej stronie,
• operator <- jak wyżej,

• operator -> przypisuje wartość znajdującą się z lewej strony do zmiennej znajdującej się po prawej stronie.

Do zmiennej wartość można również przypisać korzystając z funkcji assign(base),
ale korzystanie z powyższych operatorów jest wygodniejsze. Poniżej różne przykłady
przypisania wartości.
c(13, 13) -> zmienna.z.kropka
imieN <- "Ola"
i2 = 4
assign("zmienna",14)

Jeżeli chcemy, by po przypisaniu wartość tego przypisania została wyświetlona
na ekranie, to operacje przypisania należy zamknąć w okrągłych nawiasach.
> (zmienna <- 2^10)
[1] 1024

Warto wspomnieć w tym miejscu o zmiennej .Last.value. Przechowuje ona
wynik ostatnio wykonanego polecenia. Ta zmienna może być bardzo przydatna, jeżeli
wykonaliśmy jakieś długo liczące się polecenie a nie zapisaliśmy jego wyniku.
W większości zastosowań operatory = i <- można stosować zamiennie.
Jednak nie zawsze mają one to samo działanie. Różnica pojawia się np.
gdy operatory te użyte są przy określaniu argumentu funkcji. Operator
= służy do wskazania, który argument funkcji określamy, operator  a = b = 5
#
> a <- b <- 5
#
> a = b <- 5
#
> a <- b = 5
#
Error in (a <- b)

wszystko ok, obie zmienne mają wartość 5
wszystko ok, obie zmienne mają wartość 5
wszystko ok, obie zmienne mają wartość 5
mamy problem, lewa strona operatora = nie jest zmienną
= 5 : could not find function "<-<-"

33

34

Łagodne wprowadzenie do R
1.5.6.4

Indeksy

Do elementów wektorów, list, macierzy i ramek danych możemy się odwoływać na
cztery różne sposoby. Przedstawiamy te sposoby poniżej wraz z krótkim opisem,
więcej szczegółowych informacji znaleźć można wpisując w R polecenie ?Extract.
Do elementów struktur danych możemy odwoływać się:
• W notacji wektorowej zmienna[zakres].
W tym przypadku zmienna jest listą, wektorem, macierzą lub ramką danych,
zakres jest wektorem liczb całkowitych lub jedną liczbą całkowitą. Wynikiem
jest lista(wektor) zawierająca wybrane elementy.
W przypadku indeksowania list, ramek danych lub wektorów z nazwanymi
elementami, możemy w nawiasach [] podać wektor nazw elementów. W tym
przypadku wybrane zostaną elementy o nazwach wskazanych przez wektor
indeksów—nazw.
Jeżeli zakres jest wektorem liczb ujemnych, to zwrócone będą wszystkie elementy z listy(wektora) POZA wskazanymi pozycjami. Nie można w zakres
mieszać indeksów dodatnich i ujemnych.
> wektor <- 1:10
> wektor
[1] 1 2 3 4 5 6 7 8 9 10
> wektor[1:3]
[1] 1 2 3
> wektor[c(-1,-3,-5)]
[1] 2 4 6 7 8 9 10
> wektor <- c(a=1, b=2, c=3)
> # indeksy nie muszą być liczbami, mogą być nazwami elementów
> wektor[c("a","c")]
a c
1 3

• W notacji macierzowej zmienna[zakres1,zakres2].
Gdzie zmienna jest macierzą lub ramką danych. Wybierana jest podmacierz
(ramka danych) o wskazanych indeksach. Jeżeli któryś z zakresów nie będzie
podany zostaną wybrane wszystkie elementy w danym wierszu/kolumnie.
> macierz <- matrix(1:4,2,2)
> macierz
[,1] [,2]
[1,]
1
3
[2,]
2
4
> macierz[1,]
# tylko pierwszy wiersz
[1] 1 3
> # tylko elementy poza pierwszym wierszem i pierwszą kolumną
> macierz[-1,-1]
[1] 4

Startujemy
Domyślnie, jeżeli wynikiem ma być pojedynczy wiersz lub kolumna, to „gubiony” jest wymiar macierzy, wynik nie jest już macierzą ale wektorem. Jeżeli
chcemy zagwarantować, że wynik będzie macierzą, to należy zmienić argument
drop. Poniżej przykład.
> macierz[1,]
[1] 1 3
> macierz[1,,drop=T]
[1] 1 3
> macierz[1,,drop=F]
[,1] [,2]
[1,]
1
3

# wynik jest wektorem
# wynik jest wektorem
# wynik jest macierzą

• W notacji listowej zmienna$wartosc1
Gdzie zmienna to lista, wektor lub ramka danych. Wynikiem zastosowania tego
operatora jest element listy/wektora (lub kolumna z ramki danych) o nazwie
wartosc1.
> osobnik <- list(name=c("Jan","Tomasz"), surname="Kowalski", age=25,
married=T)
> osobnik$name
[1] "Jan"
"Tomasz"
> osobnik[[2]]
[1] "Kowalski"

• W notacji nawiasowej zmienna[[indeks1]].
Gdzie zmienna to wektor, lista, macierz lub ramka danych. Wybierany jest
jeden element o indeksie indeks1 (indeks musi być pojedynczą liczbą, nie może być wektorem). Najczęściej ten sposób indeksowania wykorzystywany jest
do list. Pamiętajmy, że ramka danych też jest listą, dlatego użycie tego sposobu indeksowania na ramce danych spowoduje wybranie wskazanej kolumny
ramki danych, podczas gdy użycie tego indeksowania na macierzy spowoduje
wybranie jednej wartości z macierzy.
> macierz <- matrix(1:4,2,2)
> # drugi element macierzy to jedna liczba
> macierz[[2]]
[1] 2
> osobnik <- list(name=c("Jan","Tomasz"), surname="Kowalski", age=25,
married=T)
> # pierwszy element listy, wektor dwuelementowy
> osobnik[[1]]
[1] "Jan"
"Tomasz"

Przydatną funkcją przy operacjach na indeksach jest funkcja which(base). Jej
wynikiem są indeksy elementów spełniające zadany warunek logiczny. Jeżeli interesują nas indeksy wystąpień pewnego wektora elementów w innym wektorze możemy

35

36

Łagodne wprowadzenie do R
użyć funkcji match(base). Działa ona znacznie szybciej niż odpowiednia instrukcja
zapisana z użyciem funkcji which(). Podobne działanie do funkcji match() ma binarny operator %in%. Jego wynikiem jest wektor wartości logicznych określających
czy jakikolwiek element argumentu prawego wystąpił w danym elemencie argumentu
lewego (patrz poniższy przykład).
Jeżeli chcemy znaleźć indeks elementu minimalnego lub maksymalnego w wektorze, to możemy skorzystać z funkcji which.min(base), which.max(base). Ich
wynikami są indeksy pierwszego ekstremum.
> wektor = c(11, 13, 10.5, -3, 11, -3)
> which(wektor==10.5)
[1] 3
> match(c(11,10.5,-3), wektor)
[1] 1 3 4
> which(wektor<11)
[1] 3 4 6
> which(wektor == min(wektor)) # które najmniejsze
[1] 4 6
> which.max(wektor)
# który największy
[1] 2
> which.min(wektor)
# który najmniejszy
[1] 4
> # zmienna LETTERS to 26-elementowy wektor dużych liter
> LETTERS %in% c("A", "Z", "M", "G")
[1] TRUE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
[11] FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[21] FALSE FALSE FALSE FALSE FALSE TRUE

1.5.6.5

Operatory

W tabeli 1.6 przedstawiono najpopularniejsze operatory w języku R. Dla większości
operatorów istnieją również funkcje o identycznym działaniu, ale mniej wygodnym
zapisie. Np. wyrażenie 2+3 jest równoważne wyrażeniu sum(2,3). Można również
definiować własne operatory, co opiszemy w podrozdziale 1.6.2.5.
Tabela 1.6: Lista operatorów logicznych i arytmetycznych
+, - , *, /, ^

Standardowe operatory arytmetyczne. Oba argumenty powinny mieć taki sam wymiar (macierze lub wektory) lub jeden
z argumentów powinien być liczbą.
%x%
Iloczyn Kroneckera dwóch macierzy.
%%
Reszta modulo z dzielenia.
%/%
Dzielenie całkowite.
%*%
Iloczyn dwóch macierzy.
<, ==, >, <=, >=, != Standardowe operatory porównywania wartości liczbowych.
!
Operator negacji.
&, &&, |, ||
Logiczny iloczyn oraz logiczna suma.
any(), all()
Logiczna suma(iloczyn) wszystkich elementów wektora.

Startujemy

!!

!!

!!!

Logiczna suma odpowiada łącznikowi lub a logiczny iloczyn łącznikowi
i w języku polskim. Jeżeli ten komentarz dużo Ci nie rozjaśnił to znaczy, że nie potrzebujesz korzystać z tych operatorów i się nie przejmuj
(preferujemy bezstresowy sposób nauczania ; >).

Operatory & i | służą do wykonywania operacji na listach lub wektorach, podczas gdy && i || na pojedynczych wartościach. Warto przeanalizować co się dzieje
w poniższym przykładzie.
>
>
>
>
>

# podajemy dwa wektory wartości logicznych, kolejne wartości są nazwane
lubie.statystyke
= c(ala=FALSE, ola=TRUE, ewa=TRUE)
lubie.prowadzacego = c(ala=TRUE, ola=TRUE, ewa=FALSE)
# logiczne i dla kolejnych par elementów obu wektorów
lubie.statystyke & lubie.prowadzacego
ala
ola
ewa
FALSE TRUE FALSE
> # logiczne i dla wszystkich elementów obu wektorów
> lubie.statystyke && lubie.prowadzacego
[1] FALSE
> # logiczne lub dla kolejnych par elementów obu wektorów
> lubie.statystyke | lubie.prowadzacego
ala ola ewa
TRUE TRUE TRUE
> # logiczne lub dla wszystkich elementów obu wektorów
> lubie.statystyke || lubie.prowadzacego
[1] TRUE
> any(lubie.statystyke)
[1] TRUE

Pomiędzy operatorami || (&&) a | (&) istnieje jeszcze jedna różnica.
Operatory | i & stosują tak zwane „gorliwe wartościowanie”, czyli wyznaczają wartości wszystkich argumentów tych operatorów a następnie
wyznaczają logiczną sumę lub iloczyn. Operatory || i && stosują tak
zwane „leniwe wartościowanie”, czyli wyznaczają wartość drugiego argumentu, tylko jeżeli jest ona niezbędna do określenia wartości wyniku. W sytuacji gdy pierwszy
argument operatora || ma wartość TRUE (a dla operatora && wartość FALSE) nie jest
wyliczany drugi argument, ponieważ wynik operatora jest już znany. Warto pamiętać o tych różnicach. Leniwe i gorliwe wartościowanie to przydatny mechanizm ale
może być też źródłem błędów.

!!

!!!

!!

37

> wypiszImie <- function(imie) {cat(paste(imie, "\n")); T }
> wypiszImie("ala") | wypiszImie("ola")
ala
ola
[1] TRUE
> wypiszImie("ala") || wypiszImie("ola")
ala
[1] TRUE

Z uwagi na ochronę
danych osobowych,
imiona studentek
w tym przykładzie
zostały zmienione.

38

Łagodne wprowadzenie do R
1.5.6.6

Sekwencje liczb

Sekwencje to regularne wektory liczb całkowitych. Takie wektory można generować
używając operatora : lub funkcji seq(base). Kilka sposobów generowania sekwencji
przedstawimy poniżej.
> # z użyciem operatora :, generowana jest sekwencja liczb od ... od ...
z krokiem 1
> -2:2
[1] -2 -1 0 1 2
> 2:-2
[1] 2 1 0 -1 -2
> # poniższa wywołanie funkcji seq() równoważne jest wywołaniu 1:10
> seq(10)
[1] 1 2 3 4 5 6 7 8 9 10
> # podajemy zakres wektora, równoważne z użyciem 10:25
> seq(10, 25)
[1] 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
> # dodatkowo określamy krok, czyli o ile zwiększane są kolejne wartości
> seq(10,25,by=10)
[1] 10 20
> # możemy też określić pożądany wymiar wektora, funkcja seq() sama
zatroszczy się o wybór kroku
> seq(10, 25, length.out=10)
[1] 10.00000 11.66667 13.33333 15.00000 16.66667 18.33333 20.00000
[8] 21.66667 23.33333 25.00000

Przydatną funkcją do operowania na sekwencjach liczb (a także na zwykłych wektorach) jest funkcja sample(base). Losuje ona k-elementowy podzbiór (k to drugi
argument tej funkcji) z wektora danego jako pierwszy argument tej funkcji. Można
losować elementy ze zwracaniem (gdy trzeci argument replace=T) lub bez zwracania (gdy argument replace=F, ustawienie domyślne). Można też wskazać wektor
prawdopodobieństw (argument prob) określający prawdopodobieństwa wylosowania
poszczególnych elementów wektora. W poniższym przykładzie losowany jest dziesięcioelementowy wektor liter. Wykorzystano w tym przykładzie predefiniowany wektor
letters, czyli wektor małych liter z alfabetu romańskiego (inne ciekawe predefiniowane wektory to LETTERS – duże litery, month.name – nazwy miesięcy i month.abb
– trzyliterowe skróty nazw miesięcy).
> # wylosujmy dziesięć losowych liter
> sample(letters,10,T)
[1] "u" "q" "x" "s" "q" "f" "c" "f" "l" "x"
> # wylosujmy wektor cyfr od 1 do 3, z zadanymi prawdopodobieństwami
wylosowania
> sample(1:3,20,T, prob=c(0.6,0.3,0.1))
[1] 2 3 1 1 3 3 1 1 1 1 1 2 1 1 1 2 1 1 2 2

Startujemy
1.5.6.7

Komentarze

Język R, jak każdy przyzwoity (i wiele nieprzyzwoitych) języków programowania,
umożliwia komentowanie fragmentów kodu. Znakiem rozpoczęcia komentarza jest #.
Interpretator ignoruje ten znak i wszystkie po nim występujące aż do końca linii.

1.5.7

Wyświetlanie i formatowanie obiektów

Dwie najpopularniejsze funkcje do wyświetlania wartości obiektów to: cat(base)
i print(base). Funkcje te różnią się w działaniu. Aby je porównać zacznijmy od
przykładu, w którym wyświetlimy wektor 6 napisów.
> nap = rep(c("Ala ma kota", "Ola nie ma kota", "Ela chce mieć kota"),2)
> print(nap)
# wyświetlanie sformatowane
[1] "Ala ma kota"
"Ola nie ma kota"
"Ela chce mieć kota"
[4] "Ala ma kota"
"Ola nie ma kota"
"Ela chce mieć kota"
> cat(nap)
# wyświetlanie niesformatowane
Ala ma kota Ola nie ma kota Ela chce mieć kota Ala ma kota Ola nie ma kota

Ten sam wektor został inaczej wyświetlony przez każdą z tych funkcji. Funkcja
print() wyświetliła wektor w dwóch liniach (ponieważ w jednej się nie zmieścił),
na początku każdej linii zaznaczyła, który element wektora rozpoczyna tę linię.
Wyświetlone wartości są w cudzysłowach, dzięki czemu można rozpoznać ich typ.
Funkcja cat() wyświetliła cały wektor w jednej linii, bez żadnego dodatkowego
formatowania.
Podsumowując, funkcja cat() służy do wyświetlania niesformatowanego, funkcja
print() służy do wyświetlania sformatowanego. Funkcję print() można dowolnie
przeciążać (czyli możemy sami określać jak wyświetlane mają być obiekty różnych
klas), funkcji cat() przeciążać nie można.
Domyślnie, jeżeli w wyniku wykonania polecenia w R zostanie zwrócona
wartość, która nie zostanie przypisana do zmiennej, to wartość ta jest
wyświetlana z użyciem funkcji print().
Tak dzieje się zarówno dla prostych wyrażeń arytmetycznych, jak i dla
bardziej skomplikowanych obiektów będących wynikami np. funkcji statystycznych
(patrz wyniki testów statystycznych). Aby nasz kod był elastyczny, to oprogramowując pewną funkcjonalność, której wynik ma być specyficznie wyświetlony, powinniśmy tę funkcjonalność rozbić na dwie funkcje. Pierwsza funkcja zwróci obiekt
określonej klasy, a druga funkcja o nazwie print.klasa() będzie odpowiedzialna
za wyświetlenie tego obiektu.
W ten sposób działa większość funkcji statystycznych w R. Przykładowo wynikiem
funkcji summary() jest obiekt klasy summary. Sama funkcja summary() nic nie wyświetla, ale jeżeli wynik tej funkcji nie zostanie nigdzie przypisany, to automatycznie wywoływana jest funkcja print.summary() (przeciążony odpowiednik funkcji
print()) odpowiedzialna za wyświetlenie podsumowania. Więcej informacji o wykorzystywanym tu mechanizmie przeciążania znaleźć można w podrozdziale 1.6.2.3.

!!

!!

!!!

W pewnych sytuacjach możemy sobie nie życzyć, by wynik wyrażenia lub funkcji
był wypisywany na konsoli przez funkcję print() (co jak wspominaliśmy dzieje się
automatycznie, jeżeli wynik nie jest do czegoś przypisany). Można temu zapobiec

39

40

Łagodne wprowadzenie do R
korzystając z funkcji invisible(base). Działanie tej funkcji polega na tymczasowemu zapobiegnięciu wyświetlania jej argumentu w sytuacji gdy nie będzie on do
niczego przypisany. Prześledźmy poniższy przykład.
> # obie funkcje są tożsamościami
> I1 <- function(x) x
> I2 <- function(x) invisible(x)
> # wynik funkcji przypisujemy do zmiennej, w tym przypadku funkcja
invisible() nie ma żadnego efektu, dla obu funkcji obserwujemy to samo
zachowanie
> a <- I1(1)
> a
[1] 1
> a <- I2(1)
> a
[1] 1
> # wyniku funkcji nie przypisujemy do zmiennej, w tym przypadku funkcja
invisible() powoduje, ze wynik I2() nie jest wyświetlany
> I1(1)
[1] 1
> I2(1)

Funkcję cat() możemy również wykorzystać aby zapisywać obiekty do pliku
(zamiast wypisywać je na konsoli). Aby to zrobić należy argumentem file wskazać
ścieżkę do pliku, do którego zapisane mają być obiekty. Więcej o zapisywaniu do
plików przeczytać można w podrozdziale 1.6.5.1.
Do operacji na napisach w celu ich odpowiedniego wyświetlenia wykorzystuje się
również funkcje paste(base) i format(base). Funkcja paste() służy do łączenia
wektorów napisów, jej dwa argumenty sep=" " i collapse=NULL określają sposób
w jaki sklejane są argumenty tej funkcji. Poniżej kilka przykładów.
> # Funkcja paste() skleja argumenty w jeden łańcuch znaków
> paste("Ala", "ma", 5)
[1] "Ala ma 5"
> # parametrem sep, możemy określać, co ma separować kolejne argumenty
> paste("Ala", "ma", 5, sep="; ")
[1] "Ala; ma; 5"
> # jeżeli argumenty mają różną długość, to zadziała recycling rule
(omówimy ją później)
> paste("Jeszcze", 3:0, "...")
[1] "Jeszcze 3 ..." "Jeszcze 2 ..." "Jeszcze 1 ..." "Jeszcze 0 ..."
> # wynikiem sklejenia dwóch wektorów będzie wektor
> paste(1:5, letters[1:5], sep=" * ")
[1] "1 * a" "2 * b" "3 * c" "4 * d" "5 * e"
> # chyba, że określimy argument collapse, co spowoduje, że elementy tego
wektora zostaną połączone
> paste(1:5, letters[1:5], sep=",", collapse="; ")
[1] "1,a; 2,b; 3,c; 4,d; 5,e"

Startujemy
Funkcja format() służy do konwersji danego obiektu na typ znakowy zgodnie
z ustalonym formatowaniem. Przy konwersji można określić, ile pól po kropce ma
być wypisywanych, czy tekst ma być justowany do lewej czy do prawej, czy ma być
wykorzystana notacja naukowa (z suffixem e+) itp. Poniżej kilka przykładów użycia
tej funkcji.
> format(11/3)
[1] "3.666667"
> # wyświetlmy tę liczbę w notacji naukowej
> format(11/3, sci = TRUE)
[1] "3.666667e+00"
> # wyświetlmy tę liczbę z maksymalnie dwoma cyframi znaczącymi
> format(11/3, digits = 2)
[1] "3.7"
> # wyświetlmy te liczby z dwoma miejscami po kropce dziesiętnej
> format(c(12,21)/3, nsmall = 2)
[1] "4.00" "7.00"
> format(c(12,21)/3, digits = 2, nsmall = 1)
[1] "4.0" "7.0"

Funkcji do formatowania wyników jest znacznie więcej, np. bardzo przydatna jest
funkcja sprintf(base), która ma podobny sposób formatowania do funkcji o tej samej nazwie w języku C. Informacji o innych funkcjach do formatowania można szukać
np. w plikach pomocy do funkcji toString(base) i encodeString(base). Przedstawimy tutaj jeszcze tylko jeden przykład, dotyczący funkcji formatFix(cwhstring).
Konwertuje ona wektor liczb (pierwszy argument) na napisy o formacie określonym
przez pozostałe argumenty.
> require(cwhstring)
> # argument after określa liczbę miejsc po kropce a before przed kropką,
w wynikowym wektorze wszystkie napisy mają taką samą długość
> formatFix(c(pi, exp(1), 1, 1/pi),after=3, before=3)
[1] " 3.142" " 2.718" " 1.000" " 0.318"

Funkcja require(base) ładuje bibliotekę, podobnie jak funkcja
library(base). Różnica pojawia się w sytuacji, gdy danej biblioteki
nie ma lub są z nią problemy. Domyślnie funkcja library() sygnalizuje błąd, co przerywa wykonywanie podprogramu, podczas gdy funkcja
require() sygnalizuje ostrzeżenie, ale pozwala na kontynuację wykonywania podprogramu. Wynikiem funkcji require() w sytuacji gdy żądana biblioteka nie jest
dostępna jest wartość FALSE. Używając tej funkcji, programista może zaplanować
awaryjne rozwiązanie, na wypadek braku danego pakietu.
Oczywiście, próba wywołania funkcji z pakietu, który nie został załadowany, zakończy się błędem.

!!

!!

!!!

41

42

Łagodne wprowadzenie do R

1.6
Can one be a good
data analyst
without being
a half-good
programmer? The
short answer to that
is, ’No.’ The long
answer to that is,
’No.’
Frank Harrell
fortune(52)

Przyśpieszamy

Po lekturze tego rozdziału czytelnik będzie już całkowicie gotów do korzystania z R.
W kolejnych podrozdziałach przedstawimy składnię języka R, funkcje do operacji na
danych, wprowadzenie do grafiki oraz podstawowe statystyki opisowe. Zakładamy,
że czytelnik opanował materiał przedstawiony w poprzednich podrozdziałach.

1.6.1

Instrukcje warunkowe i pętle

Wiemy już jak pisać proste programy, w których instrukcje wykonywane są jedna po
drugiej. Korzystając z instrukcji warunkowych i pętli możemy sterować przepływem
wykonywania programu.
1.6.1.1

Instrukcja warunkowa if ... else ...

W języku R, tak jak w większości języków programowania, mamy możliwość korzystania z instrukcji if else. Umożliwia ona warunkowe wykonanie fragmentu kodu w zależności od prawdziwości pewnego warunku logicznego. Składnia instrukcji
if else jest następująca:
if (war)
instr1
# lub
if (war)
instr1

else

instr2

Fragment instrukcji warunkowej począwszy od słowa else jest nieobowiązkowy.
Jeżeli wartość warunku logicznego war jest prawdziwa (logiczna równa TRUE lub
liczbowa różna od 0), to wykonana zostanie instr1, jeżeli nie, to wykonana będzie
instr2 (o ile podano wariant z else). Zarówno instr1 jak i instr2 mogą być
zastąpione blokiem instrukcji (instrukcjami otoczonymi nawiasami {}).
Zobaczmy, jak to wygląda na poniższym przykładzie.

Autor spodziewa się,
że czytelnik nie
wierzy na słowo,
tylko sprawdzi
jakim komunikatem
zakończy się
wpisanie tych
poleceń.

> liczba = 1313
> # zapis ’liczba %% 2 == 0’ oznacza sprawdzenie, czy reszta z dzielenia
prez 2 ma wartość 0, jezeli tak jest, to to wyrażenie przyjmuje
wartość TRUE, w przeciwnym razie wartość FALSE
> if (liczba %% 2 == 0) {
+
cat("ta liczba jest parzysta\n")
+ } else {
+
cat("ta liczba jest nieparzysta\n")
+ }
ta liczba jest nieparzysta

Należy uważać, by słowo kluczowe else nie rozpoczynało nowej linii. Błędem
zakończy się następujący ciąg poleceń:

Przyśpieszamy

# ta wersja nie będzie działała
if (1==0)
cat("to nie może być prawda")
else
cat("co się wyświetli?")

Dlaczego? Jak pamiętamy R to język interpretowany. Po zakończeniu drugiej linii tego przykładu interpreter nie spodziewa się kolejnych instrukcji, dlatego wykona
(w jego mniemaniu już kompletną) instrukcję warunkową. Przechodząc do trzeciej
linijki o instrukcji if już nie pamięta, dlatego zostanie zgłoszony błąd składni. Poprawne użycie instrukcji if z wariantem else jest następujące:
# ta wersja będzie działała
if (1==0) {
cat("to nie może być prawda")
} else {
cat("co się wyświetli?")
}
# podobnie jak ta
if (1==0)
cat("to nie może być prawda") else
cat("co się wyświetli?")

1.6.1.2

Funkcja ifelse(base)

Powyżej omówiona instrukcja warunkowa bierze pod uwagę wartość tylko jednego
warunku logicznego. Funkcja ifelse() pozwala na wykonanie ciągu działań w zależności od wektora warunków logicznych. Składnia tej funkcji jest następująca:
ifelse(war, instr1, instr2)

Warunek war może być jedną wartością logiczną lub wektorem wartości logicznych. W wyniku wykonania tej funkcji zwrócona zostanie wartość lub wektor. Wynik
będzie miał wartości opisane przez instr1 w pozycjach odpowiadających wartości
TRUE wektora war oraz wartości opisane przez instr2 w pozycjach odpowiadających
wartości FALSE wektora war. Prześledźmy wyniki poniższych przykładów.
> # pierwszy argument jest wektorem
> ifelse(1:8 < 5, "mniej", "wiecej")
[1] "mniej" "mniej" "mniej" "mniej" "wiecej" "wiecej" "wiecej" "wiecej"
> # wszystkie argumenty są wektorami
> ifelse(sin(1:5)>0, (1:5)^2, (1:5)^3)
[1]
1
4
9 64 125
> # wszystkie argumenty to pojedyncze wartości
> ifelse(1==2, " cos jest nie tak", "uff")
[1] "uff"

43

Ale uwaga! Jeżeli te
instrukcje znalazły
by się w ciele
funkcji, to błąd nie
zostałby zgłoszony,
wszystko by
działało!
Interpreter to
program
interpretujący
instrukcje zapisane
w języku
programowania na
rozkazy rozumiane
przez procesor.
Interpreter języka R
jest integralną
częścią platformy R.

Łagodne wprowadzenie do R
1.6.1.3

Funkcja switch(base)

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.
> dane = 1313
> # w poniższej instrukcji sprawdzana jest klasa zmiennej dane, ta klasa
to ’numeric’, ponieważ zmienna ’dane’ przechowuje liczbę, dlatego też
wykona się wyłącznie druga akcja
> switch(class(dane),
+
logical = ,
+
numeric = cat("typ liczbowy lub logiczny"),
+
factor = cat("typ czynnikowy"),
+
cat("trudno okreslic")
+ )
typ liczbowy lub logiczny

Jeżeli wartość klucza (pierwszego argumentu funkcji switch()) nie pasuje do
etykiety żadnego z kolejnych argumentów, to wynikiem instrukcji switch() jest
wartość argumentu nie nazwanego (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 2.1.9). Zwykłe 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() wyznaczone byłyby wartości
wszystkich argumentów, czyli wykonane byłyby wszystkie funkcje cat(). Tak się
jednak (na szczęście) nie dzieje, ponieważ w tym przypadku argumenty przekazywane są w sposób leniwy i funkcja switch() sama decyduje, którą z instrukcji wykonać
(wartość którego z argumentów wyznaczyć).

!!

!!!

!!

44

Przyśpieszamy
1.6.1.4

45

Pętla for

Najpopularniejszą pętlą w większości języków programowania jest pętla for. W języku R ta pętla również jest dostępna ale korzysta się inaczej niż w większości języków
programowania. Poniżej przedstawiamy składnię pętli for.
for (zmien in wekt)
instr

Jeżeli chcemy w każdym wykonaniu pętli wykonać więcej poleceń, to instr można zastąpić blokiem instrukcji. Ta instrukcja lub blok instrukcji będzie wykonana
tyle razy ile elementów ma wektor wekt. Zmienna zmien w każdym okrążeniu pętli
przyjmować będzie kolejną wartość z tego wektora. Zacznijmy od przykładu.
> # ta pętla wykona się dla każdego elementu wektora 1:4
> for (i in 1:4) {
+
cat(paste("aktualna wartosc i to ", i, "\n"))
+ }
aktualna wartosc i to 1
aktualna wartosc i to 2
aktualna wartosc i to 3
aktualna wartosc i to 4

Elementy wektora wekt mogą być dowolnego typu. Poniżej umieszczamy przykład, w którym indeks funkcji przebiega po wartościach wektora napisów.
> indeksy = c("jablka","gruszki","truskawki","pomarancze")
> # ta pętla wykona się dla każdego elementu wektora ’indeksy’
> for (i in indeksy) {
+
cat(paste(i, "\n"))
+ }
jablka
gruszki
truskawki
pomarancze

Pętla for nie wymaga by elementy wek były różne ale warto o to zadbać. Ułatwia to śledzenie ewentualnych błędów, wystarczy bowiem wypisać, w którym kroku
pętli wystąpił błąd. W większości przypadków wygodnie jest za wekt podać wektor
kolejnych liczb całkowitych. Umożliwia to zapisywanie wyników z kolejnych okrążeń
pętli w wektorze lub w macierzy.
W wielu sytuacjach do wyznaczania wektora indeksów pętli wygodnie jest się
posłużyć funkcją seq_along(base). Argumentem tej funkcji jest wektor dowolnych
wartości a wynikiem jest wektor kolejnych liczb naturalnych od 1 do długości wektora
będącego argumentem. Poniższy kod będzie miał identyczny wynik jak przykład
z owocami powyżej ale pętla indeksowana jest liczbami naturalnymi. Posługując się
liczbowym indeksem i możemy wyniki zapisywać do macierzy lub innego obiektu,
którego nie można indeksować nazwami owoców.

Co więcej, wekt nie
musi być wektorem,
może być listą,
której elementy są
różnego typu!

46

Łagodne wprowadzenie do R

> # ta pętla wykona się dla każdego elementu wektora ’indeksy’ ale zmienna
’i’ nie będzie przyjmowała za wartości elementów tego wektora ale
jego indeksy. Innymi słowy w pierwszym wywołaniu wartością ’i’ nie
będzie wartość ’jablka’ ale wartość ’1’
> for (i in seq_along(indeksy)) {
+
cat(paste(indeksy[i], "\n"))
jablka
gruszki
truskawki
pomarancze

Zazwyczaj podobny efekt do pętli for możemy uzyskać stosując funkcje z rodziny *apply() (np. lapply()). Funkcje te będą przedstawione w podrozdziale 2.1.3.
Żadne z tych rozwiązań nie jest absolutnie lepsze, można więc korzystać z dowolnego z nich w zależności od tego, które jest łatwiej w konkretnej sytuacji zastosować
(zapisać). Najczęściej jednak używając funkcji z rodziny *apply() otrzymuje się
bardziej elegancki zapis, w wielu przypadkach też wynik wyznaczony będzie szybciej
ponieważ R jest optymalizowany do pracy na wektorach.
1.6.1.5

Pętla while

Pętla for ma z góry określoną liczbę powtórzeń do wykonania (wyznaczoną przez
długość wektora wekt). W pewnych sytuacjach nie wiemy ile powtórzeń pętli będzie
wymaganych, aby uzyskać zamierzony efekt. W takich sytuacjach wygodniej jest
wykorzystać pętlę while. Poniżej przedstawiamy jej składnię.
while (war) instr

Instrukcja instr będzie wykonywana tak długo, dopóki warunek war jest prawdziwy. Oczywiście, należy zadbać o to, by taka sytuacja kiedykolwiek zaistniała
a więc by pętla się zakończyła. Poniżej przykład z wykorzystaniem pętli while.
> i=0
> # pętla będzie się wykonywać póki warunek ’i<3’ będzie prawdziwy
> while(i < 3) {
+
cat(paste("juz",i,"\n"))
+
i = i+1
+ }
juz 0
juz 1
juz 2

1.6.1.6

Pętla repeat

W języku R istnieje też trzeci rodzaj pętli. Przyznam, że niechętnie o nim piszę
i raczej bym go nie polecał. Tą czarną owcą jest pętla repeat, której składnia przedstawiona jest poniżej.

Przyśpieszamy

47

repeat instr

Działanie tej pętli polega na powtarzaniu instrukcji instr 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). Poniżej przykład
z użyciem tej czarnej owcy.
> # pętla repeat nie ma określonego warunku stopu, przerwać ją może
wywołanie polecenia break lub interwencja użytkownika
> repeat {
+
cat("uda sie czy nie?\n")
+
if (runif(1)<0.1)
+
break
+ }
uda sie czy nie?
uda sie czy nie?

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.

1.6.2

Funkcje

Często w dużych programach pewne fragmenty kodu powtarzają się wielokrotnie
i/lub są używane w różnych miejscach naszego programu. 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 poprawi jego
czytelność. Generalnie rzecz biorąc zamykanie kodu w funkcjach jest dobrym zwyczajem, umożliwia tzw. reużywalność kodu a tym samym wpływa na zmniejszenie
liczby błędów, które zawsze gdzieś w kodzie się znajdą. Jest wiele wskazówek jak
pisać dobre funkcje, ponieważ jednak nie jest to podręcznik do informatyki 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). Funkcje powinny być możliwie krótkie, ułatwi to ich modyfikacje
i śledzenie. Jeżeli jakaś funkcja znacznie się rozrosła, to z pewnością można i warto
podzielić ją na mniejsze funkcje. Poniżej przedstawiamy schemat deklaracji funkcji.
function(listaArgumentow)
instr

Instrukcje instr można zastąpić blokiem instrukcji. Lista argumentów funkcji
może być pusta, poniżej zamieszamy przykład deklaracji i wykonania funkcji bez
argumentów. Funkcje w języku R są traktowane jak zwykłe obiekty. Konsekwencje
takiego rozwiązania zostaną szczegółowo przedstawione później. Poniżej przykład.

Moim zdaniem,
korzystanie z tego
sposobu kończenia
pętli jest w bardzo
złym stylu.

Łagodne wprowadzenie do R

> # określamy funkcję i przypisujemy ją do zmiennej funkcja1
> funkcja1 = function() {
+
cat("Dzisiaj jest ")
+
cat(format(Sys.time(), "%A %B %d"))
+ }
> # zobaczmy jak działa ta funkcja
> funkcja1()
Dzisiaj jest poniedziałek listopad 05
> # przypisujemy do zmiennej funkcja2 wartość zmiennej funkcja1, a więc
naszą funkcję
> funkcja2 = funkcja1
> # możemy ją wywołać tak samo, jak funkcję funkcja1
> funkcja2()
Dzisiaj jest poniedziałek listopad 05

Na początku tego przykładu zdefiniowana została funkcja, która następnie została przypisana do zmiennej funkcja1. Ta zmienna jest teraz zmienną typu funkcyjnego. Aby edytować ciało zmiennej możemy posłużyć się funkcją edit(utils)
lub fix(utils). Poniższy przykład spowoduje otwarcie okienka edycyjnego, umożliwiający edycję ciała funkcji.
edit(funkcja1)

!!

!!!

!!

48

Z punktu widzenia R, funkcja jest takim samym obiektem jak każdy
inny obiekt. Nazwa funkcji nie jest związana z jej definicją a jedynie
z nazwą zmiennej, w której ta funkcja jest zapamiętana.

Jeżeli chcemy by do definiowanych funkcji można było przekazywać argumenty, to w deklaracji funkcji należy umieścić nazwy tych argumentów w wektorze
listaArgumentow rozdzielając je przecinkami.
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(). Prześledźmy poniższy przykład.
> # definiujemy nową funkcje, wykorzystaną tutaj funkcję sort opiszemy w
innym miejscu
> wyswietl3Najmniejsze <- function(wektor) {
+
posortowane <- sort(wektor)
+
posortowane[1:3]
+}
> lLiczby <- c(11, 3, 10, 1, 0, 8)
> # wywołujemy naszą funkcję
> (wynik <- wyswietl3Najmniejsze(lLiczby))
[1] 0 1 3

Przyśpieszamy
Nazwy argumentów funkcji potrafią być długie, jednak nie trzeba ich całych podawać! Zamiast pełnej nazwy argumentu wystarczy podać fragment nazwy taki, który jednoznacznie identyfikuje argument.
Podobny mechanizm funkcjonuje gdy argument może przyjąć wartość
z pewnego zbioru wartości. W tym przypadku nie trzeba wskazywać pełnej nazwy
wybranej wartości, wystarczy taki fragment, który jednoznacznie określa o którą wartość chodzi. Za takie częściowe dopasowanie odpowiedzialna jest funkcja
match.arg(base). Przykład mechanizmu skrótów przedstawiony jest poniżej.

!!

!!

!!!

> # deklarujemy funkcje z dwoma argumentami
> funkcja <- function(liczba = 5, poziom = "sredni")
+
cat(paste(liczba, poziom,"\n"))
> funkcja(3, "duzy")
# wywołanie z jawnym wskazaniem obu arg.
3 duzy
> funkcja(po="duzy")
# wskazujemy drugi argument skrótem nazwy
5 duzy
> funkcja(p="maly", li=1313) # wskazujemy skrótami oba argumenty
1313 maly

1.6.2.1

Argumenty domyślne

Definiując funkcje możemy określić domyślne wartości dla kolejnych argumentów
funkcji. Jeżeli to uczynimy, to gdy przy wywołaniu funkcji dany argument nie będzie
jawnie podany, wykorzystana będzie jego domyślna wartość.
Wywołując funkcję, wartości jej argumentów możemy podawać w dowolnej kolejności. Jeżeli jednak zrezygnujemy z kolejności określonej w liście argumentów, to
poprzez nazwę musimy wskazać, który argument wprowadzamy. Gdy argumentów
domyślnych jest więcej możemy w wywołaniu funkcji pomijać te, których modyfikować nie chcemy a w liście argumentów zamiast wartości zostawić puste miejsce.
Wszystkie te możliwości zostały przedstawione w poniższym przykładzie.
>
>
+
+
+
>

# deklarujemy funkcje z trzema argumentami
wyswietlNajmniejsze <- function(wektor, do = 3, od = 1) {
posortowane <- sort(wektor)
posortowane[od:do]
}
# możemy wywołać tę funkcję z dowolną kombinacją i kolejnością
argumentów, poniżej określamy tylko pierwszy argument, pozostałe będą
domyślne
> wyswietlNajmniejsze(lLiczby)
[1] 0 1 3
> # określamy dwa pierwsze argumenty
> wyswietlNajmniejsze(lLiczby, 5)
[1] 0 1 3 8 10
> # określamy dwa argumenty, pierwszy i trzeci (musimy go wskazać przez
nazwę)
> wyswietlNajmniejsze(lLiczby, od = 5)
[1] 10 8 3

49

50

Łagodne wprowadzenie do R

> # kolejność argumentów może być dowolna
> wyswietlNajmniejsze(do = 5, wektor = lLiczby)
[1] 0 1 3 8 10
> # domyślne argumenty możemy pomijać zostawiając puste miejsce w liście
argumentów
> wyswietlNajmniejsze(losoweLiczby, , 3)
[1] 3

W deklaracji funkcji nie trzeba specyfikować nazw jej wszystkich możliwych argumentów, o ile nie są one wykorzystywane w danej funkcji. Jeżeli chcemy pozostawić
możliwość podawania dodatkowych argumentów do funkcji, to w liście argumentów
można umieścić ’...’ (wielokropek). Te nadmiarowe, nie wymienione z nazwy argumenty nie będą wykorzystane w ciele tej funkcji ale mogą być przekazane dalej
w wewnętrznych wywołaniach kolejnych funkcji.
Poniżej przedstawiamy przykład wywołania funkcji z nadmiarowymi argumentami, które koniec końców zostaną przekazane do funkcji plot().
>
>
+
+
+
>

Przekazywanie argumentów w ten sposób jest bardzo wygodne przy pisaniu wrapperów. Nie trzeba wtedy jawnie podawać (być może bardzo długiej) listy wszystkich
argumentów opakowywanej funkcji.
Nie tylko twórca funkcji może wskazywać wartości domyślne dla argumentów tej funkcji. Może to zrobić też użytkownik, określając jakie
wartości mają być uznawane za domyślne. Można to zrobić korzystając z funkcji options(base), pozwalającej na globalne określanie domyślnych wartości dla pewnych argumentów lub korzystając z pakietu Defaults
umożliwiającego ustawianie domyślnej wartości dla argumentów wskazanej funkcji.

!!

!!!

!!

Wrapper to funkcja
opakowująca inną,
standardową
funkcję. Wrappery
są wykorzystywane
najczęściej po to,
aby ujednolicić
sposób
wywoływania
interesujących nas
funkcji.

# nadmiarowe argumenty zostaną przekazane do funkcji plot()
narysujNajmniejsze <- function(wektor, ile = 3, ...) {
posortowane <- sort(wektor)
plot(posortowane[1:ile], ...)
}
# wywołujemy funkcję narysujNajmniejsze() z dodatkowymi argumentami (lwd
type i col) nie wymienionymi jawnie w liście argumentów
> narysujNajmniejsze(lLiczby, ile=20, lwd=3, type="l", col="black")

1.6.2.2

Funkcje anonimowe

W pewnych sytuacjach wygodnie jest jako argument funkcji podać funkcję. Można to zrobić na różne sposoby. Jedną z możliwości jest zdefiniowanie takiej funkcji
wcześniej, przypisanie jej do jakiejś zmiennej i podanie jako argument danej zmiennej. Ponieważ w tym przypadku nazwa zmiennej nie ma żadnego znaczenia, dlatego
nie musimy jej podawać, wygodniej jest podać ciało funkcji bezpośrednio jako argument. Mówimy w tym przypadku o funkcji anonimowej, ponieważ nie jest ona
przypisana do żadnej zmiennej, przez co też nie ma nazwy. Wykorzystanie funkcji
anonimowych obrazuje poniższy przykład. Korzystamy tu z funkcji sapply(), która
wykonuje zadaną funkcję (drugi argument funkcji sapply()) dla każdego elementu
wektora lub listy (pierwszy argument funkcji sapply()).

Przyśpieszamy

51

> # przykładowe wywołanie funkcji sapply
> pewnaFunkcja <- function(x) {
+
x^2 + 3
+ }
> sapply(c(1,2,3), pewnaFunkcja)
[1] 4 7 12
>
> # wywołanie funkcji sapply z użyciem funkcji anonimowych
> sapply(c(1,2,3), function(x) x^2+3)
[1]
4
7 12

Przekazywanie funkcji jako argumentu może wyglądać egzotycznie ale jak przekonamy się w kolejnych podrozdziałach jest to wyjątkowo przydatny mechanizm
dający wiele możliwości.
1.6.2.3

Polimorficzność funkcji

Kolejnym mechanizmem zwiększającym możliwości R jest możliwość definiowania
funkcji polimorficznych. Mechanizm ten, nazywany też przeciążaniem funkcji, pozwala na imitowanie pewnych cech języka obiektowego.
Przypuśćmy, że chcemy przeciążyć funkcję plot() a więc sprawić, aby dla określonych argumentów, funkcja ta zachowywała się w specyficzny, określony sposób
(nie każdą funkcję można przeciążyć ale do tego tematu wrócimy w podrozdziale
2.1.7). W tym celu należy zdefiniować nową funkcje i przypisać ją do zmiennej o nazwie plot.typ, gdzie typ to nazwa pewnego typu (klasy, np. factor). Wywołanie
funkcji o nazwie bez suffiksu .typ ale z argumentem klasy typ spowoduje wywołanie
funkcji z suffiksem .typ.
Przykładowo, funkcja plot() zazwyczaj rysuje coś na ekranie. Możemy jednak
zażyczyć sobie aby w zależności od klasy argumentu zachowywała się inaczej. Poniżej
przedstawiamy przykład, w którym funkcja plot() została tak przeciążona, by dla
argumentów o typie logicznym zamiast rysować wypisywała wartość argumentu.
>
>
+
+
>

# deklarujemy funkcję o nazwie ’plot.logical’
plot.logical <- function( obj) {
cat(ifelse(obj,"prawda","nieprawda"))
}
# funkcja ’plot.logical’ będzie wywołana, jeżeli za nazwę funkcji podamy
’plot’ a argument będzie typu ’logical’
> plot(1:10<3)
prawda prawda nieprawda nieprawda nieprawda nieprawda nieprawda nieprawda
nieprawda nieprawda

Pamiętamy, że korzystając z funkcji class() możemy dowolnie modyfikować nazwę klasy danego obiektu. Dzięki tej możliwości i dzięki mechanizmowi przeciążania
funkcji możemy tworzyć obiekty określonej klasy i przeciążać dla nich podstawowe
funkcje. Jeżeli tak zrobimy, to inni użytkownicy będą mogli w intuicyjny sposób
korzystać z naszych nowych funkcjonalności.
W ten sposób działają funkcje plot() i summary() dla takich typów jak lm,
factor, formula itp. Jeżeli argumentem funkcji summary() jest obiekt klasy lm,

Jeżeli ktoś nie lubi
słowa
polimorficzność, to
niech lepiej nie czyta
tego podrozdziału.

52

Łagodne wprowadzenie do R
to uruchamiana jest funkcja summary.lm(), która prezentuje w tekstowej postaci
poszczególne elementy modelu liniowego (do tego tematu wrócimy w części poświęconej statystyce). Innymi, często przeciążanymi funkcjami są predict(), anova(),
print() oraz operatory.
Korzystając z funkcji methods() możemy sprawdzić, czy zadeklarowane są jakieś przeciążone wersje interesującej nas funkcji lub też, czy są przeciążone funkcje dla jakiejś interesującej nas klasy. Warto zobaczyć jaki jest wynik polecenia
methods(plot) aby przekonać się jak wiele jest przeciążeń funkcji plot().
> # lista przeciążeń funkcji plot
> methods(plot)
[1] plot.acf*
plot.agnes*
[4] plot.data.frame*
plot.Date*
[7] plot.default
plot.dendrogram*
[10] plot.diana*
plot.ecdf
[13] plot.formula*
plot.hclust*
[16] plot.lm
plot.mca*
[19] plot.mlm
plot.mona*
[22] plot.POSIXct*
plot.ppr*
[25] plot.princomp*
plot.profile*

plot.correspondence*
plot.decomposed.ts*
plot.density
plot.factor*
plot.histogram*
plot.medpolish*
plot.partition*
plot.prcomp*
plot.table*

Non-visible functions are asterisked

Nie każda funkcja może być przeciążona. Aby R wiedział, że jakaś funkcja jest generyczna (czyli może być przeciążana) należy to określić używając funkcji UseMethod().
Kompletny opis działania tej funkcji (a zarazem technicznych aspektów działania
funkcji przeciążanych) wykracza poza zakres tej książki, ograniczmy się więc jedynie
do przykładu. W poniższym przykładzie funkcja rozmiar() wyznacza i przekazuje
liczbę elementów w danym obiekcie, bez względu czy jest to wektor, macierz czy
ramka danych.
> # wskazujemy, że funkcja rozmiar będzie przeciążana
> rozmiar = function(x) UseMethod("rozmiar")
> # opisujemy jej domyślne zachowanie
> rozmiar.default
= function(x) length(x)
> # specyfikujemy jej zachowanie dla konkretnych typów argumentów
> rozmiar.character = function(x) length(x)
> rozmiar.matrix
= function(x) dim(x)[1] * dim(x)[2]
> rozmiar.array
= function(x) prod(dim(x))
>
> # krótki test, wywołujemy tę funkcję dla wektora
> rozmiar(10:1)
[1] 10
> # wywołujemy funkcję ’rozmiar’ dla macierzy
> rozmiar(matrix(0,10,10))
[1] 100

Przyśpieszamy
1.6.2.4

Funkcje a zasięg

Każdy z trzech operatorów ->, <- i = przypisuje wartości do zmiennej o lokalnym
zasięgu (w aktualnym środowisku używając terminologii R). A więc taki operator
użyty w funkcji zmienia wartość zmiennej lokalnie w funkcji. W języku R są dostępne
również dwa inne operatory przypisania, mianowicie ->> i <<-. Ich działanie różni
się tym, że przypisują wartość do zmiennej o zasięgu globalnym, a więc zmiany
widoczne są poza zakresem funkcji. Warto przeanalizować poniższy przykład.
> # definiujemy nową funkcję, w której będziemy przypisywać wartości
> przyklad1 <- function() {
+
# pierwsze przypisanie to normalne, lokalne przypisanie
+
zmienna1 <- 2
+
# drugie przypisanie to globalne przypisanie, modyfikowana jest
zmienna w zewnętrznej przestrzeni nazw
+
zmienna2 <<- 2
+
cat(paste("zmienna1:",zmienna1,"zmienna2:",zmienna2,"\n"))
+ }
> # zainicjujmy wartość dwóch zmiennych
> zmienna1 = 1
> zmienna2 = 1
> # stan zmiennych globalnych przed uruchomieniem funkcji
> cat(paste("zmienna1:",zmienna1,"zmienna2:",zmienna2,"\n"))
zmienna1: 1 zmienna2: 1
> # stan zmiennych lokalnych wewnątrz funkcji
> przyklad1()
zmienna1: 2 zmienna2: 2
> # stan zmiennych globalnych po uruchomieniu funkcji
> cat(paste("zmienna1:",zmienna1,"zmienna2:",zmienna2,"\n"))
zmienna1: 1 zmienna2: 2

Operator = powinien być stosowany tylko w „najbardziej zewnętrznym”
poziomie zagnieżdżenia (tam jest równoważny operatorom <- i ->). Jeżeli wywołujemy funkcję, to w specyfikacji jej argumentów operatory = i  # ta instrukcja się nie wykona,
> # zostanie zinterpretowana jako próba wskazania wartości argumentu o
nazwie ’liczby’, który nie jest argumentem funkcji plot()
> plot(liczby = 1:100)
Error in plot(liczby = 1:100) : argument "x" is missing, with no default
> # ta instrukcja wykona się poprawnie, operacja podstawienia przekazuje
wynik i to on będzie narysowany na ekranie
> plot(liczby <- 1:100)

53

54

Łagodne wprowadzenie do R
1.6.2.5

Własne operatory

Kolejnym rozszerzeniem języka R, jest możliwość definiowania własnych operatorów.
Operatorem w R może być dowolny ciąg znaków otoczony znakami %. Z technicznego
punktu widzenia operatory są zwykłymi funkcjami, różnią się jedynie metodą ich
wywołania. Poniżej przykład zdefiniowania i użycia operatora %v%.
> # definiujemy operator tak jak zwykłą funkcję dwuargumentową
> "%v%" <- function(x,y)
+
x*y+x+y
> # używamy w sposób typowy dla operatorów
> 1 %v% 2
[1] 5

1.6.2.6

Inne zagadnienia związane z funkcjami

Ponieważ funkcje to zwykłe obiekty zatem nic nie stoi na przeszkodzie w definiowaniu
funkcji zagnieżdżonych.
> # przykład dla zagnieżdżonych funkcji
> zewnetrzna <- function(x) {
+
wewnetrzna <- function(x) {
+
print(x)
+
}
+
wewnetrzna(x)
> }

Możemy również funkcję zapisać do pliku, np. funkcją save(base)!
W R jest bardzo wiele użytecznych funkcji. W tej książce przedstawiamy tylko
ułamek z wielkiego zbioru wszystkich funkcji (jak duży to zbiór łatwo ocenić przeglądając liczbę wpisów w skorowidzu). Rozdział ten zamkniemy przedstawieniem
jeszcze dwóch ciekawych funkcji, mianowicie: .First(base) i .Last(base). Funkcje
te są wywoływane odpowiednio na samym początku pracy oraz przed zamknięciem
środowiska R. Możemy definiować własne wersje tych funkcji, personalizując tym
samym środowisko R. Poniżej przykład zmiany definicji tych funkcji.
>
>
>
>
>
>

# co R ma robić po uruchomieniu środowiska?
.First <- function()
options(prompt="# ", continue="- \t")
# co R ma robić przed zamknięciem środowiska?
.Last <- function()
cat("baj baj")

Jeżeli wprowadzimy te funkcje a następnie zapiszemy całe środowisko w domyślnym workspace (jest on ładowany przy każdym uruchomieniu R), to przy kolejnym
uruchomieniu R wykona się funkcja .First(). W powyższym przykładzie zmienia
ona między innymi znak zachęty ze znaku > na znak #. Przy zamykaniu R wykona
się funkcja .Last(), która wyświetli dwa słowa pożegnania.

Przyśpieszamy

1.6.3

Zarządzanie obiektami w przestrzeni nazw

Przestrzeń nazw to zbiór nazw wszystkich zmiennych, które zostały zadeklarowane
na tym samym poziomie. W głównej przestrzeni nazw znajdują się nazwy zmiennych,
które określiliśmy globalnie. Zmienne określone wewnątrz funkcji nie są widziane
poza tą funkcją, mówimy wtedy, że są w innej przestrzeni nazw. Wewnątrz funkcji
możemy odwoływać się do zmiennych znajdujących się w przestrzeni nazw tej funkcji
(a więc zadeklarowanych wewnątrz tej funkcji) oraz do zmiennych z nadrzędnych
przestrzeni nazw (w tym z głównej przestrzeni nazw).
W pakiecie R jest kilka funkcji, które pozwalają na zarządzanie przestrzeniami
nazw. Najprostszym przykładem jest funkcja ls(), która wyświetla nazwy obiektów
w aktualnej przestrzeni nazw (zachowanie domyślne) lub w przestrzeni wskazanej
przez argument name, pos lub envir tej funkcji. Innym argumentem funkcji ls() jest
all.names. Domyślnie argument all.names jest ustawiony na FALSE, co powoduje,
że nazwy obiektów rozpoczynające się od znaku . nie są wyświetlane.
Podobne działanie do ls() ma funkcja objects(base) oraz ls.str(base).
Funkcja ls.str() również wyświetla listę nazw zmiennych w aktualnej przestrzeni
nazw oraz dodatkowo wyświetla informacje o strukturze poszczególnych zmiennych
(strukturę jednego obiektu opisuje funkcja str()). Aby uzyskać listę funkcji w przestrzeni nazw można użyć funkcji lsf.str(utils).
Aby usunąć z pamięci operacyjnej wybrany (już niepotrzebny) obiekt możemy
wykorzystać funkcję rm(). Powoduje ona usunięcie obiektu lub obiektów o nazwach
podanych jako argument tej funkcji oraz zwolnienie pamięci zajmowanej przez te
zmienne. Aby usunąć wszystkie zmienne z przestrzeni roboczej należy użyć polecenia
rm(list = ls()). Podobny efekt można uzyskać przypisując do już niepotrzebnej
zmiennej wartość NULL. W tym przypadku pamięć zostanie zwolniona ale nazwa
zmiennej wciąż będzie widoczna w przestrzeni nazw.
Obiekty z pamięci operacyjnej nie są natychmiast usuwane. Dokładniej
rzecz biorąc funkcja rm() markuje wskazane obiekty jako gotowe do usunięcia. Fizyczne zwolnienie pamięci zajmowanej przez ten obiekt następuje dopiero po uruchomienia „śmieciarza”, czyli mechanizmu Garbage
Collection. Zazwyczaj ten mechanizm jest przez R przez R uruchamiany automatycznie gdy tylko zachodzi taka potrzeba. Można również ten proces uruchomić ręcznie
wywołując funkcję gc(base).

!!

!!

!!!

Funkcją save.image(base) można zapisać do pliku wszystkie zmienne znajdujące się w aktualnej (lub wskazanej argumentem envir) przestrzeni nazw. Jest
to przydatne polecenie, gdy chcemy zachować aktualny stan pracy i np. przesłać
go współpracownikowi. Wybraną zmienną lub zmienne możemy zapisać poleceniem
save(base). Inną funkcją z tej serii jest savehistory(bases) zapisująca historię
wszystkich wykonanych poleceń do wskazanego pliku. Dodatkowe informacje o stanie
środowiska R, np. lista załadowanych aktualnie pakietów, można uzyskać uruchamiając funkcję sessionInfo(utils).
Nazwy zmiennych mogą składać się z dużych i małych liter, cyfr i znaków ’_’
oraz ’.’. Operatory arytmetyczne i spacje w nazwach zmiennych są niedozwolone
(ponieważ byłyby niejednoznacznie traktowane przez parser języka). Jeżeli chcemy
jakiś napis zawierający niedozwolone znaki zamienić na poprawną nazwę zmiennych
możemy skorzystać z funkcji make.names(base). Usuwa ona niedozwolone znaki
z łańcucha znaków będącego jej argumentem.

55

56

Łagodne wprowadzenie do R
Prawdę mówiąc w R nie ma rzeczy niemożliwych i wyjątkowo uparte
osoby mogą korzystać z najdziwniejszych możliwych nazw zmiennych.
Poniżej znajduje się przykład, jak zdefiniować i używać zmiennej o nazwie a\a. Można to zrobić korzystając z funkcji assign() i get(). Oczywiście nie polecam tworzenia takich nazw ale przykład ten może się przydać w sytuacjach gdy R wygeneruje automatycznie jakąś bardzo dziwną nazwę dla zmiennej,
np. nazwą będzie ścieżka do jakiegoś pliku.

!!

!!

!!!

> # zaczynamy od dziwnego przypisania, o sposobach przypisywania jeszcze
będziemy pisać
> assign("a\a", 3)
> # sprawdźmy czy ta zmienna jest w pamięci R
> ls()
[1] "a\a"
> # odczytajmy jej wartość
> get("a\a")
[1] 3

Soon, they’ll be
speaking R on the
subway.
Michael Rennie
fortune(68)

1.6.4

Wprowadzenie do grafiki

Pisaliśmy już wiele o tym, że możliwości graficzne R są olbrzymie. Czas na poznanie ich bliżej. Wykresy w R tworzyć można korzystając z wielu różnych funkcji ale
najpopularniejszym sposobem jest skorzystanie z funkcji plot() (jest to też jedna
z najczęściej przeciążanych funkcji, co oznacza, że ma bardzo wiele wyspecjalizowanych implementacji). Poznawanie grafiki zacznijmy od prostego przykładu.
# przygotowujemy siatkę punktów
x = seq(-2*pi,2*pi,by=0.3)
# rysujemy funkcję sin(x)
plot(x, sin(x), type="b",main="Wykres funkcji sin(x) i cos(x)",col="red")
# a następnie dorysowujemy do niej funkcje cos(x)
lines(x, cos(x), col="blue", type="l")

W pierwszej linii powyższego przykładu tworzony jest wektor liczb z użyciem
funkcji seq(). Druga linijka, to wywołanie funkcji plot(). Funkcja ta czyści okno
graficzne i przygotowuje je do narysowania wykresu. Inicjuje osie, ustawia układ
współrzędnych, określa rozmiary marginesów i robi wiele innych przygotowawczych
rzeczy (więcej szczegółów przedstawionych będzie w podrozdziale poświęconym zaawansowanej grafice). Po zainicjowaniu okna graficznego funkcja plot() narysuje
linię łamaną łączącą punkty o współrzędnych x,y wskazanych przez jej dwa pierwsze argumenty (czyli wektor x i wartość funkcji sinus w tych punktach). Gdyby
podany był tylko jeden argument, to będzie on uznany za wektor współrzędnych y
a za wektor x użyty będzie wektor kolejnych liczb naturalnych.
W powyższym przykładzie funkcja plot() rysuje kolejne punkty a następnie łączy je linią. Odpowiedzialny za to postępowanie jest argument type="b" tej funkcji.
Wartość "b" oznacza, że chcemy rysować zarówno linie, jak i punkty (skrót od both).

Przyśpieszamy

1.0

Wykres funkcji sin(x) i cos(x)

●

●

●●

●
●

●
●

●

●
●

●
●

0.5

●
●

●
●
●

0.0

sin(x)

●

●
●

●
●

●
●

−0.5

●
●

●
●

●
●

●
●

●

−1.0

●
●●

−6

−4

−2

●

●

●
●●

0

2

4

6

x

Rysunek 1.5: Wykres narysowany różnymi rodzajami linii

W trzeciej linii przykładu wartość type="l" oznacza, że rysowane mają być wyłącznie linie. Inne możliwe wartości tego argumentu, to p (punkty), n (nic), s (schodki),
h (pionowe kreski, podobne do histogramu). Argument col funkcji plot() umożliwia
wskazanie koloru w jakim ma być narysowana nowa linia. Argument main pozwala na
określenie, jaki napis ma być narysowany jako tytuł wykresu. Więcej o argumentach
funkcji graficznych znaleźć można w podrozdziale 4.3. Efekt działania powyższych
poleceń znajduje się na rysunku 1.5.
Funkcje matematyczne można rysować korzystając również z funkcji curve().
Pierwszym argumentem jest wyrażenie (funkcja) zmiennej x, które ma być narysowane, kolejne dwa argumenty określają końce przedziału, na którym chcemy narysować
to wyrażenie. Poniżej dwa przykłady do samodzielnego sprawdzenia.
curve(sin, from = -2*pi, to = 2*pi)
curve(x^2 - sin(x^2), -2, 2)

Kolejną bardzo przydatną funkcją graficzną jest funkcja abline(graphics). Pozwala ona na dorysowanie linii prostej podając jako argumenty współczynniki równania prostej, czyli równania y = ax + b. Jeżeli chcemy narysować linię poziomą
lub pionową, to wystarczy podać tylko jedną współrzędną, odpowiednio określając
argument h dla linii poziomych lub v dla pionowych.
Poniżej przedstawiono kilka przykładowych wywołań funkcji abline(). Wynik
działania tego kodu jest umieszczony na rysunku 1.6. Za argument funkcji abline()
można również podać model liniowy otrzymany z użyciem lm(stats). W tym przypadku do wykresu dorysowana będzie prosta regresji (pozostawiam to czytelnikowi
do samodzielnego sprawdzenia).

57

Łagodne wprowadzenie do R

2

Wariacje z funkcją abline()

a=2, b=0
a=1, b=0

1

v = −1

0

a=0, b=0

−1

h = −1

−2

58

−2

−1

0

1

2

Rysunek 1.6: Przykładowe użycia funkcji abline()

plot(0, xlim=c(-2,2), ylim=c(-2,2), type="n", xlab="", ylab="",
main="Wariacje nt. funkcji abline()")
# kilka prostych określonych przez równanie y = a x + b
abline(0,0)
abline(0,1)
for (i in 1:10)
abline(0, i)
# dodajemy linię poziomą
abline(h=-1,lwd=3, col="red")
# dodajemy linię pionową
abline(v=-1,lwd=3, lty=2, col="blue")
# na wykres nanosimy kilka opisów
text( 1.7, 0.2, "a=0, b=0")
text( 1.7, 1.1, "a=1, b=0")
text( 1.3, 1.7, "a=2, b=0")
text( 1.7,-0.8, "h = -1")
text(-0.6, 1.1, "v = -1")

Funkcja text(graphics) służy do umieszczania napisów na wykresach. Kolejne
argumenty tej funkcji to: współrzędne punktu, w którym ma znaleźć się napis oraz
łańcuch znaków określający co ma być do wykresu dopisane. Dostępnych argumentów funkcji graficznych jest znacznie więcej o czym łatwo się przekonać przeglądając
pomoc do wymienionych funkcji. Wrócimy do tego tematu w podrozdziale 4.3.

Przyśpieszamy
Funkcja abline() dorysowuje linie do istniejącego wykresu (inaczej niż
funkcja plot(), która tworzy nowy wykres). Przed jej wywołaniem należy więc zapewnić, by jakieś okno graficzne z wykresem było aktywne
i zainicjowane. W powyższym przykładzie wykorzystaliśmy do tego funkcje plot, z argumentem type="n". Ten argument wyłącza rysowanie wykresu, a więc
w tym przypadku funkcja plot() jedynie zainicjowała okno graficzne, osie oraz opis
osi i wykresu nic jednak nie rysując.
Do funkcji abline(), podobnie jak do większości funkcji graficznych, można podawać takie same argumenty, jak w przypadku funkcji plot(), czyli np. argumenty
col, lwd lub lty. Argument lty odpowiada za styl linii, lwd za jej grubość. Więcej
informacji o argumentach funkcji graficznych znaleźć można w podrozdziale 4.3.8.

!!

1.6.5

!!

!!!

Operacje na plikach i katalogach

Zanim zaczniemy omawiać funkcje służące do odczytywania i zapisywania danych
z plików, przedstawimy kilka funkcji do wykonywania podstawowych operacji na
katalogach i plikach.
Zacznijmy od dwóch funkcji: getwd(base) i setwd(base). Pierwsza z tych funkcji sprawdza, jaki katalog na dysku jest aktualnie katalogiem roboczym, druga pozwala na zmianę katalogu roboczego. Podobny efekt można uzyskać wyklikując opcję
File \ Change dir ... w menu. Zmiana katalogu roboczego na początku pracy
pozwala na znaczne skrócenie zapisu ścieżek do plików, ponieważ wszystkie ścieżki do plików możemy podawać w postaci bezwzględnej (niewygodne) i względnej,
względem katalogu roboczego (wygodne).
Aby wyświetlić listę plików znajdujących się w aktualnym (lub innym wskazanym) katalogu można posłużyć się funkcją list.files(base) lub dir(base).
Pierwszym, opcjonalnym, argumentem tych funkcji jest ścieżka do katalogu, którego
zawartość chcemy wyświetlić (domyślnie jest to aktualny katalog roboczy). W tabeli
1.7 przedstawiono listę funkcji do operowania na plikach a poniżej przedstawiono
przykład wywołania wybranych funkcji.
> # funkcjami setwd() i getwd() można zmieniać katalog roboczy
> setwd("c:/Projekty/Dane")
> getwd()
[1] "c:/Projekty/Dane"
> # zobaczmy co jest w tym katalogu
> (list.files() -> lista.plikow)
[1] "daneFWF.txt"
"daneMatlab.MAT"
"daneMieszkania.csv"
[4] "daneSAS.sas7bdat"
"daneSoc.csv"
"daneSPSS.sav"

Przydatnymi funkcjami do operacji na plikach tymczasowych są tempfile(base)
i tempdir(base). Wynikiem pierwszej z nich jest ścieżka do nieistniejącego jeszcze
pliku (nazwa jest losową kombinacje znaków), który może być wykorzystany jako plik
tymczasowy. Wynikiem drugiej funkcji jest ścieżka do tymczasowego, nieistniejącego
jeszcze katalogu. Obie funkcje są przydatne, jeżeli chcemy przechować tymczasowo
pewne dane w plikach ale nie mamy pomysłu na ich nazwę. Poniżej przykład użycia
tych funkcji.

59

60

Łagodne wprowadzenie do R

# generujemy losową nazwę dla tymczasowego pliku
tmpf <- tempfile()
# wpisujemy do tego pliku napis
cat(file=tmpf, "Poczatek pliku")
# tu operacje na pliku
# ....
# na koniec kasujemy tymczasowy plik
unlink(tmpf)

Kolejną przydatną funkcją do operacji na plikach jest sink(base). Zapisuje ona
do wskazanego pliku tekstowego przebieg interakcji z R. Jej wywołanie powoduje
przekazanie wyjścia z konsoli R do wskazanego pliku (domyślnie wyjście jest kierowane zarówno do pliku jak i na ekran, ale można zarządzać, by było kierowane tylko
do pliku). W wyniku jej działania, we wskazanym pliku znajduje się cała historia
wykonanych poleceń wraz otrzymanymi wynikami, czyli kopia wszystkiego co działo
się na konsoli R.
Tabela 1.7: Funkcje do operacji na plikach
Funkcja tworzy pliki o zadanych nazwach, jeżeli takie pliki istnieją, to ich zawartość jest kasowana.
file.exists(...)
Funkcja sprawdza czy pliki o zadanych nazwach istnieją.
file.remove(...)
Funkcja usuwa pliki o zadanych nazwach (patrz też
funkcja unlink()).
file.rename(from, to)
Funkcja zmienia nazwę pojedynczego pliku.
file.append(file1, file2) Funkcja dokleja plik o nazwie file2 do pliku
file1.
file.copy(from, to,
Funkcja do kopiowania pliku from w pozycje wskaoverwrite=F)
zaną przez argument to.
file.symlink(from, to)
Funkcja do tworzenia linków symbolicznych (pod
Unixami).
dir.create(path,
Funkcja do tworzenia katalogów. Wynikiem tej
showWarnings=T,
funkcji jest wartość TRUE, jeżeli operacja utworzerecursive=F)
nia katalogu została wykonana pomyślnie. Jeżeli
dany katalog już istnieje lub nie udało go się utworzyć funkcja przekazuje wartość FALSE.
unlink(x, recursive=F)
Funkcja do usuwania plików lub katalogów.
file.info(...)
Wynikiem tej funkcji są informacje o wskazanych
plikach.
file_test(op, x, y)
Funkcja do testowania plików. Dostępne testy to:
jednoargumentowe (tylko x jest używane) op="-f"
istnieje i nie jest katalogiem, op="-d" istnieje i jest
katalogiem oraz dwuargumentowe op="-nt" jest
młodszy niż (pod uwagę brane są daty modyfikacji)
i op="-ot" jest starszy niż.
file.show(...)
Funkcja wyświetla w oknie R zawartość jednego lub
większej liczby plików.
file.create(...)

Przyśpieszamy
Jeżeli nie chcemy z klawiatury wpisywać ścieżki do pliku, to możemy wyklikać ją korzystając z funkcji file.choose(base) lub
choose.files(base). Obie funkcje otwierają okno systemowe pozwalające na wskazanie pliku lub plików. Wynikiem obu funkcji jest wektor
ścieżek do wskazanych przez użytkownika plików.
Przypomnijmy też, że R ma możliwość uzupełniania ścieżek. Jeżeli przy wpisywaniu
ścieżki do pliku lub katalogu naciśniemy Tab, to R uzupełni nazwę wpisywanego
katalogu lub pliku. Jeżeli ścieżkę można uzupełnić na wiele sposobów, to R wyświetla
listę wszystkich możliwości.

!!

!!

!!!

Rysunek 1.7: Okno systemowe umożliwiające wybór jednego lub więcej plików. Wynik
działania funkcji file.choose() lub choose.files()

1.6.5.1

Odczytywanie i zapisywanie plików tekstowych

W R jest kilka różnych funkcji umożliwiających czytanie danych z pliku i zapisywanie
danych do pliku. Funkcje te mają wiele argumentów pozwalających na określenie rodzaju kodowania, znaku separatora, kropki dziesiętnej, typu odczytywanych danych
i innych detali opisujących format danych w pliku. Aby nie utonąć w szczegółach,
poniżej przedstawione są jedynie najczęstsze przykłady użycia. Wymienione funkcje
mają bardzo dokładnie opracowane pliki pomocy, tam z pewnością zainteresowani
oraz potrzebujący znajdą więcej informacji.
Analizując dane najczęściej korzysta się z danych tabelarycznych i w takiej postaci przechowuje się te dane w plikach tekstowych. Do operacji na plikach tekstowych, w których są dane zapisane w tej postaci wykorzystać można funkcje
read.table(base) i write.table(base). Obie funkcje są szczegółowo opisane w podrozdziale 2.3.1, w tym rozdziale przedstawiamy jedynie krótkie wprowadzenie. Zacznijmy od prostego przykładu wczytania danych z pliku.
macierz = read.table("nazwa.pliku.z.danymi")

61

Łagodne wprowadzenie do R
W pliku "nazwa.pliku.z.danymi" mogą być umieszczone informacje o nazwach
kolumn (zmiennych) i/lub wierszy (przypadków). Kolejne wartości w pliku rozdzielane mogą być różnymi znakami (najpopularniejsze separatory to przecinek, średnik,
spacja lub tabulacja). Do odczytanie danych z pliku, w którym w pierwszej linii
umieszczone są nazwy kolumn a wartości kolejnych pól rozdzielane są znakami tabulacji można użyć polecenia:
macierz = read.table("nazwa.pliku", header=T, sep="\t")

!!

!!

!!!

Ścieżka do pliku może być również adresem URL! Korzystając z takich ścieżek możemy odczytywać dane z plików umieszczonych na innych
komputerach. Przykładowe zbiory danych wykorzystywane w tej książce
mogą być w ten sposób bezpośrednio odczytane z Internetu.

Wartość lub wektor wartości możemy zapisać do pliku korzystając z funkcji
cat(base). Domyślnie wynik tej funkcji jest wyświetlany w konsoli, ale zmieniając wartość argumentu file możemy zapisać wyniki do pliku. Tak to wygląda na
przykładzie:
cat(wektor, file="nazwa.pliku", append=F)

Argument append określa, czy wynik tej funkcji ma być dopisany do końca pliku
(o ile plik istnieje), czy też ten wynik ma nadpisać ewentualną zawartość wskazanego pliku. Jeżeli wskazany plik nie istnieje, wynik jest w obu przypadkach taki sam.
Do zapisu danych (wektora, macierzy lub ramki danych) w formacie tabelarycznym można wykorzystać funkcję write.table(). Poniższy przykład zapisuje dane
rozdzielając kolejne elementy znakiem tabulacji.
write.table(macierz, file="nazwa.pliku", sep="\t")

Duże i złożone obiekty lepiej przechowywać w postaci binarnej. Zapis w formacie plików binarnych umożliwia funkcja save(base). Funkcja ta zapisuje wskazany obiekt lub listę obiektów w formacie Rdata. Do takiego formatu można zapisać nie tylko liczby ale też złożone obiekty i funkcje. Jeżeli chcemy zapisać do
pliku wartość wszystkich obiektów z przestrzeni nazw, to można skorzystać z funkcji save.image(base). Zapisuje ona do pliku wszystkie dostępne obiekty. Podobny
efekt ma polecenie z menu File / Save workspace.
Binarna reprezentacja RData może różnić się dla różnych wersji R! Może
więc się zdarzyć, że po zainstalowaniu nowej wersji R pewne pliki binarne nie odczytują się prawidłowo. Niestety w tym przypadku R nie
sygnalizuje informacji o błędzie, użytkownik może być nawet nieświadomy źródła błędnych wyników. Z tego powodu, jeżeli chcemy przechowywać dane
dłużej lub chcemy przenieść je na inny komputer (gdzie może być zainstalowana
inna wersja R), to powinniśmy użyć innego formatu danych. Unikniemy dzięki temu
przykrych niespodzianek w stylu „działało i już nie działa”.

!!

!!!

!!

62

Kolory z pakietu RColorBrewer

magenta2green(colorRamps)
cyan2yellow(colorRamps)
blue2yellow(colorRamps)
green2red(colorRamps)
blue2green(colorRamps)
blue2red(colorRamps)
cm.colors(grDevices)
topo.colors(grDevices)
terrain.colors(grDevices)
heat.colors(grDevices)
rainbow(grDevices)

Kolory z pakietów grDevices i colorRamps

RdBu
PuOr
PRGn
PiYG
BrBG

RdYlGn
RdYlBu
RdGy

Spectral

Set3
Set2
Set1
Pastel2
Pastel1
Paired
Dark2
Accent

Greens
GnBu
BuPu
BuGn
Blues

PuRd
PuBuGn
PuBu
OrRd
Oranges
Greys

YlOrRd
YlOrBr
YlGnBu
YlGn
Reds
RdPu
Purples

coral3
coral2
coral1
coral
chocolate4
chocolate3
chocolate2
chocolate1
chocolate
chartreuse4
chartreuse3
chartreuse2
chartreuse1
chartreuse
cadetblue4
cadetblue3
cadetblue2
cadetblue1
cadetblue
burlywood4
burlywood3
burlywood2
burlywood1
burlywood
brown4
brown3
brown2
brown1
brown
blueviolet
blue4
blue3
blue2
blue1
blue
blanchedalmond
black
bisque4
bisque3
bisque2
bisque1
bisque
beige
azure4
azure3
azure2
azure1
azure
aquamarine4
aquamarine3
aquamarine2
aquamarine1
aquamarine
antiquewhite4
antiquewhite3
antiquewhite2
antiquewhite1
antiquewhite
aliceblue
white
cornsilk4
cornsilk3
cornsilk2
cornsilk1
cornsilk
cornflowerblue
coral4

deeppink4
deeppink3
deeppink2
deeppink1
deeppink
darkviolet
darkturquoise
darkslategrey
darkslategray4
darkslategray3
darkslategray2
darkslategray1
darkslategray
darkslateblue
darkseagreen4
darkseagreen3
darkseagreen2
darkseagreen1
darkseagreen
darksalmon
darkred
darkorchid4
darkorchid3
darkorchid2
darkorchid1
darkorchid
darkorange4
darkorange3
darkorange2
darkorange1
darkorange
darkolivegreen4
darkolivegreen3
darkolivegreen2
darkolivegreen1
darkolivegreen
darkmagenta
darkkhaki
darkgrey
darkgreen
darkgray
darkgoldenrod4
darkgoldenrod3
darkgoldenrod2
darkgoldenrod1
darkgoldenrod
darkcyan
darkblue
cyan4
cyan3
cyan2
cyan1
cyan

gray27
gray26
gray25
gray24
gray23
gray22
gray21
gray20
gray19
gray18
gray17
gray16
gray15
gray14
gray13
gray12
gray11
gray10
gray9
gray8
gray7
gray6
gray5
gray4
gray3
gray2
gray1
gray0
gray
goldenrod4
goldenrod3
goldenrod2
goldenrod1
goldenrod
gold4
gold3
gold2
gold1
gold
ghostwhite
gainsboro
forestgreen
floralwhite
firebrick4
firebrick3
firebrick2
firebrick1
firebrick
dodgerblue4
dodgerblue3
dodgerblue2
dodgerblue1
dodgerblue
dimgrey
dimgray
deepskyblue4
deepskyblue3
deepskyblue2
deepskyblue1
deepskyblue

gray87
gray86
gray85
gray84
gray83
gray82
gray81
gray80
gray79
gray78
gray77
gray76
gray75
gray74
gray73
gray72
gray71
gray70
gray69
gray68
gray67
gray66
gray65
gray64
gray63
gray62
gray61
gray60
gray59
gray58
gray57
gray56
gray55
gray54
gray53
gray52
gray51
gray50
gray49
gray48
gray47
gray46
gray45
gray44
gray43
gray42
gray41
gray40
gray39
gray38
gray37
gray36
gray35
gray34
gray33
gray32
gray31
gray30
gray29
gray28

grey39
grey38
grey37
grey36
grey35
grey34
grey33
grey32
grey31
grey30
grey29
grey28
grey27
grey26
grey25
grey24
grey23
grey22
grey21
grey20
grey19
grey18
grey17
grey16
grey15
grey14
grey13
grey12
grey11
grey10
grey9
grey8
grey7
grey6
grey5
grey4
grey3
grey2
grey1
grey0
grey
greenyellow
green4
green3
green2
green1
green
gray100
gray99
gray98
gray97
gray96
gray95
gray94
gray93
gray92
gray91
gray90
gray89
gray88

grey99
grey98
grey97
grey96
grey95
grey94
grey93
grey92
grey91
grey90
grey89
grey88
grey87
grey86
grey85
grey84
grey83
grey82
grey81
grey80
grey79
grey78
grey77
grey76
grey75
grey74
grey73
grey72
grey71
grey70
grey69
grey68
grey67
grey66
grey65
grey64
grey63
grey62
grey61
grey60
grey59
grey58
grey57
grey56
grey55
grey54
grey53
grey52
grey51
grey50
grey49
grey48
grey47
grey46
grey45
grey44
grey43
grey42
grey41
grey40
lightpink1
mistyrose1
pink4
lightpink
mistyrose
pink3
lightgrey
pink2
mintcream
lightgreen
midnightblue
pink1
lightgray
pink
mediumvioletred
peru
lightgoldenrodyellow
mediumturquoise
lightgoldenrod4mediumspringgreen peachpuff4
lightgoldenrod3 mediumslateblue peachpuff3
lightgoldenrod2 mediumseagreen peachpuff2
lightgoldenrod1 mediumpurple4
peachpuff1
lightgoldenrod mediumpurple3
peachpuff
lightcyan4
papayawhip
mediumpurple2
lightcyan3
mediumpurple1 palevioletred4
lightcyan2
mediumpurple palevioletred3
lightcyan1
mediumorchid4 palevioletred2
lightcyan
mediumorchid3 palevioletred1
lightcoral
mediumorchid2 palevioletred
lightblue4
mediumorchid1 paleturquoise4
lightblue3
mediumorchid paleturquoise3
lightblue2
paleturquoise2
mediumblue
lightblue1 mediumaquamarinepaleturquoise1
lightblue
paleturquoise
maroon4
palegreen4
maroon3
lemonchiffon4
palegreen3
maroon2
lemonchiffon3
palegreen2
maroon1
lemonchiffon2
palegreen1
maroon
lemonchiffon1
magenta4
palegreen
lemonchiffon
magenta3
lawngreen
palegoldenrod
magenta2
lavenderblush4
orchid4
magenta1
lavenderblush3
orchid3
magenta
lavenderblush2
orchid2
lavenderblush1
linen
orchid1
limegreen
lavenderblush
orchid
lightyellow4
orangered4
lavender
lightyellow3
orangered3
khaki4
lightyellow2
orangered2
khaki3
lightyellow1
orangered1
khaki2
lightyellow
orangered
khaki1
orange4
lightsteelblue4
khaki
orange3
lightsteelblue3
ivory4
orange2
lightsteelblue2
ivory3
orange1
lightsteelblue1
ivory2
orange
lightsteelblue
ivory1
lightslategrey
ivory
olivedrab4
lightslategray
olivedrab3
indianred4
lightslateblue
indianred3
olivedrab2
lightskyblue4
indianred2
olivedrab1
lightskyblue3
indianred1
olivedrab
lightskyblue2
indianred
oldlace
lightskyblue1
navyblue
hotpink4
navy
lightskyblue
hotpink3
lightseagreen
navajowhite4
hotpink2
lightsalmon4
navajowhite3
hotpink1
lightsalmon3
navajowhite2
hotpink
lightsalmon2
honeydew4
navajowhite1
lightsalmon1
honeydew3
navajowhite
lightsalmon
honeydew2
moccasin
lightpink4
honeydew1
mistyrose4
lightpink3
honeydew
mistyrose3
grey100
lightpink2
mistyrose2

Predefiniowane nazwy kolorów, colors()
slategray1
slategray
slateblue4
slateblue3
slateblue2
slateblue1
slateblue
skyblue4
skyblue3
skyblue2
skyblue1
skyblue
sienna4
sienna3
sienna2
sienna1
sienna
seashell4
seashell3
seashell2
seashell1
seashell
seagreen4
seagreen3
seagreen2
seagreen1
seagreen
sandybrown
salmon4
salmon3
salmon2
salmon1
salmon
saddlebrown
royalblue4
royalblue3
royalblue2
royalblue1
royalblue
rosybrown4
rosybrown3
rosybrown2
rosybrown1
rosybrown
red4
red3
red2
red1
red
purple4
purple3
purple2
purple1
purple
powderblue
plum4
plum3
plum2
plum1
plum

Rysunek 4.37: Palety kolorów. Z przyczyn ekonomicznych prezentujemy wersję czarnobiałą. Kolor znaleźć można na stronie http://www.biecek.pl/R/

yellowgreen
yellow4
yellow3
yellow2
yellow1
yellow
whitesmoke
wheat4
wheat3
wheat2
wheat1
wheat
violetred4
violetred3
violetred2
violetred1
violetred
violet
turquoise4
turquoise3
turquoise2
turquoise1
turquoise
tomato4
tomato3
tomato2
tomato1
tomato
thistle4
thistle3
thistle2
thistle1
thistle
tan4
tan3
tan2
tan1
tan
steelblue4
steelblue3
steelblue2
steelblue1
steelblue
springgreen4
springgreen3
springgreen2
springgreen1
springgreen
snow4
snow3
snow2
snow1
snow
slategrey
slategray4
slategray3
slategray2

Zbiory danych
W tym miejscu przedstawimy zbiory danych wykorzystywane w poprzednich rozdziałach. Są one umieszczone w Internecie i można je ściągnąć podanymi poniżej
poleceniami. Jeżeli nie mamy własnych danych, to warto na tych przećwiczyć omawiane w tej książce funkcje.

4.4

Zbiór danych onkologicznych: daneO.csv

Ten zbiór danych zawiera informacje o dziewięciu zmiennych zmierzonych dla 97
pacjentek z wrocławskiego oddziału onkologii. Dane zostały przetworzone tak, by nie
można było wydobyć z nich jakichkolwiek, nawet częściowych informacji o pacjentkach. Dane te nadają się do ćwiczeń, ale z uwagi na zbyt małą liczbę przypadków
nie mogą być wykorzystane do wnioskowania o prawdziwych skutkach tej choroby.
> daneO = read . table(”http ://www. biecek . pl/R/dane/daneO. csv” , sep=” ; ” , h=T)
> summary(daneO)
Wiek
Rozmiar . guza
Wezly . chlonne
Nowotwor
Min.
:29.00
Min.
:1.000
Min.
:0.0000
Min.
: 1.000
1st Qu.:42.00
1st Qu.:1.000
1st Qu.:0.0000
1st Qu. : 2.000
Median :46.00
Median :1.000
Median :0.0000
Median : 2.000
Mean :45.52
Mean
:1.268
Mean :0.4124 Mean
: 2.221
3rd Qu.:50.00
3rd Qu.:2.000
3rd Qu.:1.0000
3rd Qu. : 3.000
Max.
:57.00 Max.
:2.000 Max.
:1.0000 Max.
: 3.000
NA’ s
:11.000
Receptory . estrogenowe Receptory . progesteronowe Niepowodzenia Okres . bez .wznowy
(−) :37
(−) :24
brak :84
Min.
:10.00
(+) :21
(+) :18
wznowa:13
1st Qu.:30.75
(++) :24
(++) :32
Median :38.00
(+++): 9
(+++):16
Mean
:37.41
NA’ s : 6
NA’ s : 7
3rd Qu.:45.00
Max.
:54.00
NA’ s
: 1.00
VEGF
Min.
: 118
1st Qu. : 629
Median : 1489
Mean
: 2627
3rd Qu. : 3240
Max.
:22554

273

Patrick Burns: In
the old days with
S-PLUS, the rule of
thumb was that you
needed 10 times as
much memory as
your dataset. [...] R
(and current
versions of S-PLUS)
are more frugal than
S-PLUS was back
then.
Ajay Shah: Hmm, so
it’d be interesting to
apply current prices
of RAM and current
prices of R, to work
out the break-even
point at which it’s
better tobuy SAS!
:-) Without making
any calculations,
I can’t see how SAS
can compete with
the price of 4G of
RAM.
Patrick Burns, Ajay
Shah
fortune(93)

274

Zbiory danych

4.5

Zbiór danych o cenach mieszkań: daneMieszkania.csv

Ten zbiór danych zawiera informacje o pięciu parametrach dla 200 mieszkań z wrocławskiego rynku nieruchomości (ceny z roku 2004 a więc już trochę nieaktualne,
w każdym razie nie mogą być traktowane jako oferta handlowa).
> mieszkania = read . table(”http ://www. biecek . pl/R/dane/daneMieszkania . csv” ,
header=T, sep=” ; ”)
> summary( mieszkania )
cena
pokoi
powierzchnia
dzielnica
typ . budynku
Min.
: 83280 Min.
:1.00 Min.
:17.00 Biskupin
:65 kamienica :61
1st Qu.:143304 1st Qu.:2.00 1st Qu.:31.15 Krzyki
:79 n i s k i blok :63
Median :174935 Median :3.00 Median :43.70 Srodmiescie :56 wiezowiec :76
Mean :175934 Mean
:2.55 Mean
:46.20
3rd Qu.:208741 3rd Qu.:3.00 3rd Qu.:61.40
Max.
:295762 Max.
:4.00 Max.
:87.70

4.6

Zbiór danych socjodemograficznych: daneSoc.csv

Ten zbiór danych zawiera informacje o siedmiu zmiennych (głównie socjodemograficznych) zmierzonych dla 204 pacjentów jednej z wrocławskich przychodni.
> daneSoc = read . csv(”http ://www. biecek . pl/R/dane/daneSoc . csv” , sep=” ; ”)
> summary(daneSoc)
wiek
wyksztalcenie
st . cywilny
plec
Min.
:22.00
podstawowe:93
s i n g i e l :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.
:75.00
praca
c i s n i e n i e . skurczowe c i s n i e n i e . rozkurczowe
nie pracuje
: 52 Min.
: 93.0
Min.
: 57.00
uczen lub pracuje :152
1st Qu.:126.0
1st Qu. : 77.00
Median :137.5
Median : 80.00
Mean
:137.0
Mean
: 80.43
3rd Qu.:148.0
3rd Qu. : 86.25
Max.
:178.0
Max.
:107.00

Skorowidz
argument
alternative, 204
bg, 259
cex, 259
col, 56, 257
col.main, 257
col.sub, 257
drop, 35
error, 109
header, 89
lty, 258
lwd, 258
main, 56, 262
mfcol, 263
mfrow, 263
na.rm, 29
pch, 259
sub, 262
type, 56, 258
xlab, 262
ylab, 262

as.complex(base), 22, 31
as.data.frame(base), 31
as.double(base), 31
as.factor(base), 31
as.integer(base), 31
as.list(base), 31
as.logical(base), 31
as.matrix(base), 31
as.numeric(base), 31
asin(base), 21
assign(base), 33, 56
atan(base), 21
atan2(base), 21
attach(base), 73
attr(base), 81
attributes(base), 81
axis(graphics), 255
bagplot(aplpack), 240
balloonplot(gplots), 137
bar.err(agricolae), 157
bar.group(agricolae), 157
barplot(graphics), 238
bartlett.test(stats), 209
besselI(base), 121
besselJ(base), 121
besselK(base), 121
besselY(base), 121
beta(base), 22
betareg(betareg), 194
binom.test(stats), 213
bmp(grDevices), 99
boot(boot), 225
boot.ci(boot), 226
box.cox(car), 152
boxcox(MASS), 152
boxplot(graphics), 133
boxplot.stats(graphics), 133
browseEnv(base), 117
by(base), 70
bzfile(base), 102
c(base), 29, 67
capabilities(utils), 102
cat(base), 39, 62
cbind(base), 79
cdplot(graphics), 186
ce.mimp(dprep), 148
ceiling(base), 21
character(base), 67
chartr(base), 66
chisq.test(stats), 202, 216

funkcja
.First(base), 54
.Last(base), 54
:(base), 67
abline(graphics), 57, 260
abs(base), 21
acos(base), 21
ad.test(nortest), 199
add1.glm(stats), 188
addlogo(pixmap), 254
addmargins(stats), 64
aggregate(base), 70
agrep(base), 66
anova(stats), 155, 171
anova.coxph(survival), 232
anova.glm(stats), 188
anova.survreg(survival), 232
ansari.test(stats), 209
aov(stats), 156
apply(base), 78, 150
apropos(utils), 18
aregImpute(Hmisc), 147
Arg(base), 22
args(utils), 18
array(base), 80
arrows(graphics), 260
as(methods), 84
as.character(base), 31

286

SKOROWIDZ

choose(base), 22
choose.files(base), 60
chplot(chplot), 240
class(base), 32, 81
close(base), 101
cloud(lattice), 238
cm.colors(grDevices), 257
coef(stats), 171
col2rgb(grDevices), 258
colMeans(base), 76
colnames(utils), 72
colors(graphics), 257
colours(graphics), 257
colSums(base), 76
combn(base), 22
complete.cases(stats), 29, 146
complex(base), 22
confint.glm(stats), 188
Conj(base), 22
contour(graphics), 244
contr.helmert(stats), 161
contr.poly(stats), 161
contr.SAS(stats), 161
contr.sdif(MASS), 161
contr.sum(stats), 161
contr.treatment(stats), 161
convolve(stats), 22
cooks.distance.glm(stats), 188
coplot(graphics), 242
cor(stats), 126, 213
cor.test(stats), 214
cos(base), 21
cov(stats), 126
cox.zph(survival), 232
coxph(survival), 232
ctree(party), 232
cummax(base), 69
cummin(base), 69
cumprod(base), 69
cumsum(base), 69
curve(graphics), 57, 260
cut(base), 64, 152
cvm.test(nortest), 199
D(stats), 123
data(utils), 97
data.ellipse(car), 243
data.entry(utils), 72
data.frame(base), 30, 72
debug(base), 111
debugger(utils), 110
density(stats), 130, 186
dep(asuR), 176
deparse(base), 87
deriv(polynom), 118
deriv(stats), 123
det(base), 26, 76
detach(base), 73
dev.off(grDevices), 99
deviance(stats), 171

diag(base), 75
diff(base), 69
digamma(base), 22
dim(base), 73, 80
dimnames(utils), 72
dir(base), 59
dir.create(base), 60
distplot(vcd), 243
dotchart(graphics), 239
double(base), 67
download.file(utils), 101
drop1.glm(stats), 188
duplicated(base), 69
durbin.test(agricolae), 158
eapply(base), 70
ec.knnimp(dprep), 148
ecdf(stats), 130
edit(utils), 7, 48, 72
effects.glm(stats), 188
eigen(base), 76
encodeString(base), 41
eval(base), 117
example(utils), 18
exp(base), 21
expand.grid(base), 77
expm1(base), 21
expression(base), 123, 257
extends(methods), 84
faces(aplpack), 250
factor(base), 27
factorial(base), 22
family(stats), 183
fifo(base), 102
file(base), 102
file.append(base), 60
file.choose(base), 60
file.copy(base), 60
file.create(base), 60
file.exists(base), 60
file.info(base), 60
file.remove(base), 60
file.rename(base), 60
file.show(base), 60
file.show(utils), 101
file.symlink(base), 60
file test(base), 60
filled.contour(graphics), 244
find(utils), 18
fisher.test(stats), 216
fitdistr(MASS), 143
fitted(stats), 171
fivenum(stats), 128
fix(base), 7
fix(utils), 81
fligner.test(stats), 209
floor(base), 21
format(base), 40
formatFix(cwhstring), 41
fourfold(vcd), 243

287

288

SKOROWIDZ

fourfoldplot(graphics), 243
ftable(stats), 64
function(base), 31
gam(gam), 196
gamma(base), 22
gc(base), 55
GCD(polynom), 118
geometric.mean(psych), 126
get(base), 56
getwd(base), 59
gl(base), 65
glm(stats), 182, 188
glm.diag.plots(boot), 188
gModel(gRbase), 196
gnls(nlme), 193
goodfit(vcd), 204
gpairs(YaleToolkit), 240
grep(base), 66
gsub(base), 66
gzfile(base), 102
harmonic.mean(psych), 126
head(utils), 72
heat.colors(grDevices), 257
heatmap(stats), 246
help(utils), 18
help.search(base), 16
help.search(utils), 18
hist(graphics), 129
hist2d(gplots), 235
hnp(asuR), 176
HSD.test(agricolae), 157
hsv(grDevices), 258
HTML(R2HTML), 108
identify(graphics), 261
identify3d(scatterplot3d), 238
ifelse(base), 43
ihp(asuR), 176
ilp(asuR), 176
Im(base), 22
image(graphics), 253
impute(e1071), 148
initialize(methods), 83
inspect(asuR), 176
install.packages(utils), 5
integer(base), 67
integral(polynom), 118
integrate(stats), 123
interaction.plot(stats), 164
intersect(base), 121
inverse.rle(base), 68
invisible(base), 40
ipcp(iplots), 247
IQR(stats), 126
irp(asuR), 176
is(methods), 84
is.character(base), 31
is.complex(base), 22, 31
is.double(base), 31
is.element(base), 121

is.factor(base), 31
is.integer(base), 31
is.logical(base), 31
is.na(base), 31, 146
is.nan(base), 31
is.numeric(base), 31
isClassUnion(methods), 84
jitter(base), 236
jpg(grDevices), 99
kde(ks), 244
kde2d(MASS), 244
kronecker(base), 77
kruskal.test(stats), 206
ks.test(stats), 204
kurtosis(e1071), 126
lapply(base), 70
layout(graphics), 263
lbeta(base), 22
lchoose(base), 22
LCM(polynom), 118
legend(graphics), 256
legendre.polynomials(orthopolynom), 119
length(base), 67, 126
levelplot(lattice), 244
levels(base), 64, 152, 177
leverage.plot.glm(stats), 188
lfactorial(base), 22
lgamma(base), 22
library(base), 5
lillie.test(nortest), 199
lines(graphics), 56, 260
list(base), 30
list.files(base), 59, 60
lm(stats), 155, 161, 169
lm.fit(stats), 169
lm.ridge(MASS), 179, 180
lme(nlme), 193
locator(graphics), 261
loess(stats), 194
log(base), 21
log10(base), 21
log1p(base), 21
log2(base), 21
logb(base), 21
logical(base), 67
logLik.glm(stats), 188
lower.tri(base), 76
lowess(stats), 194
lqs(MASS), 181
lrm(Design), 182
ls(base), 14, 55
ls.str(base), 55
LSD.test(agricolae), 158
lsf.str(utils), 55
lsoda(odesolve), 123
macierzowe, 76
make.contrasts(gmodels), 161
make.names(base), 55
mancontr(asuR), 161

SKOROWIDZ

manova(stats), 167
mantelhaen.test(stats), 217
mapply(base), 70
margin.table(base), 64
match(base), 36
match.arg(base), 49
matlines(graphics), 252
matplot(graphics), 252
matpoints(graphics), 252
matrix(base), 25, 30
max(base), 69, 126
mcnemar.test(stats), 217
mean(stats), 126
median(stats), 126
merge(base), 79
min(base), 69, 126
Mod(base), 22
moda(dprep), 126
mode(base), 32, 81
mood.test(stats), 209
mosaicplot(graphics), 136
mt.rawp2adjp(multtest), 223
mtext(graphics), 263
mvr(pls), 192
na.fail(stats), 29
na.omit(stats), 29, 146
names(utils), 72
nchar(base), 66
ncol(base), 73
new(methods), 83
nlevels(base), 64
nlm(stats), 122, 190
nlme(nlme), 193
nlrq(quantreg), 195
nls(stats), 190
norm.test(asuR), 176
nrow(base), 73
object.size(base), 81
objects(base), 55
odbcConnectExcel(RODBC), 95
odbcConnectExcel2007(RODBC), 95
optim(stats), 122
optimize(stats), 122
options(base), 50
order(base), 69, 78
outer(base), 77, 246
outlier.test.glm(stats), 188
p.adjust(stats), 223
pairs(graphics), 240
pairwise.prop.test(stats), 212
pairwise.t.test(stats), 209
par(graphics), 264
parcoord(MASS), 247
partialAssociations(CoCo), 220
paste(base), 40
pdf(grDevices), 99
pearson.test(nortest), 199
persp(graphics), 244
pictex(grDevices), 100

pie(graphics), 238
pipe(base), 102
plot(graphics), 56, 252
plot(pixmap), 254
plot(stats), 171
plot.design(graphics), 164
plot.lm(stats), 174
plotcorr(ellipse), 242
plotmath(grDevices), 257
pmax(base), 69
pmin(base), 69
png(grDevices), 99
points(graphics), 260
poly.calc(polynom), 118
polygon(graphics), 260
polynomial(polynom), 118
poscript(grDevices), 99
pR2(pscl), 188
predict(stats), 171, 178, 184
predict.glm(stats), 188
print(base), 39
print.summary.lm(stats), 172
proc.time(base), 115
prod(base), 69
prop.table(base), 64
prop.test(stats), 211
psigamma(base), 22
q(base), 10
qnorm(stats), 138
qq.plot(car), 201
qq.plot.glm(stats), 188
qqnorm(stats), 201
qqplot(stats), 205
qr(base), 76
quantile(stats), 126
rainbow(grDevices), 257
range(base), 126
rank(base), 69
rapply(base), 70
rbind(base), 79
Re(base), 22
read.arff(foreign), 98
read.csv(utils), 95
read.dbf(foreign), 98
read.dta(foreign), 98
read.epiinfo(foreign), 98
read.fwf(utils), 94
read.mtp(foreign), 98
read.octave(foreign), 98
read.pnm(pixmap), 254
read.S(foreign), 98
read.spss(foreign), 96, 98
read.ssd(foreign), 97, 98
read.systat(foreign), 98
read.table(utils), 61, 89
read.xport(foreign), 98
readBin(base), 102
readLines(base), 102
readMat(R.matlab), 97, 98

289

290

SKOROWIDZ

rect(graphics), 260
reorder(base), 177
rep(base), 24, 67, 246
replicate(base), 70
require(base), 41
resid(stats), 171
residuals.glm(stats), 185, 188
return(base), 48
rev(base), 68
rgb(grDevices), 258
rgb2hsv(grDevices), 258
rgl.surface(rgl), 244
rk4(odesolve), 123
rle(base), 68
rlm(MASS), 181
rm(base), 55
RNGkind(base), 138
rose.diag(circular), 235
round(base), 21
rowMeans(base), 76
rownames(utils), 72
rowsum(base), 76
rowSums(base), 76
rpp(asuR), 176
Rprof(base), 114
rq(quantreg), 195
Rsitesearch(base), 16
rstandard.glm(stats), 188
rstudent.glm(stats), 188
rug(graphics), 129, 260
ryp(asuR), 176
sample(base), 38
sapply(base), 70
sas.get(Hmisc), 98
save(base), 55, 62
save.image(base), 55, 62
savehistory(base), 55
scan(base), 93
scatter3d(Rcmdr), 236
scatterplot(car), 135, 194, 236
scatterplot.matrix(car), 240
scatterplot3d(scatterplot3d), 236
sd(stats), 126
seek(base), 102
segmented(segmented), 196
segments(graphics), 260
sem(sem), 196
seq(base), 38, 67
seq along(base), 45
sessionInfo(utils), 55
set.seed(base), 139
setClass(base), 83
setClassUnion(methods), 84
setdiff(base), 121
setequal(base), 121
setwd(base), 59
sf.test(nortest), 199
shapiro.test(nortest), 199
shell(base), 117

shell.exec(base), 117
sign.test(BSDA), 209
signif(base), 21
simpleError(base), 112
simpleWarning(base), 112
sin(base), 21
sink(base), 60
skewness(e1071), 126
slegendre.polynomials(orthopolynom), 119
slot(methods), 83
slotNames(methods), 84
smooth.spline(stats), 194
socketConnection(base), 102
solve(base), 26, 75
solve(polynom), 118
sort(base), 68
source(base), 6, 12
sp(car), 136, 236
specify.model(sem), 196
split(base), 73
sprintf(base), 41
spss.get(Hmisc), 95, 98
sqrt(base), 21
stack(utils), 74
stars(graphics), 250
step(stats), 178, 184
step.glm(stats), 188
stop(base), 109, 112
str(base), 81
stripchart(graphics), 234
strsplit(base), 66
sub(base), 66
subset(base), 73
substitute(base), 87
substr(base), 66
sum(base), 69
summary(base), 39, 128, 171, 172, 183
summary.glm(stats), 188
summary.manova(stats), 167
suppressWarnings(base), 112
supsmu(stats), 194
Surv(survival), 229
surv test(coin), 230
survdiff(survival), 230
survfit(survival), 229
survreg(survival), 232
svd(base), 76
svdpc.fit(pls), 192
Sweave(Sweave), 105
sweep(base), 150
switch(base), 44
symbols(graphics), 260
system(base), 116
system.time(base), 115
t(base), 76
t.test(stats), 206
table(base), 64, 128, 202
tail(utils), 72
tan(base), 21

SKOROWIDZ

tapply(base), 70
tempdir(base), 59
tempfile(base), 59
terrain.colors(grDevices), 257
text(graphics), 57, 263
title(graphics), 262
toBibtex(utils), 107
toLatex(utils), 107
tolower(base), 66
topo.color(grDevices), 257
toString(base), 41
toupper(base), 66
traceback(base), 111
transcan(Hmisc), 147
trigamma(base), 22
trunc(base), 21
try(base), 112
typeof(base), 81
unclass(base), 81
undebug(base), 111
union(base), 121
unique(base), 69
uniroot(stats, 122
unlink(base), 60
unlist(base), 70
unstack(utils), 74
unz(base), 102
upper.tri(base), 76
url(base), 102
url.show(utils), 101
UseMethod(base), 52
var(stats), 126
var.test(stats), 209
vector(base), 67
vif(car), 179
vignette(utils), 108
vioplot(vioplot), 135
waller.test(agricolae), 158
warning(base), 112
weighted.mean(stats), 126
which(base), 35
which.max(base), 35
which.min(base), 35
wilcox.test(stats), 206
wireframe(lattice), 244
with(base), 73
write.csv(utils), 95
write.table(utils), 61, 92
writeBin(base), 102
writeLines(base), 102
X11(grDevices), 100
xfig(grDevices), 100
xtable(xtable), 106
xtabs(stats), 64
xxp(asuR), 176
funkcje
anonimowe, 50
arytmetyczne, 21
Bessela, 121

do manipulacji właściwościami obiektów, 81
do operacji na plikach, 60
dystrybuanty i gęstości, 144
generatory liczb losowych, 144
importu/eksportu danych, 98
konwertujące typ/klasę, 31
operacji na źródłach danych, 102
operowania na napisach, 66
polimorficzne, 51
specjalne, 22
trygonometryczne, 21
tworzące kontrasty, 161
wykresy diagnostyczne, 176
z rodziny apply, 70
instrukcja
for, 45
function, 47
if, 42
if-else, 42
repeat, 46
switch, 44
while, 46
klasa
anova, 156
array, 80
call, 117, 123
data.frame, 72
density, 131
ecdf, 132
expression, 123, 257
factor, 63
glm, 183, 185
histogram, 130
htest, 200
lm, 170
matrix, 80
nls, 190
summary, 39, 128
summary.glm, 184
summary.lm, 170
Surv, 229
survfit, 229
try-error, 112
operator
::, 6
%in%, 36
->, 53
->>, 53
<-, 53
<<-, 53
=, 53
malpka, 83
operatory, 54
arytmetyczne, 21
pakiet
agricolae, 157

291

292

SKOROWIDZ

asuR, 176
betareg, 194
bnlearn, 196
boot, 225
bootstrap, 225
BSDA, 97
circular, 235
colorRamps, 258
contrast, 160
copula, 140
debug, 109
Defaults, 50
e1071, 126
evd, 144
evir, 144
fdrtool, 223
foreign, 96, 98
fortunes, 1
gam, 196
ggm, 196
ggplot, 234, 250
ggplot2, 251
gmodels, 160
gRbase, 196
grDevices, 100, 257
grid, 251, 263
Hmisc, 95, 98
iplots, 247
ipred, 233
irr, 219
lattice, 251
locfdr, 223
matlab, 96
MCMCpack, 144
mehods, 84
mnormt, 144
multcomp, 160
multtest, 223
mvnorm, 144
nlme, 193
nortest, 199
orthopolynom, 119
pixmap, 254
plotrix, 250
pls, 192
polynom, 118
psy, 219
psych, 126
quantreg, 195
R.matlab, 96, 98
Rcmdr, 5
RColorBrewer, 258
rgl, 236
RMySQL, 103
RODBC, 103
sem, 196
stats, 126, 144, 160, 194, 223
survival, 228
Sweave, 104

recycling rule, 76
test
niezależności
χ2 , 216
Cochrana-Mantela-Haenszela, 217
Fishera, 216
normalności
Andersona Darlinga, 199
Cramera-von Misesa, 199
Lillieforsa (Kolmogorova-Smirnova), 199
Pearsona, 199
Shapiro-Francia, 199
Shapiro-Wilka, 199
równości średnich
Kruskala-Wallisa , 206
t Studenta, 206
Wilcoxona (Manna-Whitneya), 206
równości parametrów skali
Ansari-Bradley, 209
Mooda, 209
równości proporcji, 211
równości wariancji
Bartletta, 209
F, 209
Flingera-Killeen, 209
symetrii
McNemary, 217
współczynnika korelacji, 214
typ
konwersja, 31
sprawdzenie typu, 31
zmienna
.Last.value, 33
.Machine, 113
.Platform, 113
.Random.seed, 139
letters, 38
NA, 29
NaN, 27

●
●
●
●

●

●

●

●

●
●
●
●

R

Przewodnik po pakiecie

Pakiet R jest wykorzystywanym na całym świecie narzędziem do analizy danych, zarówno finansowych,
biologicznych, medycznych jak i dowolnych innych. Możliwościami R przewyższa większość profesjonalnych pakietów statystycznych. Rozwijany przez największych światowych ekspertów oraz setki entuzjastów umożliwia przeprowadzenie rzetelnej analizy, zobrazowanie wyników czytelnymi wykresami, automatyczne wygenerowanie raportu, wysłanie go mailem renderując przy okazji trójwymiarową animację.
Na dodatek R jest darmowy do wszelkich zastosowań, tak edukacyjnych jak i biznesowych.
„Przewodnik...” to pierwsza polskojęzyczna książka w całości poświęcona R. Czytelnik znajdzie tu przystępne wprowadzenie, opis użytecznych bibliotek, zaawansowanych mechanizmów oraz informacje na temat setek przydatnych funkcji. Szczególny nacisk został położony na przedstawienie elastyczności języka R
oraz zademonstrowanie statystycznych i graficznych możliwości tego pakietu.
Z „Przewodnika...” skorzystać może szeroka rzesza użytkowników R:
• Osoby początkujące, nie mające jeszcze kontaktu z R, znajdą tu łagodne wprowadzenie, wiele
komentarzy, opisów i szczegółowo omówionych przykładów.
• Osoby korzystające już z R znajdą opis wielu przydatnych dodatkowych zagadnień takich jak
programowanie objaśniające, debugger, profiler, leniwa ewaluacja, odczytywanie danych z rożnych
źródeł danych i wielu innych. Pozwoli im to usystematyzować, uzupełnić i pogłębić wiedzę o pakiecie R.

●

• Eksperci, pracujący z R na co dzień, znajdą tu podręczną ściągawkę zawierającą 43 tabele, 98
ilustracji, 332 przykłady kodu R oraz opis 578 przydatnych funkcji, często wraz z listą i opisem
argumentów oraz dodatkowymi uwagami. Zamieszczone schematy i ilustracje pozwolą na szybkie
wyszukiwanie ważnych informacji.

●

Wydanie książki dofinansowane przez
Instytut Podstaw Informatyki PAN

x5 − 4x3

exp(cos(x2) − x)

5

6

7

8

xlab − etykieta osi x
sub − podtytul wykresu

●

●

32

0

srt = 0
srt =
340

=

srt

40

srt

=

srt=

=3

srt = 280
srt = 260
srt

=2

40

●

lend=1

lend=0
●

ljoin=0

20
srt =

●

●

ljoin=1

ljoin=2

00

srt

Rysunek 4.45: Właściwości tekstu, osi i końców linii

family
sans

side 1

φαµιλψ
σψµβολ

side 3

family
mono

main, line=3

main, line=5

main − tytul wykresu

●

text()
adj=c(0,1)
text()
adj=c(1,1)

text()
adj=c(0.5,1)

text()
adj=c(0.5,1)

text()
adj=c(0,0)
text()
adj=c(1,0.5)

family
serif

●

xpd=NA

xpd=TRUE

xpd=, adj=

xpd=FALSE

kwantyl 90%

3. kwartyl

mediana

1. kwartyl

cos(x)2 + sin(x)2

legend()
x
x3
x2
x4

moda

ś rednia

lend=, ljoin=

Y |X ∼ N (µ, σ 2 )
E(Y |X) = µ = W β
W |X = γX

Dostępny w mvr(pls), svdpc.fit(pls).

Model regresji PCR
Metoda regresji grzbietowej
Dostępna w lm.ridge(MASS).

Rysunek 3.35: Wybrane modele regresji i metody estymacji parametrów o których piszemy w tym rozdziale

Dostępny w glm(stats).

Metoda estymacji odpornej
Dostępna w rlm(MASS), lqs(MASS).

Y |X ∼ B(p, 1)
p
h(E(Y |X)) = log 1−p
= Xβ

Obecne są

HH
j wartości odstające

HH
Bardzo dużo
kolumn X

?

Y |X ∼ N (µ, σ 2 )
E(Y |X) = µ = Xβ

są współliniowe

Dostępny w lm(stats).

Liniowy model mieszany lub losowy



Y |X ∼ N (µ, Σ = σe2 I + σa2 Z)
E(Y |X) = µ = Xβ

Dostępny w lme(nlme), nlme(nlme) (nieliniowy).

Model regresji liniowej

 Kolumny X

Dostępny w gam(gam).

Model regresji logistycznej

Y |X ∼ F
P(θ)
h(E(Y |X)) =
s (Xj )
j j

Zmienna Y

jest binarna
HH
j

HH
Zakłócenie ma
rozkład gaussowski

?

Y |X ∼ F (θ)
h(E(Y |X)) = Xβ

Dostępny w glm(stats).

H
H f (X, β) jest liniowa
 HH

j
Y nie są niezależne

?

Y |X ∼ N (µ, σ 2 )
E(Y |X) = µ = f (X, β)

Dostępna w nls(stats).

●

●

Regresja segmentowa
Dostępna w segmented(segmented).

-

Ogólny model addytywny GAM

?

HH
HH
j
Regresja nieliniowa

Lokalne wygładzanie
Dostępne w lowess(stats), loess(stats).







Ogólny model liniowy

Y |X ∼ F (θ)
h(E(Y |X)) = f (X, β)

Dostępny w gnls(nlme).

60
40
20

Ogólny nieliniowy model regresji (GNLS)

80
zawod.

!!
!!

> # losujemy obserwacje z rozkładu lognormalnego
> wek = rlnorm(100)
> # estymujemy parametry w rodzinie rozkładów normalnych
> fitdistr(wek, "normal")
mean
sd
1.5460227
1.6830700
(0.1683070) (0.1190110)
> # estymujemy parametry w rodzinie rozkładów gamma
> fitdistr(wek, "gamma", list(shape=3,rate=3))
shape
rate
1.1445007
0.7402887
(0.1441915) (0.1161330)

0

0

Do oceny parametrów metodą maksimum funkcji wiarogodności w określonej rodzinie rozkładów służy funkcja fitdistr(MASS). Estymowane mogą być parametry
dla szerokiej klasy rozkładów, praktycznie wszystkich wymienionych w tabeli 3.2.
Pierwszym argumentem funkcji fitdistr() jest wektor obserwacji na bazie którego wykonana będzie estymacja, drugim argumentem powinna być nazwa rozkładu
a trzecim argumentem lista z inicjującymi ocenami parametrów rozkładu. Trzeci argument nie jest wymagany dla rozkładu normalnego, log-normalnego, wykładniczego i Poissona. Poniżej przedstawiamy przykład wywołania tej funkcji. Poza ocenami
parametrów wyznaczany jest też błąd standardowy tych ocen (w nawiasach).

=6

podsta. srednie wyzsze

1.0

20

0.8

=1

0.6

srt = 80

0.4

srt = 100

0.2

Estymacja parametrów

srt

Ścieżka do pliku może być również adresem URL! Korzystając z takich ścieżek możemy odczytywać dane z plików umieszczonych na innych
komputerach. Przykładowe zbiory danych wykorzystywane w tej książce
mogą być w ten sposób odczytane z Internetu.

0.0

3.2.2.1

srt

Rysunek 4.28: Stereogram, wykonany z użyciem funkcji cloud(). Spróbuj zobaczyć ten obrazek
w trzech wymiarach.

!!!

!!

Y

0.00

0
22
=
200
srt =
srt = 180
srt =
160
14
0

Z
Y

Rysunek 1.7: Okno systemowe umożliwiające wybór jednego lub więcej plików. Wynik
działania funkcji file.choose() lub choose.files()

0.25

Rysunek 3.14: Wybrane charakterystyki rozkładu ciągłej zmiennej losowej, na przykładzie rozkładu B(2, 5)

side 2

●
●
●
●
●
●
●
●
●
● ●●

0.50

=

● ●●●
● ●● ●
●●
●
●
●
●
●● ●
● ●●
●
●
●
●
● ●●
● ●● ● ●
●
●
●
●
●
●● ●
● ●
●
●● ●
●
●●
●
●●●●● ●
●
●
●
●
●
●● ● ●
●●
● ●
●
●
●
●
●
●
●●
●● ●
●●
● ●
●●
●
●
●
●
●
●
●
●● ●
●
● ●
●●●
● ●●
● ●●
●
● ●
●● ●
● ●●
●
●
● ●
●●
●
●
●●
●
●●● ●
●●●●
●
● ● ●
●
●
●
●
●
●
● ●
●
●
●
●
●
● ● ●●
●● ●
● ●
●
●● ● ● ●●
●
●
●
●●
●
●
●
● ●
●
● ●
●●
●
●
●
● ●
●●
●
●●
●
●● ●
●
●●
● ●●
●
● ●●
●
●
●●
● ●● ●
●●
●
●●
●
●
●
●
●
● ●●
●
●
● ●
●
●
●
●
●
●
●●●
●
●
●
●
●●
● ●
●
●
●
●
●●
●
●
●
●●
●
●
●
●
●●
●●
●● ● ● ●
●● ●●
● ●
●
●
● ●
●● ●
●
●
●
●
●●
●●●
●●
●
●●
●
●
●●●
●
●
●
●
●
●●
● ●
●
●
● ●
●
●
●
●
● ●
●
●
●
●
●
●● ●
●
● ● ●
●
●
●
●
● ●
●
●
●
● ● ● ●
●
● ●
●
●
●
● ●
●
● ●
●
●
●
●
● ● ●
● ●
●●
●
●
●●
●
●
●
●
●
●
●
●
●
● ●
●
●
●
●
● ● ●
●
●
●
●
●
● ●
● ●
●● ● ●
●●
●
●
●
●
● ●●●
●
● ●
● ●
●
● ●●
● ●
●
● ●
●
● ●
●
●
● ●●
● ● ● ●
●
●
●●●
●
●● ●
● ●● ●
●
●
●
●
●
●
●● ●
● ●●
● ●
●
●
●● ● ● ●● ●● ● ● ● ● ● ●
●
●
●●
●
●
●●
●
● ● ● ●●
●●
● ● ●●
● ● ● ● ● ●● ● ●●
●
●
●
● ● ●
● ●
●
● ●
●
●
●
●
●
●●
● ●
●●
●●●
●
●
●
●
●
●●●●
●●
●
●● ●
●
● ● ● ●●
●● ●
● ●
●● ●
●
●
●
●●
● ● ●
●
● ●
●
●
●
●
●
●
●
●
●
●
●
●
●● ●
● ●
●
●
●
●
● ● ●
●●
●●
●
● ●
●
● ●● ● ● ●
●●
●
●
●
●
● ●
● ●
●
● ●
● ● ●
● ●
●
●●
●
●●
●● ●
●
●
●
●
●
● ●
●
●
●● ●
●
●
● ●
●
●
●
●
● ●
●
●●
●
●
●
●
●
●
● ●●
●
●
●
●
●
●
●
●
●
●●
●
●
●
●
●●
●
● ●●
●
●
● ●
●
●
●
●
●
●
●
● ●
● ●
● ●
●●●● ●
●
●
●
●●
● ●●
●● ●
●
●
●
●
●
●
●●
●
●
●
●
●●
●
●
●
● ● ●
●
● ●
●
●
●
●
●●
● ●
●
●
●
●
●
●
●
●
●●
● ●
●●
●
●
●
●
●
●
●
● ●
●
●●
●
●
●●
●●
●
●
●
●
●
●
●●
●
●
●
●
●
●
● ●
●
●
●
●
●●
●
●
● ●
●●
●●
●
●
●
● ●● ● ● ●
●
●
●
● ●
●
●
●
●●
● ●●
●●● ● ●●●
●●
●
● ●
● ●
●
●●
●
●
●●
●
●●●
●● ●
●●
● ●● ● ●
● ● ●●
●●●● ●●
●
●
●
●
●
●●
●
●
● ●●●
● ●●
● ●
●
●●
● ●
●
● ●●●
●
●● ●
●
●
●
●
●
● ●
●
● ● ●
●● ●
●●
●
●
●
●
●
● ● ●●
● ●●
● ●●
●● ● ● ●
●● ●● ●● ● ●●
●
●●
●●●
●●●
●●●●●
●●
●●
●
●●
●
● ●
●● ●
● ● ●●
●
●● ●
● ●
●●●● ●●
●
●
●
●
●● ●
●
● ●
● ●
● ●
● ● ● ●●
●●● ● ● ●
●● ●● ●
●
●●●●● ● ● ●
●● ●
●●● ● ●
● ● ● ● ● ●●
●
●
●● ● ●
●
●
● ● ● ● ● ● ●●●● ●
●●
●● ●
●
● ● ●●
●
●● ●
●
●●
●
●
●
●● ● ● ● ●
●
●●
● ●
● ●●
●
●● ● ●
●●
●
●●
● ●
●
●● ●
●● ●●
●●
●● ●●● ●
●
●● ●
●
●●●●
●● ●● ●
●●
● ● ●
●●
● ●●
●
●
● ●●
● ● ●●
● ● ●
● ● ●●
●
●●
●● ●●
●
●● ●
●
●
●
●
●● ●
● ●
● ● ● ● ●●● ●●
●
●
● ●
●
● ●●
●●
● ● ●●●●●●
●●
● ● ●●
●●
● ●
●
●
● ● ● ● ● ●● ●●
● ●●
● ● ●● ● ●
●●●
●●
●● ●●
● ●●
●
●● ●
●● ● ●● ● ● ●
●●●
●●●●●
●
● ●● ●●
●
●
●
●
●●
●
●● ●
●
●
● ●
● ● ●●
● ●
●
●
●
● ●
●
● ● ●●●
●
●
●●● ● ● ● ● ● ● ●●●●
●● ●●
● ● ● ● ●●●
● ●
● ●● ●
● ●● ●
● ●
●● ●
●● ●● ● ●
●
●
●
● ● ●● ●
● ● ● ●●●●
●●
●
●●
●
●
●
●
●●
●
● ●
● ●●●
●● ●
●● ● ●●
●● ● ●● ● ● ● ●
●
●
● ●●● ● ● ●
●
●●● ●
●
● ●
●
●
●
●
●
●
●●
●
● ●●● ● ● ● ● ●
● ● ●
●●
●
● ●
●●
●●
●●
●
●● ●●
●
●
●
●
●
●●
●● ● ● ●
●● ●●
●
●● ● ● ●
●
● ●
●●●
●●
●
●●
● ●
●●
●● ● ● ●●
●● ●
●●
●
●
●
●
●●
● ●
● ●●●
●
● ●●
● ●
●
●●●●●
●● ●
●●
● ●●● ● ● ● ● ●● ●
● ●
●●
●●
● ●
●
●●
●
● ●
●
●
●
●● ●
●
● ● ●● ● ●●
●●
●
●
●
●● ●●
●● ●● ●
●
● ● ●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●●
●●
●
● ●
●
●
●
●●
●● ●
●
●
●
●●
●●●
●
●
● ● ●●
● ● ●●●● ●● ●
●
●
●
●
●
●
●
●
●
● ● ●
● ●
●
● ●● ● ●
●
● ●
●
●●● ● ● ●
●●
●●●
●
●
●
●●
●●
●●
● ●●
●●
●
●
● ●
●
●● ● ● ●● ●●
●
●● ● ● ●
●
●
●● ● ●●●
●
●
● ●
●● ●●
●
●
●●● ●
●●
●
●
●
● ● ●
● ● ●
●● ●
●
●
●●
●
●● ●
●
●●
●
●
●
● ● ●
●
● ●
●●●●●
●
●●
●
●
●● ● ●● ●● ●
●● ●
●
●●
●
●
●
●
●● ●
●
●
●
●
●● ●●
●
●● ●●
●
●
●
●●
●
●●
●
●
●●● ●● ●● ●
●
●
●●●
● ●
●
●
● ●
●
● ●●
● ●
●●● ●●
●
●●
●●●
●●
●
● ●● ●●
●
●
●●
●
●●
●
●
●
●
●●
●●
●●●● ●● ●
●
●●
● ●●●● ●
●
● ●
● ●
● ●
●
● ● ●●
● ●
●
●●●
● ●
●
● ● ●
● ● ●●
●●
● ●
●
●●
●●
●
●
●●
●● ●
●
●●●● ●
● ● ●
●● ●
●● ● ● ●●●
●
●●
● ●●
●●●●● ● ●
●●● ●
●

X

1.0
dystrybuanta

ylab − etykieta osi y

zawod.

legend()

wyzsze

0.8

srt

Z

srednie

0.6

srt

● ● ●●●●● ● ●
●●
●
●
●
●● ●
●
●●
●●
●●
●●
● ●●
● ●
●
●
●
●
● ●● ●
●
●
●
●
● ●●
●
●● ●
●●●●
●
●
●
●
●
●● ● ●
●
● ● ●
●
●
●
●
●●
●
●
●●
●
● ●
● ● ●
●
●
●
●
●
●
●
●
● ●
●●
●● ●
●
●
●●
●
●
●
●● ●
●
●
● ●
●●
●
●
●
●
●
● ●
●
● ●●
●
●
●●
●●● ●
●● ●
●
●●
●
●●
●
●
●●
●
●●
●
●
● ●
●● ●
● ●
● ●
●
●
●
●
●
●
●●
●
●
●
● ●
●
●●
●
●
●
●●●
●●
●
●
●●
● ●
●
●●
●● ●
●
●
●
●●
●
● ●●
●
●
●
●
● ●
● ● ●●
● ●
●
● ● ● ●●
●
●
●
●
●●
●
●
●
●
●
●
●
●
●
●
●
●
●
●●
● ●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
● ●
● ●
● ● ●
●
●
● ● ●●
●
●
●●
● ●
●
●
● ●
●
●
●
●
●
●
●●
●●
●
●
●
●●
●● ● ●
●
● ●
●
● ●
●
●
●
●
● ●
●
● ●
●
●●
●
● ●
●
●●
●●
● ●
●
●
● ●
●●
● ●
●
●
●
●
●
●● ●
●
●
●
● ●
●
●
●
● ●● ● ●
●
●
● ● ●
●
●
●
●
●
●●
●
● ● ●
●
●
●
● ● ●
●
● ●
●
● ●● ●●
●●
● ●●
●
●
● ●
●
●
●●●
●
● ●●
●● ● ●
●
●●
● ●
●● ●
● ●
●
● ●
●
● ●
●
●
●
●
●
●
● ●●
●
●
●
●
● ● ● ●●●
●
●
● ●
●
● ●
●●
●
●
●
●● ●
●● ●● ● ●
●
●
● ●● ●
●
●
●
●
●
●
● ●
● ●
●●●●●
●
● ●
●
● ●●
●●● ● ● ● ● ●
●● ●●●
●●
●
●
●
●
●
●
●
●
●
●
●●
●
●
● ●●
●
● ●●
●
●
●
●
● ●
●
●
●
●
● ●
●
●● ●
● ●
●● ●●
●●
●● ●
●●●
● ●
●● ●
●
●● ●
●
●
●●●
● ● ●
●● ●
●
●
●
●
●
●●
●
●
●
●
●
●
●
●
●
●
●
●●
●
●
● ●●
●
●
●●
●
●
●
● ●● ● ●● ●
● ●
●
●
●● ●●
●
●
●●●
● ●● ●
●
● ●
●
●
●●
●
●
● ● ●●
●
●
●
●
●
●
●
● ●●
● ●
●
●
●● ●
●
●
●●
●
●
●
●
● ●
● ●
●
●
●● ●
●
● ●
● ●
●
●
●
●●
●
● ●●
●
●
●
●●
●
● ●
●
●
●
●●
●
●
●
●
●●
●
●
●
●●
● ●
●
●●
●
●
●
●
●
●●●
● ●
●
● ●●
●
●
●
●
●
●●
●
●
●
●
●
●
●
●
●
● ●
●
●
● ●
●
●
●●
●
●
●
●
●
●
●
●●
●
●
●
●
● ●
●
●
●●
●
●
● ●●
●
●
●
●
● ●
●
●
● ●
●
● ●
●
●
●●●● ●
●
●
●
●
●
●
● ●
●
●
● ●
●
●
●
●
●
●
●
●●
●
● ●
● ●
●
●
● ● ●●
●
●
● ●
●
●●
●
●
●
●●
●●● ● ● ●●
● ●
●
●●
● ●
●
●
●
●
●●
●●●
●
●
●
● ●● ● ●●
●
●● ●●●
●●● ●●
●
●
●●
●●
●
●
●
●●
●●
●
●
●● ●
● ●
●
●
● ●●●
●●
● ●
●●
●
●
● ●●
●
● ●
●
●
● ●●
●●
●
●
●
● ●●
●
● ●●
● ●●
●
●●●
●
● ●●
●●
● ●● ●
●
●●●●● ● ●● ● ● ●●●●●
●
● ●●●
●●●●
●
●
● ●●●
●
●● ● ●●
●
●●
● ●●
●
●
●
●● ●
● ●●●
● ● ●● ●
●
●●
●
●
●●
● ●
●
●●
●
●●
●●
●
●● ●
●
●● ●
●
●
●● ● ●
●●
●● ●
●
●
● ●
●
●●
●●
●●●● ● ●●●
●
●● ●
● ●
●● ● ● ● ● ● ●
●
● ● ●●● ●
●
●
●
●
●
●● ●
●
● ● ●● ●●
●
●
●●
● ●
●●
●
● ● ● ●● ●
● ●●
● ●
●
●● ●
●
● ● ●●
● ● ● ●
●●●
●●
●
●
●● ●●
●
●
●
●● ● ●●
●●
●●
●● ● ●
●
●
●
● ● ●●
● ●●
● ● ●●
● ●●
●● ●
●●
●● ●
● ●● ●
● ●● ●
●● ●
●
● ●
● ● ●
●
●
●
●
●● ●
●●●● ● ●●
●●●●●
●● ●●
● ●
●● ● ●●● ●●● ● ●●
●
● ●
●●
●●
●● ● ●●●
●●
●
●
●●● ● ●
●
●● ●●
●●
● ● ● ●
● ●●
●
●● ● ●● ● ● ●●● ●
●
● ●
● ●● ●●
●
●
●
●
●●
●
● ●
●● ● ●
●
●
●●●
●
● ●●
●
●
●
●●
●
● ●● ●
●●
●
●
●
●●
●
● ● ●●
●
●●● ● ● ● ● ●
●● ●●
● ●
● ● ● ● ●●
●
●
● ● ●
● ●
●●●●
●
● ●
●● ●●●●
● ● ●●
●
●
●
●
●● ●●
●●
●
●
●● ●
●●
●
● ●
●●
●●●
●
●
●
●● ●
●
● ●
●
●
●
●
●● ●
● ●●●●
●●● ●
●
●●
●
●● ● ●●●
● ●● ● ●
●
● ● ●●
●
●
●
●●
●● ● ●
●●
●●
●
●
●● ●
●● ●●● ● ● ●
●
●● ●●
●●● ●
●
●●
●● ●●
● ●
●
●●●
●
● ●
● ●
●●
●●
●● ● ●
●● ●
●
●● ●
●
●
●
●●● ●
● ●
● ●
● ●●●
●●
● ●●
● ●●
●
●
● ● ●● ● ● ● ●● ●
●
●● ●
●●
●●
●
●●
●
●● ●
● ●
●
●
●● ●
●
●● ●
●
●
●●●
●● ●
●
● ●●
●● ●●
● ● ● ●● ●●
● ●●
●
●
●
●
●● ●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
● ●●
●
●
● ●
●
●
●
●
●● ●
●
●●●
●●
●
● ● ●● ● ● ●
● ● ●● ● ●
●
●
●
●
●
●
●●
●
●
● ● ●
●
● ● ● ● ●●
●
●
●●
● ●
●●● ● ● ●
●
●●
●
● ●
●●
●●
● ●
●●
● ●●
●
●●
●
●● ● ● ●●●●
●
●● ●
●
●● ●●
●
●● ● ●●●
●
● ●
●
●
●
●●
●
●
● ● ●
●●● ●
●
●
●●
●
●● ●
●●●●●●
●● ●● ●
●●
●
●
●
● ● ●
●●
●
●
●
●●
●
●
●
●
●
●● ● ●● ●● ●
●
●● ●
●
●
●● ●
●
●
●
●
● ●●
●
●
●
●●●
●
●
●
●
●
●●
● ●
●
●●● ●● ● ●
●
●
●
● ●
●
● ●● ●
●●●
● ●
●
● ●●
● ●
●
●
●●●
●●
●● ●
●●
● ●● ●●
●
●●
●
●
●●●
●
●●
●
●
●●
●●
●
●●●●● ●● ●
● ●●●● ●
● ●
●
●
● ●
●
● ●
●
● ● ●●
●●●
●
●
●
● ●
● ● ●●
●●
● ●
●
●●
●
●● ● ●● ●●●
●●
●●
●
●●
●
●
● ●
● ● ●
●●
●
● ●●●● ● ●
● ● ●●●●●● ● ●
● ●●
●

X

podstaw.

Rysunek 4.27: Wykres słupkowy, barplot().

*

axis()

80

0.0

1.00
0.90
0.75

side 4

60

przed

40

0.0

mtext(), adj=0 line=1
mtext(), adj=0.5 line=2
mtext(), adj=1 line=3

20

Rysunek 4.26: Wykres słupkowy, barplot().

0.5

expression()

7

1.0

ln(x y)

8.5
15
10

8.0

16

7.5

24

22

!!

39

7.0

Jeżeli nie chcemy wpisywać ścieżki do pliku z klawiatury, możemy wyklikać ją korzystając z funkcji file.choose(base) lub
choose.files(base). Obie funkcje otwierają okno systemowe pozwalające na wskazanie pliku lub plików. Wynikiem obu funkcji jest wektor
ścieżek do wskazanych przez użytkownika plików. Przypomnijmy, że R ma możliwość
uzupełniania ścieżek. Jeżeli przy wpisywaniu ścieżki do pliku lub katalogu naciśniemy Tab to R uzupełni nazwę wpisywanego katalogu lub pliku.

!!!

6.5

kobieta
mezczyzna

71

6.0

Rysunek 4.25: Wykres kołowy, pie().

5.5

Rysunek 4.24: Wykres kołowy, pie().

Przydatną funkcją, zapisującą do pliku tekstowego przebieg interakcji z R, jest
funkcja sink(nazwa.pliku). Jej wywołanie, powoduje przekazanie wyjścia z konsoli
R do wskazanego pliku (domyślnie wyjście to jest kierowane zarówno do pliku jak
i na ekran, ale można zarządzać by było kierowane tylko do pliku). W wyniku jej
działania, we wskazanym pliku znajduje się cała historia interakcji z R, czyli kopia
wszystkiego co działo się na konsoli R.

1.5

po

podstaw. 46 %

w trakcie

wyzsze

gestoś ć
2.0

chwile po

zawod.
srednie

0

143

3.2. Liczby losowe

# generujemy losową nazwę dla tymczasowego pliku
tmpf <- tempfile()
# wpisujemy do tego pliku napis
cat(file=tmpf, "Poczatek pliku")
# tu operacje na pliku
# ....
# na koniec kasujemy tymczasowy plik
unlink(tmpf)

chwile przed

srednie 27 %

5.0

Rozdział 1. Łagodne wprowadzenie do R

wyzsze 17 %

zawod. 11 %

4.5

60
podstaw.



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.4
Linearized                      : No
Page Count                      : 82
Producer                        : MiKTeX pdfTeX-1.40.4
Creator                         : TeX
Create Date                     : 2008:08:20 17:42:53+02:00
Modify Date                     : 2008:08:20 17:42:53+02:00
Trapped                         : False
PTEX Fullbanner                 : This is MiKTeX-pdfTeX 2.6.2838 (1.40.4)
EXIF Metadata provided by EXIF.tools

Navigation menu