Więcej informacji na temat R można znaleźć pod tymi linkami:
Program R działa na zasadzie “pytanie-odpowiedź”. Wprowadzamy dane lub polecenie do konsoli, a program wykonuje operacje i wyświetla wynik oraz czeka na kolejne instrukcje. Znakiem zachęty (prompt) do wprowadzania kolejnych instrukcji jest symbol >
.
Wszystkie prezentowane przykłady powinny działać jeżeli zostaną wpisane DOKŁADNIE tak jak w instrukcjach. Niektóre polecenia R stają się dostępne dopiero po uruchomieniu odpowiednich bibliotek. Należy zawsze upewnić się, że wymagane biblioteki są zainstalowane i załadowane. Do ładowania bibliotek służy polecenie library
.
Zobaczmy jak działa R w praktyce.
plot(rnorm(1000))
Jednym z najprostszych zastosowań programu R jest wykorzystanie go do obliczeń arytmetycznych. Jeżeli wprowadzimy działanie komputer wyświetli nam wynik działania np.
2+3
## [1] 5
11-5
## [1] 6
2*4
## [1] 8
33/11
## [1] 3
R pozwala także na wykonanie bardziej skomplikowanych obliczeń np. \(e^{-2}\)
exp(-2)
## [1] 0.1353353
Symbol [1]
wyświetlany przed wynikiem jest ‘Rową’ konwencją wyświetlania liczb oraz wektorów. Tutaj nie wydaje się on szczególnie przydatny. Jest on jednak bardzo użyteczny przy większej liczbie wyników. Liczba w nawiasie kwadratowym jest indeksem liczby w danej linijce. Zobaczmy jak to działa na przykładzie. Wygenerujmy 15 losowych liczb z rozkładu normalnego \(\mu=0, \sigma=1\).
set.seed(123)
rnorm(15)
## [1] -0.56047565 -0.23017749 1.55870831 0.07050839 0.12928774
## [6] 1.71506499 0.46091621 -1.26506123 -0.68685285 -0.44566197
## [11] 1.22408180 0.35981383 0.40077145 0.11068272 -0.55584113
Nawet korzystając z prostego kalkulatora często spotykamy się z potrzebą zapisania cząstkowych lub pośrednich wyników obliczeń, tak aby nie trzeba było ich ponownie obliczać.
R podobnie jak inne języki porgramowania pozwala na zapisywanie informacji w pamięci podręcznej komputera jako tak zwane “zmienne symboliczne”. Oznacza to, że możemy wartościom (np. liczbowym) przypisać nazwy, a następnie ponownie użyć tych wartości przy pomocy stworzonej nazwy. Aby przypisać wartość wartość do zmiennej w języku R używa się symbolu <-
. Przykładowo jeżeli chcemy stworzyć zmienną x
i przypisać jej wartość 2 wykonujemy:
x <- 2
Utworzoną zmienną możemy następnie przywołać:
x
## [1] 2
Lub użyć w dalszych obliczeniach:
2*x + 3
## [1] 7
Nazwy zmiennych mogą być w R tworzone dość swobodnie. Możemy stosować litery, liczby oraz symbol kropki (.) oraz podkreślenia (_). Istnieją jednak pewne ograniczenia, nazwa nie może rozpoczynać się od liczby, lub od kropki, a po niej liczby. Typowa nazwa zmiennej w R może wyglądać tak: wysokość.1rok
. Nazwy zmiennych w R są wrażliwe na wielkość liter, czyli WT
i wt
dla R oznaczać będą dwie różne zmienne. Niektóre zmienne są zarezerwowane dla samego R. Zaleca się niestosowanie tych nazw do nazywania zmiennych. Zmienne jednoliterowe wykorzystywane przez R to: c,q,t,C,D,F,I
oraz T
. Inne nazwy wykorzystywane przez R to: diff, df,
oraz pt
. Większość z nich to nazwy funkcji. Użycie tych nazw do nazwania własnych zmiennych nie zawsze będzie prowadziło do problemów, jednak zaleca się nie używanie tych nazw. Przykładowo F
oraz T
są skrótami słów kluczowych True
oraz False
. Użycie F
i/lub T
spowoduje, że te skróty nie będą działać poprawnie.
Nie możemy wykonać zbyt wielu analiz statystycznych na pojedynczej liczbie! Analizy statystyczne wykonywać będziemy na danych pochodzących z grupy pomiarów (np. grupa pacjentów). Jedną z zalet R jest to, że może przechowywać cały wektor danych (np. pomiarów) jako pojedynczy obiekt. Wektor jest prostym szeregiem (ciągiem) liczb. Wektor w R tworzymy następująco:
zaw.Hg <- c(20,21,22,23,27)
zaw.Hg
## [1] 20 21 22 23 27
Nie jest to jedyna droga wprowadzania danych do R, nie jest to też preferowana metoda, jednak krótkie wektory są wykorzystywane powszechnie w R do różnych zastosowań. W późniejszej części przedstawione zostaną inne metody wczytywania danych do programu R.
Na wektorach możliwe jest wykonywanie operacji arytmetycznych, tak jak na “zwykłych” liczbach. Jeżeli wykonujemy operacje na dwóch wektorach muszą mieć one tą samą długość. Zobaczmy to na przykładzie. Załóżmy że mamy wektor z wysokością i masą ciała 6 osób. Możemy utworzyć nowy wektor z wartością współczynnika BMI, który zdefiniowany jest jako stosunek wagi (kg) do kwadratu wzrostu (m). Przykładowo:
wzrost <- c(1.75, 1.80, 1.65, 1.90, 1.74, 1.91)
waga <- c(60, 72, 57, 90, 95, 72)
BMI <- waga/wzrost^2
BMI
## [1] 19.59184 22.22222 20.93664 24.93075 31.37799 19.73630
Zauważmy, że obliczenia wykonywane są na liczbach o tym samym indeksie w obydwu wektorach, to jest BMI 19.59184
został obliczony jako \(60/1.75^2\).
W istocie R pozwala na operacje arytmetyczne wektorów o różnej długości. W powyższym przykładzie wykonaliśmy potęgowania wektora wzrost (długość 6) przez wektor 2
(długość 1). Jeżeli wektory są różnej długości do elementy wektora krótszego są iterowane (powtarzane) na elementach wektora dłuższego. Zazwyczaj operacje na wektorach różnej długości wykonuje się przy modyfikacji wektora przez skalar (liczbę) przykładowo:
waga.g <- waga * 1000
waga.g
## [1] 60000 72000 57000 90000 95000 72000
Arytmetyka wektorowa jest bardzo użyteczna w przypadku obliczeń statystycznych. Przypuśćmy, że chcemy obliczyć wartość średnią oraz odchylenie standardowe dla wartości w wektorze waga
.
W pierwszej kolejności obliczymy wartość średnią, \(\overline{x} = \frac{\sum x_i}{n}\)
sum(waga)
## [1] 446
sum(waga)/length(waga)
## [1] 74.33333
Następnie zapiszmy średnią wartość wektora waga jako zmienna xbar
i przejdźmy do obliczenia odchylenia standardowego, \(SD=\sqrt{(\sum(x_i-\overline{x})^2)/(n-1)}\). Zrobimy to w kilku krokach, żeby zobaczyć obliczenia cząstkowe.
# zapisujemy średnią pod nazwą xbar
xbar <- sum(waga)/length(waga)
# obliczamy różnice między każdą wartością, a wartością średnią
waga - xbar
## [1] -14.333333 -2.333333 -17.333333 15.666667 20.666667 -2.333333
# obliczamy kwadrat tych różnic
(waga - xbar)^2
## [1] 205.444444 5.444444 300.444444 245.444444 427.111111 5.444444
# obliczamy sumę kwadratów (SS)
sum((waga - xbar)^2)
## [1] 1189.333
# obliczamy odchylenie standardowe
sqrt(sum((waga - xbar)^2)/(length(waga)-1))
## [1] 15.42293
Oczywiście R jako pakiet statystyczny ma już wbudowane funkcje służące do obliczania wartości średniej i odchylenia standardowego:
mean(waga)
## [1] 74.33333
sd(waga)
## [1] 15.42293
Jednym z najważniejszych aspektów prezentacji i analizy danych jest tworzenie odpowiednich grafik. R podobnie jak S (język z którego R się wywodzi) ma model do tworzenia wykresów, który pozwala na łatwe tworzenie prostych wykresów, a jednocześnie pozwala na dużą kontrolę nad generowaną grafiką.
Jeżeli chcemy zbadać zależność między wagą i wzrostem, pierwszym krokiem powinno być stworzenie wykresu dla tych zmiennych:
plot(wzrost,waga)
Wygenerowany wykres może być modyfikowany na wiele sposobów, poprzez dodanie odpowiednich argumentów do funkcji plot
. Zmodyfikujmy nasz wykres dodając tytuł, oraz zmieniając kształt symboli punktów, a także ich kolor oraz zakres na osi x i y:
plot(wzrost,waga, main="Wykres 1", pch = 2, col = '#63e218', xlim = c(1.55,2), ylim = c(40,100))
Idea za obliczaniem indeksu BMI jest taka, aby można było określić czy dana osoba jest otyła, na postawie jednej wartości (niezależnie od wzrostu). Ponieważ normalny BMI powinien być w przybliżeniu równy 22.5 możemy oczekiwać, że \(waga \approx 22.5 * wzrost^2\). Możemy następnie na tej podstawie dopasować krzywą do naszego wykresu, określającą oczekiwaną wagę przy danym wzroście (zakładając prawidłowy BMI). Możemy to zrobić następująco:
plot(wzrost,waga, main="Wykres 1", pch = 2, col = '#63e218', xlim = c(1.55,2), ylim = c(40,100))
hh <- c(1.65, 1.70, 1.75, 1.80, 1.85, 1.90)
lines(hh, 22.5 * hh^2)
Funkcja line
wrysowuje linie o zadanych koordynatach (x,y) do ostatniego wykresu. W powyższym przykładzie stworzyliśmy nowy wektor hh
zawierający wartości wzrostu (x), które posłużyły do stworzenia prostej dodanej do wykresu. Użycie tego wektora zamiast surowych danych w wektorze wzrost podyktowane jest dwoma przesłankami:
Zastosowanie wektora wzrost do stworzenia krzywej dodanej do wykresu nie pozwoliłoby na wygenerowanie prawidłowej krzywej.
Najłatwiejszą drogą wczytywania danych do R jest poprzez wczytanie danych z pliku tekstowego poprzez funkcję read.table
lub jej modyfikacje read.csv
oraz read.csv2
. Plik tekstowy z danymi musi być zapisany jako “plain text”, a nie “rich text” (czyli nie zapisywać danych w formacie .doc, .docx, lub .odt). Program R w założeniu tworzony był (i nadal jest) jako część systemu GNU. GNU jest projektem, który stara się imitować system UNIX, a w systemie UNIX dane zapisywane były jako “proste” pliki tekstowe (zazwyczaj rozdzielone znakiem tabulacji). Do R można wczytywać dane zapisane w arkuszach kalkulacyjnych (MS Excel), jednak wymaga to zastosowania dodatkowych bibliotek i nie jest polecaną (przynajmniej dla początkujących) metodą wczytywania danych do programu R.
Funkcja read.table
wczytuje dane jako obiekt data.frame
- tabela i oczekuje, że dane w pliku tekstowym będą miały odpowiedni układ, wartości odpowiadające wierszom będą w poszczególnych liniach (bez pustych linii), a wartości odpowiadające kolumną będą rozdzielone odpowiednim symbolem (tabulator,spacja,przecinek,średnik, itp.). Pierwsza linijka może zawierać nagłówki kolumn (np. nazwy zmiennych).
Analizę statystyczną rozpoczynamy od prostej charakteryzacji danych poprzez ich podsumowanie, a także graficzną prezentację.
Obliczenie podstawowych statystyk dla zbioru danych w programie R jest bardzo proste. Oto jak możemy obliczyć średnią, odchylenie standardowe, wariancję oraz medianę:
set.seed(123)
# generujemy 50 losowych liczb
x <- rnorm(50)
# średnia
mean(x)
## [1] 0.03440355
# odchylenie standardowe
sd(x)
## [1] 0.92587
# wariancja
var(x)
## [1] 0.8572352
# mediana
median(x)
## [1] -0.07264039
Kwantyle mogą zostać obliczone za pomocą funkcji:
quantile(x)
## 0% 25% 50% 75% 100%
## -1.96661716 -0.55931702 -0.07264039 0.69817699 2.16895597
Jak widać dzięki tej funkcji dostajemy wartość minimalną oraz maksymalną z naszego zbioru, a także kwantyle 0.25, 0.5 i 0.75. Możemy obliczyć różnicę między trzecim a pierwszym kwantylem. Rożnica ta nosi nazwę interquartile range - rozstęp ćwiartkowy (IQR) i bywa wykorzystywana jako alternatywa dla odchylenia standardowego.
q <- quantile(x)
IQR <- q[4]-q[2]
as.numeric(IQR)
## [1] 1.257494
Jest możliwe uzyskanie kwantyli dla innych (niż 0.25,0.5 i 0.75) wartości. Jeżeli chcemy uzyskać wartości dla decyli czyli wartości 0.1,0.2,0.3 itd. w R możemy wykorzystać funkcje quantile
z odpowiednim parametrem:
pvec <- seq(0,1,0.1)
pvec
## [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
quantile(x,pvec)
## 0% 10% 20% 30% 40% 50%
## -1.96661716 -1.12461142 -0.68842368 -0.46849617 -0.29942796 -0.07264039
## 60% 70% 80% 90% 100%
## 0.23594940 0.51467063 0.82482227 1.22705511 2.16895597
Zwróćmy uwagę, że istnieje wiele różnych algorytmów na wyznaczenie kwantyli. R domyślnie używa algorytmu sumy poligonu, gdzie i-ty ranga obserwacji jest równa \((i-1)/(n-1)\) kwantylowi, a pośrednie kwantyle są uzyskiwane poprzez liniową interpolację. Inne definicje kwantyli są możliwe do użycia po zmianie wartości parametru type
funkcji quantile
.
Więcej informacji na temat każdej funkcji R możemy uzyskać sprawdzając dokumentację dotyczącą danej funkcji. Dostęp do dokumentacji możliwy jest po wpisaniu symbolu ?
, a następnie nazwy interesującej nas funkcji. Można też skorzystać z okna pomocy programu RStudio.
?quantile
Kolejnym często wykorzystywanym parametrem w statystyce opisowej jest współczynnik zmienności definiowany jako: \(cv=\frac{sd}{\overline{x}}\). Współczynnik zmienności bywa nazywany statystyką ksztaltu rozkładu. Dla naszego przykładu możemy obliczyć współczynnik zmienności w następujący sposób:
cv <- sd(x)/mean(x)
cv
## [1] 26.91205
Jeżeli nasz zbór danych zawiera puste wartości (brak wartości) - NA
, obliczenie średniej (i innych parametrów opisujących dane) staje się bardziej skomplikowane. R z założenia nie pomija wartości pustych (NA
). Zilustruje to następujący przykład:
x1 <- c(x,NA)
x1
## [1] -0.56047565 -0.23017749 1.55870831 0.07050839 0.12928774
## [6] 1.71506499 0.46091621 -1.26506123 -0.68685285 -0.44566197
## [11] 1.22408180 0.35981383 0.40077145 0.11068272 -0.55584113
## [16] 1.78691314 0.49785048 -1.96661716 0.70135590 -0.47279141
## [21] -1.06782371 -0.21797491 -1.02600445 -0.72889123 -0.62503927
## [26] -1.68669331 0.83778704 0.15337312 -1.13813694 1.25381492
## [31] 0.42646422 -0.29507148 0.89512566 0.87813349 0.82158108
## [36] 0.68864025 0.55391765 -0.06191171 -0.30596266 -0.38047100
## [41] -0.69470698 -0.20791728 -1.26539635 2.16895597 1.20796200
## [46] -1.12310858 -0.40288484 -0.46665535 0.77996512 -0.08336907
## [51] NA
mean(x1)
## [1] NA
Wartość NA
należy rozumieć jako nieznaną wartość. Nie można określić wartości średniej zbioru, który zawiera nieznaną wartość. Dlatego przy próbie obliczenia średniej R zwraca wartość NA
. Jeżeli chcemy pominąć wartości NA
przy liczeniu średniej (lub innych parametrów) musimy użyć parametru na.rm=T
, spowoduje to pominięcie przez R wszystkich wartości NA
w zbiorze danych:
mean(x1, na.rm = T)
## [1] 0.03440355
Niestety funkcja length
nie rozpoznaje parametru na.rm
. Jeżeli chcemy otrzymać liczbę elementów w naszym zbiorze danych z pominięciem wartości NA
możemy to zrobić w następujący sposób:
# liczba elementów wektora x
length(x)
## [1] 50
# liczba elementów wektora x1
length(x1)
## [1] 51
# liczba elementów wektora x1 innych niż NA
sum(!is.na(x1))
## [1] 50
Powyższy kod wykorzystuje właściwość wartości boolen
(True
i False
), które w operacjach matematycznych zamieniane są na 1 (True
) i 0 (False
).
Podsumowanie dotyczące zbioru danych możemy też uzyskać korzystając z funkcji summary
:
summary(x)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## -1.96662 -0.55932 -0.07264 0.03440 0.69818 2.16896
Możemy także uzyskać podsumowanie dla całej tabeli.
W R wbudowanych jest kilka powszechnie znanych i wykorzystywanych w celach edukacyjnych zbiorów danych. Jednym z nich jest zbór ‘Irish data set’, więcej informacji można na temat tego zbioru można znaleźć tu. Jeżeli chcemy wczytać do pamięci ten zbór danych możemy wykorzystać funkcję data
.
data("iris")
summary(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
## 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
## Median :5.800 Median :3.000 Median :4.350 Median :1.300
## Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
## 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
## Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
## Species
## setosa :50
## versicolor:50
## virginica :50
##
##
##
Zwróćmy uwagę, że podsumowanie dla danych numerycznych (kolumny 1:4) i danych kategoryzujących (kolumna 5) wygląda inaczej. Dla danych numerycznych uzyskujemy:
Dla danych kategoryzujących otrzymujemy liczebności poszczególnych kategorii (grup).
Możemy otrzymać dość dokładny obraz dystrybucji wartości w badanej próbie wykonując histogram, czyli liczbę obserwacji przypadających na dany przedział (“bins”):
hist(x)
Dla danych zamieszczonych w tabeli data.txt wykonać analizę opisową (wyznaczyć średnią, odchylenie standardowe, rozstęp, medianę, decyle, współczynnik zmienności, histogram). Wskazówka: Dane w tabeli data.txt zapisane są w 5 kolumnach, ale reprezentują jeden zbiór danych. Przed przystąpieniem do analiz należy połączyć dane z wszystkich w jeden zbiór (wektor) danych.