-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwarsztat_2016.10.17.Rmd
327 lines (250 loc) · 12 KB
/
warsztat_2016.10.17.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
---
title: "Statystyka I z R<br/>Warsztat 3. Struktury danych II; rozkłady zmiennych"
author: "Tomasz Żółtak"
date: "17 października 2016"
output:
html_document:
css: ../styles.css
toc: TRUE
toc_depth: 3
---
Na dzisiejszych zajęciach zapoznamy się z używaniem macierzy. Poznamy też funkcję `table()`, przy pomocy której będziemy tworzyć rozkłady zmiennych.
# Podstawowe struktury danych w R - macierze
Macierze to dwuwymiarowe struktury danych składające się z elementów tego samego typu. Możemy wykorzystywać je m. in. do reprezentowania macierzy danych, rozkładów łączynych lub rodzin rozkładów warunkowych.
## Tworzenie macierzy
Macierz możemy utworzyć korzystając z funkcji `matrix()`, która jako pierwszy argument przyjmuje wektor wartości, którymi chcemy wypełnić macierz. Liczbę wierszy i kolumn macierzy podajemy korzystając z argumentów odpowiednio `nrow` i `ncol`.
```{r comment="", prompt=TRUE, collapse=TRUE}
x = matrix(1:16, nrow = 4)
x
str(x)
matrix(1:16, nrow = 2)
matrix(1:16, ncol = 2)
```
Zwróćmy uwagę, że macierz wypełniana jest kolejno kolumnami. Gdybyśmy z jakichś powodów chcieli wypełniać ją wierszami, możemy wykorzystać argument `byrow`.
```{r comment="", prompt=TRUE, collapse=TRUE}
matrix(letters[1:16], nrow = 2)
matrix(letters[1:16], nrow = 2, byrow = TRUE)
```
Jeśli chcemy całą macierz wypełnić tą samą wartością, wystarczy, że jako pierwszy argument podamy tą pojedynczą wartość (wektor jedoelementowy). O ile nie chcemy uzyskać macierzy 1x1, musimy oczywiście w takim przypadku podać zarówno argument `nrow` jak i `ncol`.
```{r comment="", prompt=TRUE, collapse=TRUE}
matrix(10, nrow = 2, ncol = 3)
matrix(FALSE, nrow = 5, ncol = 3)
```
## Nazwy wierszy i kolumn
Wierszom i kolumnom macierzy możemy nadać nazwy, korzystając z funkcji `rownames()` i `colnames()` (możemy też zrobić to w ramach funkcji `matrix()`, ale nie będziemy teraz o tym mówić, jako że wymagałoby to użycia struktury danych, której jeszcze nie poznaliśmy - listy). Wykorzystuje się przy tym nieco dziwaczną składnię:
```{r comment="", prompt=TRUE, collapse=TRUE}
x = matrix(1:15, nrow = 5)
x
# póki co wiersze ani kolumny macierzy 'x' nie mają żadnych nazw
rownames(x)
colnames(x)
# nadajmy im nazwy
rownames(x) = paste("w", 1:nrow(x), sep = "")
colnames(x) = paste("k", 1:ncol(x), sep = "")
# tak wygląda nasza macierz z nazwami wierszy i kolumn
x
rownames(x)
colnames(x)
```
## Wybieranie elementów macierzy
Jeśli chcemy wybrać z macierzy pewne elementy, możemy to zrobić analogicznymi metodami jak w przypadku wektorów, tyle że:
1. Indeksowanie odbywa się w dwóch wymiarach.
2. Co do zasady wybieramy *prostokątny* obszar.
Do wybierania służy nam operator `[]`, z tym że w przypadku macierzy przyjmuje on dwa argumenty, oddzielone przecinkiem: `[wektor_wskazujący_które_wybrać, wektor_wskazujący_które_kolumny_wybrać]`.
```{r comment="", prompt=TRUE, collapse=TRUE}
x = matrix(1:30, nrow = 5)
rownames(x) = paste("w", 1:nrow(x), sep = "")
colnames(x) = paste("k", 1:ncol(x), sep = "")
x
# możemy wybrać tylko niektóre wiersze i/lub kolumny macierzy
x[2:4, 4:6]
x[-c(1, 3, 5), c(TRUE, TRUE, FALSE, TRUE, FALSE, TRUE)]
x[c(5, 1, 2, 4, 3), -5]
# możemy też oczywiście chcieć wybrać konkretny element
x[1, 4]
```
Jeśli chcemy wybrać całe rzędy lub całe kolumny, możemy po prostu nie podawać nic jako odpowiedni argumentu operatora `[]`:
```{r comment="", prompt=TRUE, collapse=TRUE}
# całe rzędy
x[2:4, ]
x[(x[, 6] %% 2) == 0, ]
# całe kolumny
x[, 5:4]
x[, x[1, ] > 11]
```
### Specjalne funkcje dla macierzy kwadratowych
W przypadku macierzy kwadratowych (mających taką samą liczbę wierszy i kolumn) mamy dostępnych kilka funkcji, które pozwalają nam uzyskać łatwy dostęp do pewnych ich fragmentów. Ponieważ fregmenty te nie mają *prostokątnego* kształtu, w efekcie otrzymamy wektory wartości.
1. Elementy leżące na przekątnej możemy uzyskać korzystając z funkcji `diag()`.
2. Elementy poniżej lub powyżej przekątnej - korzystając z funkcji `lower.tri()` i `upper.tri()`.
```{r comment="", prompt=TRUE, collapse=TRUE}
y = matrix(1:16, nrow = 4)
y
diag(y)
y[lower.tri(y)]
y[upper.tri(y)]
```
Póki co funkcje te nie będą mieć dla nas znaczenia.
## Zmiana wartości elementów macierzy
Wartości macierzy możemy zmieniać, wskazując, o które elementy nam chodzi i podając wartości, które mają im zostać przypisane.
```{r comment="", prompt=TRUE, collapse=TRUE}
x
x[1, 1] = 100
x
x[, 2] = 101:105
x
x[2:3, 3:5] = -1:-6
x
```
## Operacje na macierzach
### Proste operacje arytmetyczne
Podobnie jak w przypadku wektorów, wykonanie operacji w rodzaju dodania/odjęcia/pomnożenia/podzielenia przez stałą wykonywane jest w odniesieniu do wszystkich elementów macierzy.
```{r comment="", prompt=TRUE, collapse=TRUE}
y = matrix(1, nrow = 3, ncol = 4)
y
y - 1
(2 * y)^2
```
Również analogicznie do wektorów, jeśli dokonamy tego typu operacji na dwóch macierzach o równej sobie liczbie wierszy i równej sobie liczbie kolumn, operacja zostanie wykonana parami na odpowiadających sobie elementach macierzy.
```{r comment="", prompt=TRUE, collapse=TRUE}
x = matrix(1, nrow = 3, ncol = 4)
y = matrix(rep(0:11, 4), nrow = 3, ncol = 4)
x
y
x + y
```
### Najbardziej typowe operacje na całych wierszach i/lub kolumnach
Dwie najbardziej typowe operacje, które wykonuje się na całych wierszach i/lub kolumnach macierzy to obliczenie sumy lub średniej elementów wiersza/kolumny. Pozwalają na to funkcje `rowSums()`, `colSums()`, `rowMeans()` i `colMeans()`.
```{r comment="", prompt=TRUE, collapse=TRUE}
x = matrix(rep(1:5, 6), nrow = 5)
x
rowSums(x)
rowMeans(x)
colSums(x)
colMeans(x)
```
### Łączenie ze sobą macierzy oraz macierzy i wektorów
Macierze mające taką samą liczbę kolumn możemy połączyć *dostawiając drugą poniżej pierwszej* przy pomocy funkcji `rbind()`. Macierze o takiej samej liczbie wierszy możemy z kolei połączyć *dostawiając drugą po prawej stronie pierwszej* przy pomocy funkcji `cbind()`. Drugim argumentem tych funkcji może też być wektor, o liczbie elementów równej odpowiednio liczbie kolumn lub liczbie wierszy macierzy będącej pierwszym argumentem.
```{r comment="", prompt=TRUE, collapse=TRUE}
x = matrix(0, nrow = 2, ncol = 3)
y = matrix(1, nrow = 3, ncol = 3)
z = matrix(2, nrow = 2, ncol = 2)
x
y
z
rbind(x, y)
cbind(x, z)
rbind(y, colSums(y))
cbind(z, rowSums(z))
```
### Operacje macierzowe
R posiada też oczywiście zestaw funkcji pozwalających nam wykonać podstawowe operacje algebry macierzy:
* transpozycję - funkcja `t()`,
* mnożenie mcierzowe - operator `%*%`,
* obliczanie odwrotności - funkcja `solve()`.
Podczas tego kursu raczej nie będziemy ich jednak wykorzystywać.
# Rozkłady
Zacznijmy od wczytania danych, na których będziemy dalej pracować. Funkcja `load()` pozwala wczytać obiekty R zapisane w natywnym formacie R-a, czyli .RData (linijka wcześniej służy upewnieniu się, że bęziemy próbowali wczytać dane z odpowiedniego folderu). Funkcja `load()` zwraca nazwy wczytanych obiektów - w tym przypadku jest to 11 wektorów. Wektor o nazwie *etykiety* opisuje znaczenie pozostałych wektorów, które zawierają dane - zmienne z badania Polski Generalny Sondaż Społeczny (uwzględniono tylko wybrane edycje i tylko respondentów pomiędzy 20 a 29 rokiem życia).
```{r comment="", prompt=TRUE, collapse=TRUE}
try(setwd("warsztat 2016.10.17"), silent = TRUE)
nazwyObiektow = load("dane_2016.10.17.RData")
nazwyObiektow
etykiety
summary(cbind(Y, X, Z, W, V1, V2, V3, V4, V5, V6, V7))
```
## Funkcja table()
### Rozkład brzegowy liczebności
Aby uzyskać **rozkład liczebności**, najprościej posłużyć się funkcją `table()`. Możemy wywołać ją z jednym argumentem, uzyskując rozkład brzegowy danej zmiennej.
```{r comment="", prompt=TRUE, collapse=TRUE}
# rozkład wielkości miejscowości zamieszkania w analizowanej zbiorowości
nX = table(X)
nX
str(nX)
```
Zwrócony obiekt jest typu *table*, ale w pratyce możemy postępować z nim analogicznie jak z wektorem, którego elementom zostały przypisane nazwy.
```{r comment="", prompt=TRUE, collapse=TRUE}
nX
names(nX)
nX[2:4]
nX[names(nX) == "2 M do 25 tys"]
nX * 2
```
Aby obejrzeć rozkład w formie, do jakiej jesteśmy nieco bardziej przyzwyczajeni, możemy użyć funkcji `as.matrix()`.
```{r comment="", prompt=TRUE, collapse=TRUE}
mNX = as.matrix(nX)
colnames(mNX) = "N(X = X_i)"
mNX
```
W stosunku do tego, jak przywykliśmy opisywać rozkłady w tabelach brakuje jeszcze jednego elementu - sumy wszystkich obserwacji. Możemy ją dodać na dwa sposoby - *ręcznie*, lub przy pomocy funkcji `addmargins()`.
```{r comment="", prompt=TRUE, collapse=TRUE}
# "ręcznie"
c(nX, "suma" = sum(nX))
## analogicznie do rozkładu w formie macierzy
rbind(mNX, "suma" = sum(mNX))
# przy pomocy funkcji addmargins()
addmargins(nX)
## w przypadku macierzy musimy podać dodatkowy argument, wskazujący, w którą
## stronę ma zostać dokonane zliczanie (1 - w pionie, 2 - w poziomie)
addmargins(mNX, 1)
```
### Rozkład brzegowy częstości
Aby uzyskać **rozkład częstości**, musimy podzielić liczebności w poszczególnych komórkach przez liczbę wszystkich obserwacji. Podobnie jak w przypadku dodawania komórki z sumą wszystkich obserwacji, możemy to zrobić *ręcznie*, lub korzystając z gotowej funkcji - w tym przypadku `prop.table()` (uwaga - jej argumentem jest wynik działania funkcji `table()`, a nie surowe dane).
```{r comment="", prompt=TRUE, collapse=TRUE}
# "ręcznie"
nX
pX = nX / sum(nX)
pX
# przy pomocy funkcji prop.table()
pX = prop.table(nX)
pX
# dalej możemy nadać rozkładowi nieco ładniejszy wygląd
mPX = as.matrix(c(pX, "suma" = sum(pX)))
colnames(mPX) = "P(X = x_i)"
mPX
```
Uwaga, **jeśli w obiekcie mamy rozkład z dopisanym elementem *sumy*,** musimy oczywiście dzielić przez wartość tego elementu (względnie wartość wszystkich komórek rozkładu poza tą opisującą sumę).
```{r comment="", prompt=TRUE, collapse=TRUE}
nXS = c(nX, "suma" = sum(nX))
nXS
# "ręcznie" (w tym przypadku to nawet prościej!)
pXS = nXS / nXS[length(nXS)]
pXS
# przy pomocy funkcji prop.table()
pXS = prop.table(nXS[-length(nXS)])
pXS = c(pXS, "suma" = sum(pXS))
pXS
# !!! źle !!!
nXS / sum(nXS) # !!! źle !!!
prop.table(nXS) # !!! źle !!!
# !!! źle !!!
```
### Skumulowane rozkłady brzegowe
Aby obliczyć **skumulowany rozkład brzegowy liczebności**, najprościej posłużyć się funkcją `cumsum()`. Przyjmuje ona jako argument wektor i zwraca wektor tej samej długości, którego kolejne elementy przyjmują wartości równe sumie wartości elementów wektora wejściowego, od pierwszego do danego.
```{r comment="", prompt=TRUE, collapse=TRUE}
rbind("x" = 0:6, "cumsum(x)" = cumsum(0:6))
```
---
#### Zadanie
Dysponując brzegowym rozkładem liczebności zmiennej *X*, zapisanym w obiekcie `nX` oblicz **skumulowany rozkład liczebności** zmiennej *X* i przypisz go do obiektu `sNX`, a następnie **skumulowany rozkład częstości** tej samej zmiennej i przypisz go do obiektu `sPX`.
```{r comment="", prompt=TRUE, collapse=TRUE}
nX = table(X)
nX
# to jest miejsce na Twój kod
sNX = cumsum(nX)
sNX
pNX = cumsum(pX)
pNX
pNX = sNX / sNX[length(sNX)]
pNX
```
---
# Na następne zajęcia
Jeśli interesuje Cię zrozumienie, co robimy na początku każdych zajęć, aby pobrać pliki, których będziemy używać, zapoznaj się z opisem zawartym [w pliku README.md w katalogu projektu na GitHubie](https://github.com/tzoltak/3501-KOG-S1R_2016_gr3).
## Praca domowa
Informacja zostanie rozesłana mailem.
## Do przeczytania na następne zajęcia
G. Lissowski, J. Haman i M. Jasiński. (2011). Podstawy statystyki dla socjologów. Wyd. II poprawione. Warszawa: Wydawnictwo Naukowe SCHOLAR. Rozdział 2.
Względnie inne źródła, w których opisane zostało co to jest:
* łączny rozkład statystyczny liczebności dwóch zmiennych,
* łączny rozkład statystyczny częstości dwóch zmiennych,
* rodzina rozkładów warunkowych liczebności,
* rodzina rozkładów warunkowych częstości.