diff --git a/warsztat 2016.10.10/warsztat_2016.10.10.Rmd b/warsztat 2016.10.10/warsztat_2016.10.10.Rmd index 071d625..7780391 100644 --- a/warsztat 2016.10.10/warsztat_2016.10.10.Rmd +++ b/warsztat 2016.10.10/warsztat_2016.10.10.Rmd @@ -263,244 +263,6 @@ setdiff(x, y) setdiff(y, x) ``` -# Pętla for() - -Pętla `for` w R działa zupełnie inaczej, niż w języku C (i pochodnych) oraz językach o podobnej do C składni (np. Javie)! Działa jednak bardzo podobnie do tego, jak w Pythonie. W wywołaniu pętli wskazujemy nazwę zmiennej, której kolejno (w kolejnych obiegach pętli) nadawane będą wartości kolejnych elementów zadanego wektora. Pętla zostanie (co do zasady) wykonana zostanie więc tyle razy, ile elementów ma podany wektor. Przykładowo: - -```{r comment="", prompt=TRUE, collapse=TRUE} -for (i in 1:5) { - print(i) -} -``` - -W każdym obiegu pętli zmienna `i` była jednoelementowym wektorem - kolejnymi wartościami z sekwencji `1:5`. Aby wyświetlić na konsoli jej wartości musieliśmy w tym przypadku użyć funkcji `print()` - pętla sama z siebie nie zwraca nic na konsolę. - -W ramach pętli możemy też oczywiście wykorzystać inne zmiene, zdefiniowane poza pętlą. Poniższy kod oblicza sumę wartości wektora `x` (dla weryfikacji poprawności porównamy efekt działania pętli z wartością zwracaną przez funkcję `sum()`). - -```{r comment="", prompt=TRUE, collapse=TRUE} -x = 10:20 -xSuma = 0 -for (i in x) { - xSuma = xSuma + i -} -xSuma -sum(x) -``` - ---- - -# Funkcje - -Jeśli jakiś fragment kodu będziemy chcieli wykonywać wielokrotnie, użyteczne jest *opakowanie* go w funkcję. Pozwoli to zaoszczędzić nam wiele pisania (albo kopiowania), uczyni nasz kod bez porównania bardziej przejrzystym i mniej podatnym na błędy. Podzas tego kursu będziemy zajmować się pisaniem jedynie bardzo prostych funkcji, nie martwiąc się ani ich dokumentowaniem, ani czynieniem ich odpornymi na potencjalne próby niewłaściwego użycia. - -Aby zdefiniować w R funkcję używa się składni: - -```{r eval = FALSE, comment="", prompt=TRUE, collapse=TRUE} -nazwa_funkcji = function (argument1, argument2) { - tu_jakiś_kod_który_robi_to_co_trzeba - - return(zwracanyObiekt) -} -``` - -Jeśli wykonamy w konsoli kod zawierający taką definicję funkcji, będziemy mogli jej potem używać w dalszej części naszego kodu. - -Przykłady bardzo prostych funkcji: - -```{r comment="", prompt=TRUE, collapse=TRUE} -# funkcja, która zwraca dokładnie to, co podano jej jako argument -ToSamo = function(x) { - return(x) -} -ToSamo(1:5) - -# "opakujmy" w funkcję naszą pętlę obliczającą sumę elementów wektora -SumujElementy = function(x) { - xSuma = 0 - for (i in x) { - xSuma = xSuma + i - } - return(xSuma) -} -SumujElementy(1:20) -sum(1:20) -``` - ---- - -#### Konwencja nazewnicza: - -Pisząc kod dobrze jest stosować konwencje nazewnicze, czyli reguły nadawania obiektom nazw w zależności od ich rodzaju i przeznaczenia (np. [Google's R Style Guide](https://google.github.io/styleguide/Rguide.xml)). W szczególności dobrze jest móc łatwo stwierdzić na podstawie nazwy obiektu, czy jest on zmienną (np. wektorem) czy funkcją. - -Niestety dobry zwyczaj stosowania konwencji nazewniczych jest wynalazkiem typowo informatycznym i w przeszłości raczej nie był praktykowany przez statystyków - efektem jest przerażający brak spójności w zakresie sposobu nazywania funkcji w ramach podstawowego zestawu pakietów R. Tworząc własny kod nie kultywujmy tej niechlubnej tradycji! - -**Na naszych zajęciach będziemy stosować następującą konwencję nazywania obiektów:** - - 1. Nie używamy polskich znaków. - 2. Nazwy wszystkich obiektów piszemy w konwencji *camel case*. - 3. Nazwy zmiennych zaczynamy małą literą, np. `x`, `mojaZmiena`, `innaMojaZmienna`. - 4. Nazwy funkcji zaczynamy wielką literą, np. `Funkcja`, `JakasFunkcja`, `JeszczeInnaFunkcja`. - ---- - -# Konstrukcje warunkowe - -Czasem chcemy aby w zależności od tego, jaką wartość logiczną przyjmie warunek określony w odniesieniu do pewnej zmiennej, wykonany został inny fragment kodu. Służy do tego konstrukcja `if ()`. Funkcja poniżej wykorzystuje tego typu konstrukcję, aby zwrócić orientacyjny stan jajka na podstawie liczby minut, przez które jajko było gotowane. - -```{r comment="", prompt=TRUE, collapse=TRUE} -# funkcja, która zwraca dokładnie to, co podano jej jako argument -GotujeJajko = function(liczbaMinut) { - if (liczbaMinut < 4) { - stan = "niedogotowane" - } else if (liczbaMinut < 6 ) { - stan = "na miękko" - } else if (liczbaMinut < 8.5) { - stan = "półtwarde" - } else { - stan = "na twardo" - } - return(stan) -} -GotujeJajko(7) -``` - -# Parametry rozkładu zmiennej - -Poniżej przypomnimy sobie definicje podstaowywch parametrów opisujących poziom oraz zróżnicowanie wartości zmienych statystycznych. Twoim zadaniem będzie zaimplementowanie obliczania tych parametrów w postaci funkcji. Możesz przy tym korzystać tylko z funkcji, które zostały wspomniane w tekście powyżej (w szczególności `sort()` i `length()`), pętli *for* oraz konstrukcji warunkowych *if-else*. - -## Parametry poziomu wartości - -### Minimum i maksimum - -W bloku kodu poniżej zdefiniuj funkcję "Minimum", która zwróci najmniejszą wartość przyjmowaną przez elementy wektora, przekazanego jej jako argument. Wiersze poniżej pozwalają przetestować poprawność działania Twojej funkcji, porównując wyniki, jakie zwraca dla trzech przykładowych wektorów z wynikami zaimplementowanej w R funkcji `min()`. - -```{r eval=FALSE, comment="", prompt=TRUE, collapse=TRUE} -Minimum = function(x) { - # to jest miejsce na Twój kod -} -x = c(2, 3, 2, 2, 1) -y = c(97, 3, 4, 3, 3, 1) -z = c(10, 2, 4, 2, 1, 5) -Minimum(x) == min(x) # 1 -Minimum(y) == min(y) # 1 -Minimum(z) == min(z) # 1 -``` - -W podobny sposób zdefiniuj funkcję "Maksimum". - -```{r eval=FALSE, comment="", prompt=TRUE, collapse=TRUE} -Maksimum = function(x) { - # to jest miejsce na Twój kod -} -Maksimum(x) == max(x) # 3 -Maksimum(y) == max(y) # 97 -Maksimum(z) == max(z) # 10 -``` - -### Średnia arytmetyczna - -Średnią arytmetyczną możemy obliczyć sumując wartości elementów wektora i następnie dzieląc uzyskaną sumę przez liczbę elementów. Zaimplementuj ten sposób obliczania średniej w funkcji o nazwie "Srednia". - -```{r eval=FALSE, comment="", prompt=TRUE, collapse=TRUE} -Srednia = function(x) { - # to jest miejsce na Twój kod -} -Srednia(x) == mean(x) # 2 -Srednia(y) == mean(y) # 18.5 -Srednia(z) == mean(z) # 4 -``` - -### Mediana - -Mediana to taka wartość, że co najmniej połowa analizowanych jednostek ma wartość nie wyższą od niej i jednocześnie co najmniej połowa analizowanych jednostek ma wartość nie mniejszą od niej. Okazuje się, że wartości spełniające ten dosyć skomplikowany warunek dosyć łatwo jest określić. - - - W sytuacji, gdy liczba analizowanych jednostek jest nieparzysta, jest to wartość, którą przyjmuje *środkowa* jednostka, jeśli ustawimy je w kolejności według wartości danej zmiennej. - - W sytuacji, gdy liczba analizowanych jednostek jest parzysta, medianą jest każda wartość (liczba rzeczywista) z przedziału, którego granice wyznaczają wartości tych dwóch obserwacji, które, jeśli ustawimy je w kolejności według wartości danej zmiennej, stoją *obok środka*. - - Oznacza to, że jeśli te dwie jednostki mają różne wartości analizowanej zmiennej, to wartości będących medianą jest nieskończenie wiele. W praktyce chcemy jednak zwykle wybrać jedną z nich - typowo stosowaną regułą takiego ujednoznacznienia jest zwracanie jako mediany średniej z wartości wyznaczających granice przedziału (taka reguła jest też zaimplementowana w dostęnej w R funkcji `median()`). - -W bloku kodu poniżej zdefiniuj funkcję "Mediana" zwracającą wartość mediany zadanego wektora, wykorzystując opisane powyżej reguły (w tym sposób ustalenia jednej wartości, która zostanie zwrócona w sytuacji, gdy medianą rozkładu jest wiele wartości) i strukturę warunkową `if() {} else {}`. - -```{r eval=FALSE, comment="", prompt=TRUE, collapse=TRUE} -Mediana = function(x) { - # to jest miejsce na Twój kod -} -Mediana(x) == median(x) # 2 -Mediana(y) == median(y) # 3 -Mediana(z) == median(z) # 3 -``` - -## Parametry rozproszenia - -### Rozstęp - -Rozstęp to różnica pomiędzy maksimum a minimum. W bloku kodu poniżej zdefiniuj funkcję "Rozstęp", która wykorzystując napisane przez Ciebie wcześniej funkcje `Maksimum()` i `Minimum()` obliczy i zwróci wartość rozstępu dla wektora przekazanego jej jako argument. - -```{r eval=FALSE, comment="", prompt=TRUE, collapse=TRUE} -Rozstep = function(x) { - # to jest miejsce na Twój kod -} -Rozstep(x) == 2 -Rozstep(y) == 96 -Rozstep(z) == 9 -``` - -### Wariancja i odchylenie standardowe - -Wariancja i odchylenie standardowe to najczęściej wykorzystywane parametry opisujące zróżnicowanir wartości zmiennych mierzonych na skalach przedziałowych (lub mocniejszych). Odgrywają też centralną rolę w wielu technikach analizy zależności pomiędzy zmiennymi (analiza wariancji, korelacja liniowa, regresja). Wariancję obliczamy jako średnią kwadratów różnic pomiędzy wartością zmiennej dla danej jednostki obserwacji a średnią danego rozkładu. - -Odchylenie standardowe to pierwiastek kwadratowy z wariancji. Posługiwanie się nim jest o tyle użyteczne, że jest ono wyrażone w tej samej jednostce, co mierzona zmienna (wariancja jest mianowana w jednostce mierzonej zmiennej podniesinej do kwadratu). - -Wykorzystując zdefiniowaną wcześniej przez siebie funkcje `Srednia()` zaimplementuj poniżej funkcję "Wariancja" zwracającą wartość wariancji dla wektora podanego jako jej argument. Następnie, wykorzystując ją zdefiniuj też funkcję "OdchylenieStandardowe". - -Uwaga! Typowo dostępne w programach (i ogólniej bibliotekach) statystycznych funkcje służące obliczaniu wariancji zwracają nie opisany powyżej parametr opisowy, ale nieobciążony estymator wariancji populacyjnej obliczany przy założeniu, że zadane przez nas wartości są prostą próbą losową! Tak też zachowują się dostępne w R funkcje `var()` i `sd()`. Stąd aby wykorzystać je do weryfikacji poprawności działania naszej funkcji, musimy wcześniej przekształcić zwracane przez nie wyniki. - -```{r eval=FALSE, comment="", prompt=TRUE, collapse=TRUE} -Wariancja = function(x) { - # to jest miejsce na Twój kod -} -Wariancja(x) == (var(x) * (length(x) - 1) / length(x)) # 0.4 -Wariancja(y) == (var(y) * (length(y) - 1) / length(y)) # 1233.25 -Wariancja(z) == (var(z) * (length(z) - 1) / length(z)) # 9 - -OdchylenieStandardowe = function(x) { - # to jest miejsce na Twój kod -} -``` - -### Współczynnik zmienności - -W przypadku niektórych zmiennych (dokładnie: tych mierzonych na skalach ilorazowych) bardziej użyteczną praktycznie miarą zróżnicowania jest współczynnik zmienności, którego wartość otzrymujemy dzieląc odchylenia standardowe przez średnią danego rozkładu. W efekcie uzyskujemy współczynnik niemianowany (bez jednostki), którego wartości można porównywać nawet pomiędzy zmiennymi mierzonymi w różnych jednostkach. Jednakże aby obliczanie współczynnika zmienności miało sens, mierzona zmienna musi być mierzona na skali olorazowej i nie może przyjmować wartości ujemnych. - -Zaimplementuj poniżej funkcję "WspolczynnikZmiennosci" zwracającą wartość współczynnika zmieności dla wektora podanego jako jej argument. Wykorzystaj zdefiniowane wcześniej przez siebie funkcje `Srednia()` i `OdchylenieStandardowe()`. - -```{r eval=FALSE, comment="", prompt=TRUE, collapse=TRUE} -WspolczynnikZmiennosci = function(x) { - # to jest miejsce na Twój kod -} -round(WspolczynnikZmiennosci(x), 6) == 0.353553 -round(WspolczynnikZmiennosci(y), 6) == 2.079431 -round(WspolczynnikZmiennosci(z), 6) == 0.821584 -``` - -### Odchylenia przeciętne (od mediany) - -Odchylenie przeciętne (od mediany) obliczane jest jako średnia modułów różnic pomiędzy wartością zmiennej dla danej jednostki obserwacji a medianą. Zaimplementuj poniżej funkcję "OdchyleniePrzecietne" zwracającą wartość odchylenia przeciętnego dla wektora podanego jako jej argument. Wykorzystaj zdefiniowaną wcześniej przez siebie funkcję `Srednia()`. - -```{r eval=FALSE, comment="", prompt=TRUE, collapse=TRUE} -OdchyleniePrzecietne = function(x) { - # to jest miejsce na Twój kod -} -OdchyleniePrzecietne(x) == 0.4 -OdchyleniePrzecietne(y) == (16 + 1/6) -OdchyleniePrzecietne(z) == (2 + 1/3) -``` - -# Na następne zajęcia - -## Praca domowa - -Jeśli w czasie zajęć nie udało Ci się zaimplementować wpostaci funkcji wszystkich opisanych wyżej parametrów, dokończ to w domu. **Plik *.Rmd zawierający skończone ćwiczenie prześlij na adres zoltakt@is.uw.edu.pl** (zrób to również, jeśli udało Ci się skończyć w trakcie zajęć). - ## 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.](http://libra.ibuk.pl/book/145985) - Rozdział 2. (w serwisie IBUK Libra dostępna za pośrednictwem konta czytelnika BUW). diff --git a/warsztat 2016.10.10/warsztat_2016.10.10.html b/warsztat 2016.10.10/warsztat_2016.10.10.html index 3bee291..415ba87 100644 --- a/warsztat 2016.10.10/warsztat_2016.10.10.html +++ b/warsztat 2016.10.10/warsztat_2016.10.10.html @@ -133,25 +133,6 @@

10 października 2016

  • Porównywanie wartości wektorów
  • Wybieranie elementów wektora
  • Wektory jako zbiory wartości
  • - -
  • Pętla for()
  • -
  • Funkcje
  • -
  • Konstrukcje warunkowe
  • -
  • Parametry rozkładu zmiennej
  • -
  • Na następne zajęcia
  • @@ -383,207 +364,6 @@

    Wektory jako zbiory wartości

    > setdiff(y, x) [1] 11 12 13 14 15 - -
    -

    Pętla for()

    -

    Pętla for w R działa zupełnie inaczej, niż w języku C (i pochodnych) oraz językach o podobnej do C składni (np. Javie)! Działa jednak bardzo podobnie do tego, jak w Pythonie. W wywołaniu pętli wskazujemy nazwę zmiennej, której kolejno (w kolejnych obiegach pętli) nadawane będą wartości kolejnych elementów zadanego wektora. Pętla zostanie (co do zasady) wykonana zostanie więc tyle razy, ile elementów ma podany wektor. Przykładowo:

    -
    > for (i in 1:5) {
    -+   print(i)
    -+ }
    -[1] 1
    -[1] 2
    -[1] 3
    -[1] 4
    -[1] 5
    -

    W każdym obiegu pętli zmienna i była jednoelementowym wektorem - kolejnymi wartościami z sekwencji 1:5. Aby wyświetlić na konsoli jej wartości musieliśmy w tym przypadku użyć funkcji print() - pętla sama z siebie nie zwraca nic na konsolę.

    -

    W ramach pętli możemy też oczywiście wykorzystać inne zmiene, zdefiniowane poza pętlą. Poniższy kod oblicza sumę wartości wektora x (dla weryfikacji poprawności porównamy efekt działania pętli z wartością zwracaną przez funkcję sum()).

    -
    > x = 10:20
    -> xSuma = 0
    -> for (i in x) {
    -+   xSuma = xSuma + i
    -+ }
    -> xSuma
    -[1] 165
    -> sum(x)
    -[1] 165
    -
    -
    -
    -

    Funkcje

    -

    Jeśli jakiś fragment kodu będziemy chcieli wykonywać wielokrotnie, użyteczne jest opakowanie go w funkcję. Pozwoli to zaoszczędzić nam wiele pisania (albo kopiowania), uczyni nasz kod bez porównania bardziej przejrzystym i mniej podatnym na błędy. Podzas tego kursu będziemy zajmować się pisaniem jedynie bardzo prostych funkcji, nie martwiąc się ani ich dokumentowaniem, ani czynieniem ich odpornymi na potencjalne próby niewłaściwego użycia.

    -

    Aby zdefiniować w R funkcję używa się składni:

    -
    > nazwa_funkcji = function (argument1, argument2) {
    -+   tu_jakiś_kod_który_robi_to_co_trzeba
    -+   
    -+   return(zwracanyObiekt)
    -+ }
    -

    Jeśli wykonamy w konsoli kod zawierający taką definicję funkcji, będziemy mogli jej potem używać w dalszej części naszego kodu.

    -

    Przykłady bardzo prostych funkcji:

    -
    > # funkcja, która zwraca dokładnie to, co podano jej jako argument
    -> ToSamo = function(x) {
    -+   return(x)
    -+ }
    -> ToSamo(1:5)
    -[1] 1 2 3 4 5
    -> 
    -> # "opakujmy" w funkcję naszą pętlę obliczającą sumę elementów wektora
    -> SumujElementy = function(x) {
    -+   xSuma = 0
    -+   for (i in x) {
    -+     xSuma = xSuma + i
    -+   }
    -+   return(xSuma)
    -+ }
    -> SumujElementy(1:20)
    -[1] 210
    -> sum(1:20)
    -[1] 210
    -
    -
    -

    Konwencja nazewnicza:

    -

    Pisząc kod dobrze jest stosować konwencje nazewnicze, czyli reguły nadawania obiektom nazw w zależności od ich rodzaju i przeznaczenia (np. Google’s R Style Guide). W szczególności dobrze jest móc łatwo stwierdzić na podstawie nazwy obiektu, czy jest on zmienną (np. wektorem) czy funkcją.

    -

    Niestety dobry zwyczaj stosowania konwencji nazewniczych jest wynalazkiem typowo informatycznym i w przeszłości raczej nie był praktykowany przez statystyków - efektem jest przerażający brak spójności w zakresie sposobu nazywania funkcji w ramach podstawowego zestawu pakietów R. Tworząc własny kod nie kultywujmy tej niechlubnej tradycji!

    -

    Na naszych zajęciach będziemy stosować następującą konwencję nazywania obiektów:

    -
      -
    1. Nie używamy polskich znaków.
    2. -
    3. Nazwy wszystkich obiektów piszemy w konwencji camel case.
    4. -
    5. Nazwy zmiennych zaczynamy małą literą, np. x, mojaZmiena, innaMojaZmienna.
    6. -
    7. Nazwy funkcji zaczynamy wielką literą, np. Funkcja, JakasFunkcja, JeszczeInnaFunkcja.
    8. -
    -
    -
    -
    -
    -

    Konstrukcje warunkowe

    -

    Czasem chcemy aby w zależności od tego, jaką wartość logiczną przyjmie warunek określony w odniesieniu do pewnej zmiennej, wykonany został inny fragment kodu. Służy do tego konstrukcja if (). Funkcja poniżej wykorzystuje tego typu konstrukcję, aby zwrócić orientacyjny stan jajka na podstawie liczby minut, przez które jajko było gotowane.

    -
    > # funkcja, która zwraca dokładnie to, co podano jej jako argument
    -> GotujeJajko = function(liczbaMinut) {
    -+   if (liczbaMinut < 4) {
    -+     stan = "niedogotowane"
    -+   } else if (liczbaMinut < 6 ) {
    -+     stan = "na miękko"
    -+   } else if (liczbaMinut < 8.5) {
    -+     stan = "półtwarde"
    -+   } else {
    -+     stan = "na twardo"
    -+   }
    -+   return(stan)
    -+ }
    -> GotujeJajko(7)
    -[1] "półtwarde"
    -
    -
    -

    Parametry rozkładu zmiennej

    -

    Poniżej przypomnimy sobie definicje podstaowywch parametrów opisujących poziom oraz zróżnicowanie wartości zmienych statystycznych. Twoim zadaniem będzie zaimplementowanie obliczania tych parametrów w postaci funkcji. Możesz przy tym korzystać tylko z funkcji, które zostały wspomniane w tekście powyżej (w szczególności sort() i length()), pętli for oraz konstrukcji warunkowych if-else.

    -
    -

    Parametry poziomu wartości

    -
    -

    Minimum i maksimum

    -

    W bloku kodu poniżej zdefiniuj funkcję “Minimum”, która zwróci najmniejszą wartość przyjmowaną przez elementy wektora, przekazanego jej jako argument. Wiersze poniżej pozwalają przetestować poprawność działania Twojej funkcji, porównując wyniki, jakie zwraca dla trzech przykładowych wektorów z wynikami zaimplementowanej w R funkcji min().

    -
    > Minimum = function(x) {
    -+   # to jest miejsce na Twój kod
    -+ }
    -> x = c(2, 3, 2, 2, 1)
    -> y = c(97, 3, 4, 3, 3, 1)
    -> z = c(10, 2, 4, 2, 1, 5)
    -> Minimum(x) == min(x)  # 1
    -> Minimum(y) == min(y)  # 1
    -> Minimum(z) == min(z)  # 1
    -

    W podobny sposób zdefiniuj funkcję “Maksimum”.

    -
    > Maksimum = function(x) {
    -+   # to jest miejsce na Twój kod
    -+ }
    -> Maksimum(x) == max(x)  #  3
    -> Maksimum(y) == max(y)  # 97
    -> Maksimum(z) == max(z)  # 10
    -
    -
    -

    Średnia arytmetyczna

    -

    Średnią arytmetyczną możemy obliczyć sumując wartości elementów wektora i następnie dzieląc uzyskaną sumę przez liczbę elementów. Zaimplementuj ten sposób obliczania średniej w funkcji o nazwie “Srednia”.

    -
    > Srednia = function(x) {
    -+   # to jest miejsce na Twój kod
    -+ }
    -> Srednia(x) == mean(x)  #  2
    -> Srednia(y) == mean(y)  # 18.5
    -> Srednia(z) == mean(z)  #  4
    -
    -
    -

    Mediana

    -

    Mediana to taka wartość, że co najmniej połowa analizowanych jednostek ma wartość nie wyższą od niej i jednocześnie co najmniej połowa analizowanych jednostek ma wartość nie mniejszą od niej. Okazuje się, że wartości spełniające ten dosyć skomplikowany warunek dosyć łatwo jest określić.

    -
      -
    • W sytuacji, gdy liczba analizowanych jednostek jest nieparzysta, jest to wartość, którą przyjmuje środkowa jednostka, jeśli ustawimy je w kolejności według wartości danej zmiennej.
    • -
    • W sytuacji, gdy liczba analizowanych jednostek jest parzysta, medianą jest każda wartość (liczba rzeczywista) z przedziału, którego granice wyznaczają wartości tych dwóch obserwacji, które, jeśli ustawimy je w kolejności według wartości danej zmiennej, stoją obok środka. -
        -
      • Oznacza to, że jeśli te dwie jednostki mają różne wartości analizowanej zmiennej, to wartości będących medianą jest nieskończenie wiele. W praktyce chcemy jednak zwykle wybrać jedną z nich - typowo stosowaną regułą takiego ujednoznacznienia jest zwracanie jako mediany średniej z wartości wyznaczających granice przedziału (taka reguła jest też zaimplementowana w dostęnej w R funkcji median()).
      • -
    • -
    -

    W bloku kodu poniżej zdefiniuj funkcję “Mediana” zwracającą wartość mediany zadanego wektora, wykorzystując opisane powyżej reguły (w tym sposób ustalenia jednej wartości, która zostanie zwrócona w sytuacji, gdy medianą rozkładu jest wiele wartości) i strukturę warunkową if() {} else {}.

    -
    > Mediana = function(x) {
    -+   # to jest miejsce na Twój kod
    -+ }
    -> Mediana(x) == median(x)  # 2
    -> Mediana(y) == median(y)  # 3
    -> Mediana(z) == median(z)  # 3
    -
    -
    -
    -

    Parametry rozproszenia

    -
    -

    Rozstęp

    -

    Rozstęp to różnica pomiędzy maksimum a minimum. W bloku kodu poniżej zdefiniuj funkcję “Rozstęp”, która wykorzystując napisane przez Ciebie wcześniej funkcje Maksimum() i Minimum() obliczy i zwróci wartość rozstępu dla wektora przekazanego jej jako argument.

    -
    > Rozstep = function(x) {
    -+   # to jest miejsce na Twój kod
    -+ }
    -> Rozstep(x) ==  2
    -> Rozstep(y) == 96
    -> Rozstep(z) ==  9
    -
    -
    -

    Wariancja i odchylenie standardowe

    -

    Wariancja i odchylenie standardowe to najczęściej wykorzystywane parametry opisujące zróżnicowanir wartości zmiennych mierzonych na skalach przedziałowych (lub mocniejszych). Odgrywają też centralną rolę w wielu technikach analizy zależności pomiędzy zmiennymi (analiza wariancji, korelacja liniowa, regresja). Wariancję obliczamy jako średnią kwadratów różnic pomiędzy wartością zmiennej dla danej jednostki obserwacji a średnią danego rozkładu.

    -

    Odchylenie standardowe to pierwiastek kwadratowy z wariancji. Posługiwanie się nim jest o tyle użyteczne, że jest ono wyrażone w tej samej jednostce, co mierzona zmienna (wariancja jest mianowana w jednostce mierzonej zmiennej podniesinej do kwadratu).

    -

    Wykorzystując zdefiniowaną wcześniej przez siebie funkcje Srednia() zaimplementuj poniżej funkcję “Wariancja” zwracającą wartość wariancji dla wektora podanego jako jej argument. Następnie, wykorzystując ją zdefiniuj też funkcję “OdchylenieStandardowe”.

    -

    Uwaga! Typowo dostępne w programach (i ogólniej bibliotekach) statystycznych funkcje służące obliczaniu wariancji zwracają nie opisany powyżej parametr opisowy, ale nieobciążony estymator wariancji populacyjnej obliczany przy założeniu, że zadane przez nas wartości są prostą próbą losową! Tak też zachowują się dostępne w R funkcje var() i sd(). Stąd aby wykorzystać je do weryfikacji poprawności działania naszej funkcji, musimy wcześniej przekształcić zwracane przez nie wyniki.

    -
    > Wariancja = function(x) {
    -+   # to jest miejsce na Twój kod
    -+ }
    -> Wariancja(x) == (var(x) * (length(x) - 1) / length(x))  #    0.4
    -> Wariancja(y) == (var(y) * (length(y) - 1) / length(y))  # 1233.25
    -> Wariancja(z) == (var(z) * (length(z) - 1) / length(z))  #    9
    -> 
    -> OdchylenieStandardowe = function(x) {
    -+   # to jest miejsce na Twój kod
    -+ }
    -
    -
    -

    Współczynnik zmienności

    -

    W przypadku niektórych zmiennych (dokładnie: tych mierzonych na skalach ilorazowych) bardziej użyteczną praktycznie miarą zróżnicowania jest współczynnik zmienności, którego wartość otzrymujemy dzieląc odchylenia standardowe przez średnią danego rozkładu. W efekcie uzyskujemy współczynnik niemianowany (bez jednostki), którego wartości można porównywać nawet pomiędzy zmiennymi mierzonymi w różnych jednostkach. Jednakże aby obliczanie współczynnika zmienności miało sens, mierzona zmienna musi być mierzona na skali olorazowej i nie może przyjmować wartości ujemnych.

    -

    Zaimplementuj poniżej funkcję “WspolczynnikZmiennosci” zwracającą wartość współczynnika zmieności dla wektora podanego jako jej argument. Wykorzystaj zdefiniowane wcześniej przez siebie funkcje Srednia() i OdchylenieStandardowe().

    -
    > WspolczynnikZmiennosci = function(x) {
    -+   # to jest miejsce na Twój kod
    -+ }
    -> round(WspolczynnikZmiennosci(x), 6) == 0.353553
    -> round(WspolczynnikZmiennosci(y), 6) == 2.079431
    -> round(WspolczynnikZmiennosci(z), 6) == 0.821584
    -
    -
    -

    Odchylenia przeciętne (od mediany)

    -

    Odchylenie przeciętne (od mediany) obliczane jest jako średnia modułów różnic pomiędzy wartością zmiennej dla danej jednostki obserwacji a medianą. Zaimplementuj poniżej funkcję “OdchyleniePrzecietne” zwracającą wartość odchylenia przeciętnego dla wektora podanego jako jej argument. Wykorzystaj zdefiniowaną wcześniej przez siebie funkcję Srednia().

    -
    > OdchyleniePrzecietne = function(x) {
    -+   # to jest miejsce na Twój kod
    -+ }
    -> OdchyleniePrzecietne(x) == 0.4
    -> OdchyleniePrzecietne(y) == (16 + 1/6)
    -> OdchyleniePrzecietne(z) == (2 + 1/3)
    -
    -
    -
    -
    -

    Na następne zajęcia

    -
    -

    Praca domowa

    -

    Jeśli w czasie zajęć nie udało Ci się zaimplementować wpostaci funkcji wszystkich opisanych wyżej parametrów, dokończ to w domu. **Plik .Rmd zawierający skończone ćwiczenie prześlij na adres zoltakt@is.uw.edu.pl* (zrób to również, jeśli udało Ci się skończyć w trakcie zajęć).

    -

    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. (w serwisie IBUK Libra dostępna za pośrednictwem konta czytelnika BUW).

    diff --git a/warsztat 2016.10.17/dane_2016.10.17.RData b/warsztat 2016.10.17/dane_2016.10.17.RData new file mode 100644 index 0000000..13f988c Binary files /dev/null and b/warsztat 2016.10.17/dane_2016.10.17.RData differ diff --git a/warsztat 2016.10.17/warsztat_2016.10.17.Rmd b/warsztat 2016.10.17/warsztat_2016.10.17.Rmd new file mode 100644 index 0000000..1b35fde --- /dev/null +++ b/warsztat 2016.10.17/warsztat_2016.10.17.Rmd @@ -0,0 +1,487 @@ +--- +title: "Statystyka I z R
    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. Poznamy też sposób tworzenia **prostych** tabel w Rmarkdown i wizualizowania (dyskretnych) rozkładów 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 + + + + +``` + +--- + +### Rozkłady łączne dwóch zmiennych + +Funkcja `table()` pozwala też łatwo uzyskać **łączny rozkład liczebności** dwóch zmiennych - wystarczy podać jej jako drugi argument inny wektor (o tej samej liczbie elementów, co ten, który podajemy jako pierwszy argument). + +```{r comment="", prompt=TRUE, collapse=TRUE} +# łączny rozkład liczebności zadowolenia z własnego wykształcenia +# i roku przeprowadzenia badania PGSS +nV7Y = table(V7, Y) +nV7Y +``` + +Zwrócony obiekt, jak w przypadku jednowymiarowym, jest typu *table*, ale tym razem ma dwa wymiary i możemy go traktować podobnie jak macierz. + +```{r comment="", prompt=TRUE, collapse=TRUE} +str(nV7Y) +colnames(nV7Y) +rownames(nV7Y) +nV7Y[3:4, 2:3] +``` + +Do uzyskanego rozkładu możemy też dodać rozkłady brzegowe, przy pomocy poznanej już wcześniej funkcji `addmargins()`. Wywołanie jej bez podania drugiego parametru spowoduje dodanie wszystkich możliwych (tu: dwóch) rozkładów brzegowych. Możemy też zrobić to *na piechotę*, korzystając z funkcji `rowSums()`, `colSums()`, `rbind()` i `cbind()`. + +```{r comment="", prompt=TRUE, collapse=TRUE} +# przy pomocy funkcji addmargins() +addmargins(nV7Y) +# "na piechotę" +nBV7Y = rbind(nV7Y, "suma" = colSums(nV7Y)) +nBV7Y = cbind(nBV7Y, "suma" = rowSums(nBV7Y)) +nBV7Y +``` + +--- + +#### Zadanie + +Dysponując łącznym rozkładem liczebności zmiennych *V7* i *Y*, zapisanym w obiekcie `nV7Y` oblicz **łączny rozkład częstości** tych zmiennych i przypisz go do obiektu `pV7Y`. Pokaż ten rozkład w konsoli z wartościami zaokrąglonymi do trzeciego miejsca po przecinku, używając polecenia `round(pV7Y, 3)`. + +```{r comment="", prompt=TRUE, collapse=TRUE} +# to jest miejsce na Twój kod + + + + +``` + +--- + + +### Rozkłady warunkowe + +**Warunkowe rozkłady liczebności** w istocie możemy traktować po prostu jako *wycinki* z łącznego rozkładu liczebności. + +```{r comment="", prompt=TRUE, collapse=TRUE} +# warunkowy rozkład liczebności zadowolenia z własnego wykształcenia +# dla roku badania PGSS równego 1995 +nV7Y[, colnames(nV7Y) == "1995"] +# warunkowy rozkład liczebności zadowolenia z własnego wykształcenia +# dla roku badania PGSS mniejszego niż 2000 +temp = nV7Y[, as.numeric(colnames(nV7Y)) < 2000] +temp +rowSums(temp) +``` + +**Rodzina warunkowych rozkładów liczebności** jest z kolei właściwie tożsama, z łącznym rozkładem liczebności, z którego *obcięto* rozkład brzegowy jednej zmiennej. + +```{r comment="", prompt=TRUE, collapse=TRUE} +# łączny rozkład liczebności zadowolenia z własnego wykształcenia +# i roku badania PGSS +addmargins(nV7Y) +# rodzina warunkowych rozkładów liczebności zadowolenia z własnego wykształcenia +# pod warunkiem roku badania PGSS +addmargins(nV7Y)[, -(ncol(nV7Y) + 1)] +# lub równoważnie (a nawet prościej) +addmargins(nV7Y, 1) +``` + +Pojedynczy **warunkowy rozkład częstości** możemy uzyskać na podstawie odpowiedniego warunkowego rozkładu liczebności w analogiczny sposób, jak brzegowy rozkład częstości na podstawie brzegowego rozkładu liczebności. + +```{r comment="", prompt=TRUE, collapse=TRUE} +# jakiś rozkład warunkowy +nWarunkowyV7Y1995 = nV7Y[, colnames(nV7Y) == "1995"] +nWarunkowyV7Y1995 +# "ręcznie" +pWarunkowyV7Y1995 = nWarunkowyV7Y1995 / sum(nWarunkowyV7Y1995) +pWarunkowyV7Y1995 +# przy pomocy funkcji prop.table +prop.table(nWarunkowyV7Y1995) +``` + +**Pamiętamy oczywiście o tym, że w sytuacji, gdy do nasz rozkład łączny już wcześniej uzupełniliśmy o rozkłady brzegowe, musielibyśmy obliczyć to nieco inaczej!** + +**Rodzinę warunkowych rozkładów częstości** również możemy uzyskać przy pomocy funkcji `prop.table()`, podając jej drugi (opcjonalny), argument. Podobnie jak w przypadku funkcji `addmargins()` wskazuje on, *w którą stronę* ma być wykonana operacja (tu: procentowania). Żeby sprawy nie były zbyt proste, **wartości tego drugiego argumentu mają inne znaczenie w ramach funkcji `prop.table()`, niż w ramach funkcji `addmargins()`**: + + * `prop.table()`: 1 - procentuj w wierszach, 2 - procentuj w kolumnach; + * `addmargins()`: 1 - dodaj rozkład brzegowy pierwszej zmiennej (dla dwóch zmiennych: ten na dole, tzn. sumuj w kolumnach), 2 - dodaj rozkład brzegowy drugiej zmienej (dla dwóch zmiennych: ten po prawej, tzn. sumuj w wierszach). + +```{r comment="", prompt=TRUE, collapse=TRUE} +# rodzina warunkowych rozkładów częstości zadowolenia z własnego wykształcenia +# w zależności od roku badania PGSS +rWRPV7Y = addmargins(prop.table(nV7Y, 2), 1) +rWRPV7Y +round(rWRPV7Y, 3) +``` + +## Prosta wizualizacja rozkładów zmiennych (kategorialnych) - funkcja barplot() + +### Prosta wizualizacja rozkładu jednej zmiennej + +Wykres słupkowy obrazujący rozkład jednej zmiennej możemy uzyskać korzystając z funkcji `barplot`, której jako argument podajemy rozkład danej zmiennej (uwaga, bez ew. elementu z sumą). + +```{r comment="", prompt=TRUE, collapse=TRUE} +nX = table(X) +pX = prop.table(nX) +barplot(nX) +barplot(pX) +``` + +Funkcja ma też dużą liczbę dodatkowych argumentów, które pozwalają nam zarządzać jego wyglądem i uzupełnić o dodatkowe elmenty (np. tytuł, czy etykiety osi). Funkcji `grid()` możemy użyć, aby dodać linie siatki. + +```{r comment="", prompt=TRUE, collapse=TRUE} +barplot(pX, col = 3, + main = "Wielkość miejscowości zamieszkania w analizowane zbiorowości", + ylab = "czestość") +grid(col = grey(0.3), nx = NA, ny = NULL) +``` + +Czasem bardziej użyteczne byłoby pokazanie wykresu w postaci *skumulowanej* - słupków reprezentujących częstość (względnie liczebność) poszczególnych słupków *nałożonych jeden na drugim*. Możemy to łatwo uzyskać, konwertując nasz rozkład na macierz przed przekazaniem funkcji `barplot()`. + +```{r comment="", prompt=TRUE, collapse=TRUE} +barplot(as.matrix(nX)) +# nawet mając macierz możemy wrócić do poprzedniego wyglądu +barplot(as.matrix(nX), beside = TRUE) +# żeby móc coś zrozumieć, warto dodać legendę +barplot(as.matrix(pX), + main = "Wielkość miejscowości zamieszkania w analizowane zbiorowości", + legend.text = TRUE, args.legend = list(x = "right"), xlim = c(0, 1.8)) +``` + +Niestety kwestia pozycjonowania legendy nie jest tu rozwiązana w niezawodny sposób. + +### Prosta wizualizacja rozkładu dwóch zmiennych + +Opisane poniżej rozwiązania można oczywiście zastosować do różnych typów rozkładów łącznych i rodzin rozkładów warunkowych, ale **prowadząc analizy zwykle skupiamy się na porównywania ze sobą rozkładów w ramach rodziny warunkowych rozkładów częstości**. Stąd przykład odnosi się właśnie do takiej rodziny rozkładów. + +```{r comment="", prompt=TRUE, collapse=TRUE} +# rodzina warunkowych rozkładów częstości zadowolenia z własnego wykształcenia +# w zależności od roku badania PGSS +rWRPV7Y = prop.table(nV7Y, 2) +barplot(rWRPV7Y) +``` + +Bez legendy, tytułu i etykiet osi trochę trudno się zorientować, o co chodzi. + +```{r comment="", prompt=TRUE, collapse=TRUE} +barplot(rWRPV7Y, + main = "Zadowolenie z własnego wykształcenia\nw różnych rundach badania PGSS", + xlab = "rok badania PGSS", + ylab = "częstość", + legend.text = TRUE, args.legend = list(x = "right"), xlim = c(0, 10)) +``` + +Możemy też uzyskać wykres w postaci słupków zestawionych obok siebie - choć w tym przypadku jest on raczej mniej użyteczny analitycznie. + +```{r comment="", prompt=TRUE, collapse=TRUE} +barplot(rWRPV7Y, beside = TRUE, + main = "Zadowolenie z własnego wykształcenia\nw różnych rundach badania PGSS", + xlab = "rok badania PGSS", + ylab = "częstość", + legend.text = TRUE, args.legend = list(x = "topright"), ylim = c(0, 0.9)) +``` + +# Na następne zajęcia + +## Praca domowa + +Wejdź dziś wieczorem na stronę projektu na GitHubie z materiałami z tego warsztatu i zobacz, co pojawiło się w tym miejscu. + +## 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.](http://libra.ibuk.pl/book/145985) - Rozdziały: 1.1.-1.2., 3.5.-3.6., 4.1.-4.2. oraz 4.5. w zakresie, w jakim odnosi się do parametrów omówionych w 4.1. i 4.2. diff --git a/warsztat 2016.10.17/warsztat_2016.10.17.html b/warsztat 2016.10.17/warsztat_2016.10.17.html new file mode 100644 index 0000000..914c47b --- /dev/null +++ b/warsztat 2016.10.17/warsztat_2016.10.17.html @@ -0,0 +1,1019 @@ + + + + + + + + + + + + + + +Statystyka I z R Warsztat 3. Struktury danych II; rozkłady zmiennych + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + +

    Na dzisiejszych zajęciach zapoznamy się z używaniem macierzy. Poznamy też funkcję table(), przy pomocy której będziemy tworzyć rozkłady zmiennych. Poznamy też sposób tworzenia prostych tabel w Rmarkdown i wizualizowania (dyskretnych) rozkładów 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.

    +
    > x = matrix(1:16, nrow = 4)
    +> x
    +     [,1] [,2] [,3] [,4]
    +[1,]    1    5    9   13
    +[2,]    2    6   10   14
    +[3,]    3    7   11   15
    +[4,]    4    8   12   16
    +> str(x)
    + int [1:4, 1:4] 1 2 3 4 5 6 7 8 9 10 ...
    +> matrix(1:16, nrow = 2)
    +     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
    +[1,]    1    3    5    7    9   11   13   15
    +[2,]    2    4    6    8   10   12   14   16
    +> matrix(1:16, ncol = 2)
    +     [,1] [,2]
    +[1,]    1    9
    +[2,]    2   10
    +[3,]    3   11
    +[4,]    4   12
    +[5,]    5   13
    +[6,]    6   14
    +[7,]    7   15
    +[8,]    8   16
    +

    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.

    +
    > matrix(letters[1:16], nrow = 2)
    +     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
    +[1,] "a"  "c"  "e"  "g"  "i"  "k"  "m"  "o" 
    +[2,] "b"  "d"  "f"  "h"  "j"  "l"  "n"  "p" 
    +> matrix(letters[1:16], nrow = 2, byrow = TRUE)
    +     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
    +[1,] "a"  "b"  "c"  "d"  "e"  "f"  "g"  "h" 
    +[2,] "i"  "j"  "k"  "l"  "m"  "n"  "o"  "p" 
    +

    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.

    +
    > matrix(10, nrow = 2, ncol = 3)
    +     [,1] [,2] [,3]
    +[1,]   10   10   10
    +[2,]   10   10   10
    +> matrix(FALSE, nrow = 5, ncol = 3)
    +      [,1]  [,2]  [,3]
    +[1,] FALSE FALSE FALSE
    +[2,] FALSE FALSE FALSE
    +[3,] FALSE FALSE FALSE
    +[4,] FALSE FALSE FALSE
    +[5,] FALSE FALSE FALSE
    +
    +
    +

    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ę:

    +
    > x = matrix(1:15, nrow = 5)
    +> x
    +     [,1] [,2] [,3]
    +[1,]    1    6   11
    +[2,]    2    7   12
    +[3,]    3    8   13
    +[4,]    4    9   14
    +[5,]    5   10   15
    +> # póki co wiersze ani kolumny macierzy 'x' nie mają żadnych nazw
    +> rownames(x)
    +NULL
    +> colnames(x)
    +NULL
    +> # 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
    +   k1 k2 k3
    +w1  1  6 11
    +w2  2  7 12
    +w3  3  8 13
    +w4  4  9 14
    +w5  5 10 15
    +> rownames(x)
    +[1] "w1" "w2" "w3" "w4" "w5"
    +> colnames(x)
    +[1] "k1" "k2" "k3"
    +
    +
    +

    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. +
    3. Co do zasady wybieramy prostokątny obszar.
    4. +
    +

    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ć].

    +
    > x = matrix(1:30, nrow = 5)
    +> rownames(x) = paste("w", 1:nrow(x), sep = "")
    +> colnames(x) = paste("k", 1:ncol(x), sep = "")
    +> x
    +   k1 k2 k3 k4 k5 k6
    +w1  1  6 11 16 21 26
    +w2  2  7 12 17 22 27
    +w3  3  8 13 18 23 28
    +w4  4  9 14 19 24 29
    +w5  5 10 15 20 25 30
    +> # możemy wybrać tylko niektóre wiersze i/lub kolumny macierzy
    +> x[2:4, 4:6]
    +   k4 k5 k6
    +w2 17 22 27
    +w3 18 23 28
    +w4 19 24 29
    +> x[-c(1, 3, 5), c(TRUE, TRUE, FALSE, TRUE, FALSE, TRUE)]
    +   k1 k2 k4 k6
    +w2  2  7 17 27
    +w4  4  9 19 29
    +> x[c(5, 1, 2, 4, 3), -5]
    +   k1 k2 k3 k4 k6
    +w5  5 10 15 20 30
    +w1  1  6 11 16 26
    +w2  2  7 12 17 27
    +w4  4  9 14 19 29
    +w3  3  8 13 18 28
    +> # możemy też oczywiście chcieć wybrać konkretny element
    +> x[1, 4]
    +[1] 16
    +

    Jeśli chcemy wybrać całe rzędy lub całe kolumny, możemy po prostu nie podawać nic jako odpowiedni argumentu operatora []:

    +
    > # całe rzędy
    +> x[2:4, ]
    +   k1 k2 k3 k4 k5 k6
    +w2  2  7 12 17 22 27
    +w3  3  8 13 18 23 28
    +w4  4  9 14 19 24 29
    +> x[(x[, 6] %% 2) == 0, ]
    +   k1 k2 k3 k4 k5 k6
    +w1  1  6 11 16 21 26
    +w3  3  8 13 18 23 28
    +w5  5 10 15 20 25 30
    +> # całe kolumny
    +> x[, 5:4]
    +   k5 k4
    +w1 21 16
    +w2 22 17
    +w3 23 18
    +w4 24 19
    +w5 25 20
    +> x[, x[1, ] > 11]
    +   k4 k5 k6
    +w1 16 21 26
    +w2 17 22 27
    +w3 18 23 28
    +w4 19 24 29
    +w5 20 25 30
    +
    +

    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. +
    3. Elementy poniżej lub powyżej przekątnej - korzystając z funkcji lower.tri() i upper.tri().
    4. +
    +
    > y = matrix(1:16, nrow = 4)
    +> y
    +     [,1] [,2] [,3] [,4]
    +[1,]    1    5    9   13
    +[2,]    2    6   10   14
    +[3,]    3    7   11   15
    +[4,]    4    8   12   16
    +> diag(y)
    +[1]  1  6 11 16
    +> y[lower.tri(y)]
    +[1]  2  3  4  7  8 12
    +> y[upper.tri(y)]
    +[1]  5  9 10 13 14 15
    +

    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.

    +
    > x
    +   k1 k2 k3 k4 k5 k6
    +w1  1  6 11 16 21 26
    +w2  2  7 12 17 22 27
    +w3  3  8 13 18 23 28
    +w4  4  9 14 19 24 29
    +w5  5 10 15 20 25 30
    +> x[1, 1] = 100
    +> x
    +    k1 k2 k3 k4 k5 k6
    +w1 100  6 11 16 21 26
    +w2   2  7 12 17 22 27
    +w3   3  8 13 18 23 28
    +w4   4  9 14 19 24 29
    +w5   5 10 15 20 25 30
    +> x[, 2] = 101:105
    +> x
    +    k1  k2 k3 k4 k5 k6
    +w1 100 101 11 16 21 26
    +w2   2 102 12 17 22 27
    +w3   3 103 13 18 23 28
    +w4   4 104 14 19 24 29
    +w5   5 105 15 20 25 30
    +> x[2:3, 3:5] = -1:-6
    +> x
    +    k1  k2 k3 k4 k5 k6
    +w1 100 101 11 16 21 26
    +w2   2 102 -1 -3 -5 27
    +w3   3 103 -2 -4 -6 28
    +w4   4 104 14 19 24 29
    +w5   5 105 15 20 25 30
    +
    +
    +

    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.

    +
    > y = matrix(1, nrow = 3, ncol = 4)
    +> y
    +     [,1] [,2] [,3] [,4]
    +[1,]    1    1    1    1
    +[2,]    1    1    1    1
    +[3,]    1    1    1    1
    +> y - 1
    +     [,1] [,2] [,3] [,4]
    +[1,]    0    0    0    0
    +[2,]    0    0    0    0
    +[3,]    0    0    0    0
    +> (2 * y)^2
    +     [,1] [,2] [,3] [,4]
    +[1,]    4    4    4    4
    +[2,]    4    4    4    4
    +[3,]    4    4    4    4
    +

    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.

    +
    > x = matrix(1, nrow = 3, ncol = 4)
    +> y = matrix(rep(0:11, 4), nrow = 3, ncol = 4)
    +> x
    +     [,1] [,2] [,3] [,4]
    +[1,]    1    1    1    1
    +[2,]    1    1    1    1
    +[3,]    1    1    1    1
    +> y
    +     [,1] [,2] [,3] [,4]
    +[1,]    0    3    6    9
    +[2,]    1    4    7   10
    +[3,]    2    5    8   11
    +> x + y
    +     [,1] [,2] [,3] [,4]
    +[1,]    1    4    7   10
    +[2,]    2    5    8   11
    +[3,]    3    6    9   12
    +
    +
    +

    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().

    +
    > x = matrix(rep(1:5, 6), nrow = 5)
    +> x
    +     [,1] [,2] [,3] [,4] [,5] [,6]
    +[1,]    1    1    1    1    1    1
    +[2,]    2    2    2    2    2    2
    +[3,]    3    3    3    3    3    3
    +[4,]    4    4    4    4    4    4
    +[5,]    5    5    5    5    5    5
    +> rowSums(x)
    +[1]  6 12 18 24 30
    +> rowMeans(x)
    +[1] 1 2 3 4 5
    +> colSums(x)
    +[1] 15 15 15 15 15 15
    +> colMeans(x)
    +[1] 3 3 3 3 3 3
    +
    +
    +

    Łą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.

    +
    > x = matrix(0, nrow = 2, ncol = 3)
    +> y = matrix(1, nrow = 3, ncol = 3)
    +> z = matrix(2, nrow = 2, ncol = 2)
    +> x
    +     [,1] [,2] [,3]
    +[1,]    0    0    0
    +[2,]    0    0    0
    +> y
    +     [,1] [,2] [,3]
    +[1,]    1    1    1
    +[2,]    1    1    1
    +[3,]    1    1    1
    +> z
    +     [,1] [,2]
    +[1,]    2    2
    +[2,]    2    2
    +> rbind(x, y)
    +     [,1] [,2] [,3]
    +[1,]    0    0    0
    +[2,]    0    0    0
    +[3,]    1    1    1
    +[4,]    1    1    1
    +[5,]    1    1    1
    +> cbind(x, z)
    +     [,1] [,2] [,3] [,4] [,5]
    +[1,]    0    0    0    2    2
    +[2,]    0    0    0    2    2
    +> rbind(y, colSums(y))
    +     [,1] [,2] [,3]
    +[1,]    1    1    1
    +[2,]    1    1    1
    +[3,]    1    1    1
    +[4,]    3    3    3
    +> cbind(z, rowSums(z))
    +     [,1] [,2] [,3]
    +[1,]    2    2    4
    +[2,]    2    2    4
    +
    +
    +

    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).

    +
    > try(setwd("warsztat 2016.10.17"), silent = TRUE)
    +> nazwyObiektow = load("dane_2016.10.17.RData")
    +> nazwyObiektow
    + [1] "etykiety" "Y"        "X"        "Z"        "W"        "V1"      
    + [7] "V2"       "V3"       "V4"       "V5"       "V6"       "V7"      
    +> etykiety
    +                                              Y 
    +                             "Rok badania PGSS" 
    +                                              X 
    +           "Wielkość miejscowości zamieszkania" 
    +                                              Z 
    +          "Liczba osób w gospodarstwie domowym" 
    +                                              W 
    +                             "Wiek respondenta" 
    +                                             V1 
    +           "Zadowolenie z miejsca zamieszkania" 
    +                                             V2 
    +     "Zadowolenie z czasu wolnego i wypoczynku" 
    +                                             V3 
    +               "Zadowolenie z życia rodzinnego" 
    +                                             V4 
    +                      "Zadowolenie z przyjaźni" 
    +                                             V5 
    +                 "Zadowolenie ze stanu zdrowia" 
    +                                             V6 
    +"Zadowolenie ze swoich warunków mieszkaniowych" 
    +                                             V7 
    +         "Zadowolenie z własnego wykształcenia" 
    +> summary(cbind(Y, X, Z, W, V1, V2, V3, V4, V5, V6, V7))
    +    Y                       X                       Z             W      
    + 1992:198   1 Wieś           :436   1 JEDNA          : 67   21     :134  
    + 1995:221   2 M do 25 tys    :197   2 DWIE           :135   20     :131  
    + 1999:354   3 M 25-99,9 tys  :198   3 TRZY           :323   25     :127  
    + 2005:204   4 M 100-499,9 tys:214   4 CZTERY         :291   27     :124  
    + 2010:218   5 M 500+ tys     :150   5 PIĘĆ           :167   28     :123  
    +                                    6 SZEŚĆ          :122   26     :120  
    +                                    7 SIEDEM I WIĘCEJ: 90   (Other):436  
    +                      V1                           V2     
    + 1 Bardzo zadowolony   :228   1 Bardzo zadowolony   :139  
    + 2 Zadowolony          :535   2 Zadowolony          :436  
    + 3 Raczej zadowolony   :286   3 Raczej zadowolony   :309  
    + 4 Raczej niezadowolony: 79   4 Raczej niezadowolony:182  
    + 5 Niezadowolony       : 52   5 Niezadowolony       : 99  
    + 6 Bardzo niezadowolony: 15   6 Bardzo niezadowolony: 30  
    +                                                          
    +                      V3                           V4     
    + 1 Bardzo zadowolony   :344   1 Bardzo zadowolony   :290  
    + 2 Zadowolony          :598   2 Zadowolony          :624  
    + 3 Raczej zadowolony   :192   3 Raczej zadowolony   :228  
    + 4 Raczej niezadowolony: 37   4 Raczej niezadowolony: 34  
    + 5 Niezadowolony       : 13   5 Niezadowolony       : 18  
    + 6 Bardzo niezadowolony: 11   6 Bardzo niezadowolony:  1  
    +                                                          
    +                      V5                           V6     
    + 1 Bardzo zadowolony   :272   1 Bardzo zadowolony   :149  
    + 2 Zadowolony          :609   2 Zadowolony          :450  
    + 3 Raczej zadowolony   :199   3 Raczej zadowolony   :287  
    + 4 Raczej niezadowolony: 78   4 Raczej niezadowolony:128  
    + 5 Niezadowolony       : 28   5 Niezadowolony       :120  
    + 6 Bardzo niezadowolony:  9   6 Bardzo niezadowolony: 61  
    +                                                          
    +                      V7     
    + 1 Bardzo zadowolony   :162  
    + 2 Zadowolony          :520  
    + 3 Raczej zadowolony   :239  
    + 4 Raczej niezadowolony:161  
    + 5 Niezadowolony       : 95  
    + 6 Bardzo niezadowolony: 18  
    +                             
    +
    +

    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.

    +
    > # rozkład wielkości miejscowości zamieszkania w analizowanej zbiorowości
    +> nX = table(X)
    +> nX
    +X
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +              436               197               198               214 
    +     5 M 500+ tys 
    +              150 
    +> str(nX)
    + 'table' int [1:5(1d)] 436 197 198 214 150
    + - attr(*, "dimnames")=List of 1
    +  ..$ X: chr [1:5] "1 Wieś" "2 M do 25 tys" "3 M 25-99,9 tys" "4 M 100-499,9 tys" ...
    +

    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.

    +
    > nX
    +X
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +              436               197               198               214 
    +     5 M 500+ tys 
    +              150 
    +> names(nX)
    +[1] "1 Wieś"            "2 M do 25 tys"     "3 M 25-99,9 tys"  
    +[4] "4 M 100-499,9 tys" "5 M 500+ tys"     
    +> nX[2:4]
    +X
    +    2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +              197               198               214 
    +> nX[names(nX) == "2 M do 25 tys"]
    +2 M do 25 tys 
    +          197 
    +> nX * 2
    +X
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +              872               394               396               428 
    +     5 M 500+ tys 
    +              300 
    +

    Aby obejrzeć rozkład w formie, do jakiej jesteśmy nieco bardziej przyzwyczajeni, możemy użyć funkcji as.matrix().

    +
    > mNX = as.matrix(nX)
    +> colnames(mNX) = "N(X = X_i)"
    +> mNX
    +                  N(X = X_i)
    +1 Wieś                   436
    +2 M do 25 tys            197
    +3 M 25-99,9 tys          198
    +4 M 100-499,9 tys        214
    +5 M 500+ tys             150
    +

    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ęcznie"
    +> c(nX, "suma" = sum(nX))
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +              436               197               198               214 
    +     5 M 500+ tys              suma 
    +              150              1195 
    +> ## analogicznie do rozkładu w formie macierzy
    +> rbind(mNX, "suma" = sum(mNX))
    +                  N(X = X_i)
    +1 Wieś                   436
    +2 M do 25 tys            197
    +3 M 25-99,9 tys          198
    +4 M 100-499,9 tys        214
    +5 M 500+ tys             150
    +suma                    1195
    +> # przy pomocy funkcji addmargins()
    +> addmargins(nX)
    +X
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +              436               197               198               214 
    +     5 M 500+ tys               Sum 
    +              150              1195 
    +> ## 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)
    +                  N(X = X_i)
    +1 Wieś                   436
    +2 M do 25 tys            197
    +3 M 25-99,9 tys          198
    +4 M 100-499,9 tys        214
    +5 M 500+ tys             150
    +Sum                     1195
    +
    +
    +

    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ęcznie"
    +> nX
    +X
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +              436               197               198               214 
    +     5 M 500+ tys 
    +              150 
    +> pX = nX / sum(nX)
    +> pX
    +X
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +        0.3648536         0.1648536         0.1656904         0.1790795 
    +     5 M 500+ tys 
    +        0.1255230 
    +> # przy pomocy funkcji prop.table()
    +> pX = prop.table(nX)
    +> pX
    +X
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +        0.3648536         0.1648536         0.1656904         0.1790795 
    +     5 M 500+ tys 
    +        0.1255230 
    +> # 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
    +                  P(X = x_i)
    +1 Wieś             0.3648536
    +2 M do 25 tys      0.1648536
    +3 M 25-99,9 tys    0.1656904
    +4 M 100-499,9 tys  0.1790795
    +5 M 500+ tys       0.1255230
    +suma               1.0000000
    +

    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ę).

    +
    > nXS = c(nX, "suma" = sum(nX))
    +> nXS
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +              436               197               198               214 
    +     5 M 500+ tys              suma 
    +              150              1195 
    +> # "ręcznie" (w tym przypadku to nawet prościej!)
    +> pXS = nXS / nXS[length(nXS)]
    +> pXS
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +        0.3648536         0.1648536         0.1656904         0.1790795 
    +     5 M 500+ tys              suma 
    +        0.1255230         1.0000000 
    +> # przy pomocy funkcji prop.table()
    +> pXS = prop.table(nXS[-length(nXS)])
    +> pXS = c(pXS, "suma" = sum(pXS))
    +> pXS
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +        0.3648536         0.1648536         0.1656904         0.1790795 
    +     5 M 500+ tys              suma 
    +        0.1255230         1.0000000 
    +> # !!! źle !!!
    +> nXS / sum(nXS)  # !!! źle !!!
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +       0.18242678        0.08242678        0.08284519        0.08953975 
    +     5 M 500+ tys              suma 
    +       0.06276151        0.50000000 
    +> prop.table(nXS)  # !!! źle !!!
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +       0.18242678        0.08242678        0.08284519        0.08953975 
    +     5 M 500+ tys              suma 
    +       0.06276151        0.50000000 
    +> # !!! ź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.

    +
    > rbind("x" = 0:6, "cumsum(x)" = cumsum(0:6))
    +          [,1] [,2] [,3] [,4] [,5] [,6] [,7]
    +x            0    1    2    3    4    5    6
    +cumsum(x)    0    1    3    6   10   15   21
    +
    +
    +

    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.

    +
    > nX = table(X)
    +> nX
    +X
    +           1 Wieś     2 M do 25 tys   3 M 25-99,9 tys 4 M 100-499,9 tys 
    +              436               197               198               214 
    +     5 M 500+ tys 
    +              150 
    +> # to jest miejsce na Twój kod
    +> 
    +> 
    +> 
    +
    +
    +
    +
    +

    Rozkłady łączne dwóch zmiennych

    +

    Funkcja table() pozwala też łatwo uzyskać łączny rozkład liczebności dwóch zmiennych - wystarczy podać jej jako drugi argument inny wektor (o tej samej liczbie elementów, co ten, który podajemy jako pierwszy argument).

    +
    > # łączny rozkład liczebności zadowolenia z własnego wykształcenia
    +> #   i roku przeprowadzenia badania PGSS
    +> nV7Y = table(V7, Y)
    +> nV7Y
    +                        Y
    +V7                       1992 1995 1999 2005 2010
    +  1 Bardzo zadowolony      15   18   34   38   57
    +  2 Zadowolony             97   96  149   79   99
    +  3 Raczej zadowolony      40   40   79   44   36
    +  4 Raczej niezadowolony   27   34   58   25   17
    +  5 Niezadowolony          17   27   29   14    8
    +  6 Bardzo niezadowolony    2    6    5    4    1
    +

    Zwrócony obiekt, jak w przypadku jednowymiarowym, jest typu table, ale tym razem ma dwa wymiary i możemy go traktować podobnie jak macierz.

    +
    > str(nV7Y)
    + 'table' int [1:6, 1:5] 15 97 40 27 17 2 18 96 40 34 ...
    + - attr(*, "dimnames")=List of 2
    +  ..$ V7: chr [1:6] "1 Bardzo zadowolony" "2 Zadowolony" "3 Raczej zadowolony" "4 Raczej niezadowolony" ...
    +  ..$ Y : chr [1:5] "1992" "1995" "1999" "2005" ...
    +> colnames(nV7Y)
    +[1] "1992" "1995" "1999" "2005" "2010"
    +> rownames(nV7Y)
    +[1] "1 Bardzo zadowolony"    "2 Zadowolony"          
    +[3] "3 Raczej zadowolony"    "4 Raczej niezadowolony"
    +[5] "5 Niezadowolony"        "6 Bardzo niezadowolony"
    +> nV7Y[3:4, 2:3]
    +                        Y
    +V7                       1995 1999
    +  3 Raczej zadowolony      40   79
    +  4 Raczej niezadowolony   34   58
    +

    Do uzyskanego rozkładu możemy też dodać rozkłady brzegowe, przy pomocy poznanej już wcześniej funkcji addmargins(). Wywołanie jej bez podania drugiego parametru spowoduje dodanie wszystkich możliwych (tu: dwóch) rozkładów brzegowych. Możemy też zrobić to na piechotę, korzystając z funkcji rowSums(), colSums(), rbind() i cbind().

    +
    > # przy pomocy funkcji addmargins()
    +> addmargins(nV7Y)
    +                        Y
    +V7                       1992 1995 1999 2005 2010  Sum
    +  1 Bardzo zadowolony      15   18   34   38   57  162
    +  2 Zadowolony             97   96  149   79   99  520
    +  3 Raczej zadowolony      40   40   79   44   36  239
    +  4 Raczej niezadowolony   27   34   58   25   17  161
    +  5 Niezadowolony          17   27   29   14    8   95
    +  6 Bardzo niezadowolony    2    6    5    4    1   18
    +  Sum                     198  221  354  204  218 1195
    +> # "na piechotę"
    +> nBV7Y = rbind(nV7Y, "suma" = colSums(nV7Y))
    +> nBV7Y = cbind(nBV7Y, "suma" = rowSums(nBV7Y))
    +> nBV7Y
    +                       1992 1995 1999 2005 2010 suma
    +1 Bardzo zadowolony      15   18   34   38   57  162
    +2 Zadowolony             97   96  149   79   99  520
    +3 Raczej zadowolony      40   40   79   44   36  239
    +4 Raczej niezadowolony   27   34   58   25   17  161
    +5 Niezadowolony          17   27   29   14    8   95
    +6 Bardzo niezadowolony    2    6    5    4    1   18
    +suma                    198  221  354  204  218 1195
    +
    +
    +

    Zadanie

    +

    Dysponując łącznym rozkładem liczebności zmiennych V7 i Y, zapisanym w obiekcie nV7Y oblicz łączny rozkład częstości tych zmiennych i przypisz go do obiektu pV7Y. Pokaż ten rozkład w konsoli z wartościami zaokrąglonymi do trzeciego miejsca po przecinku, używając polecenia round(pV7Y, 3).

    +
    > # to jest miejsce na Twój kod
    +> 
    +> 
    +> 
    +> 
    +
    +
    +
    +
    +

    Rozkłady warunkowe

    +

    Warunkowe rozkłady liczebności w istocie możemy traktować po prostu jako wycinki z łącznego rozkładu liczebności.

    +
    > # warunkowy rozkład liczebności zadowolenia z własnego wykształcenia
    +> #   dla roku badania PGSS równego 1995
    +> nV7Y[, colnames(nV7Y) == "1995"]
    +   1 Bardzo zadowolony           2 Zadowolony    3 Raczej zadowolony 
    +                    18                     96                     40 
    +4 Raczej niezadowolony        5 Niezadowolony 6 Bardzo niezadowolony 
    +                    34                     27                      6 
    +> # warunkowy rozkład liczebności zadowolenia z własnego wykształcenia
    +> #   dla roku badania PGSS mniejszego niż 2000
    +> temp = nV7Y[, as.numeric(colnames(nV7Y)) < 2000]
    +> temp
    +                        Y
    +V7                       1992 1995 1999
    +  1 Bardzo zadowolony      15   18   34
    +  2 Zadowolony             97   96  149
    +  3 Raczej zadowolony      40   40   79
    +  4 Raczej niezadowolony   27   34   58
    +  5 Niezadowolony          17   27   29
    +  6 Bardzo niezadowolony    2    6    5
    +> rowSums(temp)
    +   1 Bardzo zadowolony           2 Zadowolony    3 Raczej zadowolony 
    +                    67                    342                    159 
    +4 Raczej niezadowolony        5 Niezadowolony 6 Bardzo niezadowolony 
    +                   119                     73                     13 
    +

    Rodzina warunkowych rozkładów liczebności jest z kolei właściwie tożsama, z łącznym rozkładem liczebności, z którego obcięto rozkład brzegowy jednej zmiennej.

    +
    > # łączny rozkład liczebności zadowolenia z własnego wykształcenia
    +> #   i roku badania PGSS
    +> addmargins(nV7Y)
    +                        Y
    +V7                       1992 1995 1999 2005 2010  Sum
    +  1 Bardzo zadowolony      15   18   34   38   57  162
    +  2 Zadowolony             97   96  149   79   99  520
    +  3 Raczej zadowolony      40   40   79   44   36  239
    +  4 Raczej niezadowolony   27   34   58   25   17  161
    +  5 Niezadowolony          17   27   29   14    8   95
    +  6 Bardzo niezadowolony    2    6    5    4    1   18
    +  Sum                     198  221  354  204  218 1195
    +> # rodzina warunkowych rozkładów liczebności zadowolenia z własnego wykształcenia
    +> #   pod warunkiem roku badania PGSS
    +> addmargins(nV7Y)[, -(ncol(nV7Y) + 1)]
    +                        Y
    +V7                       1992 1995 1999 2005 2010
    +  1 Bardzo zadowolony      15   18   34   38   57
    +  2 Zadowolony             97   96  149   79   99
    +  3 Raczej zadowolony      40   40   79   44   36
    +  4 Raczej niezadowolony   27   34   58   25   17
    +  5 Niezadowolony          17   27   29   14    8
    +  6 Bardzo niezadowolony    2    6    5    4    1
    +  Sum                     198  221  354  204  218
    +> # lub równoważnie (a nawet prościej)
    +> addmargins(nV7Y, 1)
    +                        Y
    +V7                       1992 1995 1999 2005 2010
    +  1 Bardzo zadowolony      15   18   34   38   57
    +  2 Zadowolony             97   96  149   79   99
    +  3 Raczej zadowolony      40   40   79   44   36
    +  4 Raczej niezadowolony   27   34   58   25   17
    +  5 Niezadowolony          17   27   29   14    8
    +  6 Bardzo niezadowolony    2    6    5    4    1
    +  Sum                     198  221  354  204  218
    +

    Pojedynczy warunkowy rozkład częstości możemy uzyskać na podstawie odpowiedniego warunkowego rozkładu liczebności w analogiczny sposób, jak brzegowy rozkład częstości na podstawie brzegowego rozkładu liczebności.

    +
    > # jakiś rozkład warunkowy
    +> nWarunkowyV7Y1995 = nV7Y[, colnames(nV7Y) == "1995"]
    +> nWarunkowyV7Y1995
    +   1 Bardzo zadowolony           2 Zadowolony    3 Raczej zadowolony 
    +                    18                     96                     40 
    +4 Raczej niezadowolony        5 Niezadowolony 6 Bardzo niezadowolony 
    +                    34                     27                      6 
    +> # "ręcznie"
    +> pWarunkowyV7Y1995 = nWarunkowyV7Y1995 / sum(nWarunkowyV7Y1995)
    +> pWarunkowyV7Y1995
    +   1 Bardzo zadowolony           2 Zadowolony    3 Raczej zadowolony 
    +            0.08144796             0.43438914             0.18099548 
    +4 Raczej niezadowolony        5 Niezadowolony 6 Bardzo niezadowolony 
    +            0.15384615             0.12217195             0.02714932 
    +> # przy pomocy funkcji prop.table
    +> prop.table(nWarunkowyV7Y1995)
    +   1 Bardzo zadowolony           2 Zadowolony    3 Raczej zadowolony 
    +            0.08144796             0.43438914             0.18099548 
    +4 Raczej niezadowolony        5 Niezadowolony 6 Bardzo niezadowolony 
    +            0.15384615             0.12217195             0.02714932 
    +

    Pamiętamy oczywiście o tym, że w sytuacji, gdy do nasz rozkład łączny już wcześniej uzupełniliśmy o rozkłady brzegowe, musielibyśmy obliczyć to nieco inaczej!

    +

    Rodzinę warunkowych rozkładów częstości również możemy uzyskać przy pomocy funkcji prop.table(), podając jej drugi (opcjonalny), argument. Podobnie jak w przypadku funkcji addmargins() wskazuje on, w którą stronę ma być wykonana operacja (tu: procentowania). Żeby sprawy nie były zbyt proste, wartości tego drugiego argumentu mają inne znaczenie w ramach funkcji prop.table(), niż w ramach funkcji addmargins():

    +
      +
    • prop.table(): 1 - procentuj w wierszach, 2 - procentuj w kolumnach;
    • +
    • addmargins(): 1 - dodaj rozkład brzegowy pierwszej zmiennej (dla dwóch zmiennych: ten na dole, tzn. sumuj w kolumnach), 2 - dodaj rozkład brzegowy drugiej zmienej (dla dwóch zmiennych: ten po prawej, tzn. sumuj w wierszach).
    • +
    +
    > # rodzina warunkowych rozkładów częstości zadowolenia z własnego wykształcenia
    +> #   w zależności od roku badania PGSS
    +> rWRPV7Y = addmargins(prop.table(nV7Y, 2), 1)
    +> rWRPV7Y
    +                        Y
    +V7                              1992        1995        1999        2005
    +  1 Bardzo zadowolony    0.075757576 0.081447964 0.096045198 0.186274510
    +  2 Zadowolony           0.489898990 0.434389140 0.420903955 0.387254902
    +  3 Raczej zadowolony    0.202020202 0.180995475 0.223163842 0.215686275
    +  4 Raczej niezadowolony 0.136363636 0.153846154 0.163841808 0.122549020
    +  5 Niezadowolony        0.085858586 0.122171946 0.081920904 0.068627451
    +  6 Bardzo niezadowolony 0.010101010 0.027149321 0.014124294 0.019607843
    +  Sum                    1.000000000 1.000000000 1.000000000 1.000000000
    +                        Y
    +V7                              2010
    +  1 Bardzo zadowolony    0.261467890
    +  2 Zadowolony           0.454128440
    +  3 Raczej zadowolony    0.165137615
    +  4 Raczej niezadowolony 0.077981651
    +  5 Niezadowolony        0.036697248
    +  6 Bardzo niezadowolony 0.004587156
    +  Sum                    1.000000000
    +> round(rWRPV7Y, 3)
    +                        Y
    +V7                        1992  1995  1999  2005  2010
    +  1 Bardzo zadowolony    0.076 0.081 0.096 0.186 0.261
    +  2 Zadowolony           0.490 0.434 0.421 0.387 0.454
    +  3 Raczej zadowolony    0.202 0.181 0.223 0.216 0.165
    +  4 Raczej niezadowolony 0.136 0.154 0.164 0.123 0.078
    +  5 Niezadowolony        0.086 0.122 0.082 0.069 0.037
    +  6 Bardzo niezadowolony 0.010 0.027 0.014 0.020 0.005
    +  Sum                    1.000 1.000 1.000 1.000 1.000
    +
    +
    +
    +

    Prosta wizualizacja rozkładów zmiennych (kategorialnych) - funkcja barplot()

    +
    +

    Prosta wizualizacja rozkładu jednej zmiennej

    +

    Wykres słupkowy obrazujący rozkład jednej zmiennej możemy uzyskać korzystając z funkcji barplot, której jako argument podajemy rozkład danej zmiennej (uwaga, bez ew. elementu z sumą).

    +
    > nX = table(X)
    +> pX = prop.table(nX)
    +> barplot(nX)
    +

    +
    > barplot(pX)
    +

    +

    Funkcja ma też dużą liczbę dodatkowych argumentów, które pozwalają nam zarządzać jego wyglądem i uzupełnić o dodatkowe elmenty (np. tytuł, czy etykiety osi). Funkcji grid() możemy użyć, aby dodać linie siatki.

    +
    > barplot(pX, col = 3,
    ++         main = "Wielkość miejscowości zamieszkania w analizowane zbiorowości",
    ++         ylab = "czestość")
    +> grid(col = grey(0.3), nx = NA, ny = NULL)
    +

    +

    Czasem bardziej użyteczne byłoby pokazanie wykresu w postaci skumulowanej - słupków reprezentujących częstość (względnie liczebność) poszczególnych słupków nałożonych jeden na drugim. Możemy to łatwo uzyskać, konwertując nasz rozkład na macierz przed przekazaniem funkcji barplot().

    +
    > barplot(as.matrix(nX))
    +

    +
    > # nawet mając macierz możemy wrócić do poprzedniego wyglądu
    +> barplot(as.matrix(nX), beside = TRUE)
    +

    +
    > # żeby móc coś zrozumieć, warto dodać legendę
    +> barplot(as.matrix(pX),
    ++         main = "Wielkość miejscowości zamieszkania w analizowane zbiorowości",
    ++         legend.text = TRUE, args.legend =  list(x = "right"), xlim = c(0, 1.8))
    +

    +

    Niestety kwestia pozycjonowania legendy nie jest tu rozwiązana w niezawodny sposób.

    +
    +
    +

    Prosta wizualizacja rozkładu dwóch zmiennych

    +

    Opisane poniżej rozwiązania można oczywiście zastosować do różnych typów rozkładów łącznych i rodzin rozkładów warunkowych, ale prowadząc analizy zwykle skupiamy się na porównywania ze sobą rozkładów w ramach rodziny warunkowych rozkładów częstości. Stąd przykład odnosi się właśnie do takiej rodziny rozkładów.

    +
    > # rodzina warunkowych rozkładów częstości zadowolenia z własnego wykształcenia
    +> #   w zależności od roku badania PGSS
    +> rWRPV7Y = prop.table(nV7Y, 2)
    +> barplot(rWRPV7Y)
    +

    +

    Bez legendy, tytułu i etykiet osi trochę trudno się zorientować, o co chodzi.

    +
    > barplot(rWRPV7Y,
    ++         main = "Zadowolenie z własnego wykształcenia\nw różnych rundach badania PGSS",
    ++         xlab = "rok badania PGSS",
    ++         ylab = "częstość",
    ++         legend.text = TRUE, args.legend =  list(x = "right"), xlim = c(0, 10))
    +

    +

    Możemy też uzyskać wykres w postaci słupków zestawionych obok siebie - choć w tym przypadku jest on raczej mniej użyteczny analitycznie.

    +
    > barplot(rWRPV7Y, beside = TRUE,
    ++         main = "Zadowolenie z własnego wykształcenia\nw różnych rundach badania PGSS",
    ++         xlab = "rok badania PGSS",
    ++         ylab = "częstość",
    ++         legend.text = TRUE, args.legend =  list(x = "topright"), ylim = c(0, 0.9))
    +

    +
    +
    +
    +
    +

    Na następne zajęcia

    +
    +

    Praca domowa

    +

    Wejdź dziś wieczorem na stronę projektu na GitHubie z materiałami z tego warsztatu i zobacz, co pojawiło się w tym miejscu.

    +
    +
    +

    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ły: 1.1.-1.2., 3.5.-3.6., 4.1.-4.2. oraz 4.5. w zakresie, w jakim odnosi się do parametrów omówionych w 4.1. i 4.2.

    +
    +
    + + + + +
    + + + + + + + +