W przykładach omawianych w tej notatce wykorzystuję dane z 6. rundy Europejskiego Sondażu Społecznego. Zbiory danych z wszystkich dotychczas zrealizowanych rund są publicznie dostępne na stronie projektu wraz z wszelką potrzebną dokumentacją metodologiczną. Jedyne ograniczenie w dostępie do danych wiąże się z koniecznością rejestracji, ale sama procedura jest raczej bezbolesna. Co więcej, aplikacja zamieszczona na stronie ESS pozwala na generowanie zbiorów danych wielopoziomowych, w których informacjom o respondentach towarzyszą informacje na temat krajów czy regionów, z których respondenci pochodzą, takich jak wskaźnik PKB czy poziom nierówności dochodowych. Zaletą tej aplikacji jest również to, że umożliwia pobieranie części danych z poszczególnej rundy, niekoniecznie wszystkich. Wykorzystałem tę możliwość przy przygotowywaniu danych na potrzeby tej notatki: zamiast całego zbioru danych, obejmującego wszystkich respondentów i wszystkie zmienne mierzone w ESS wygenerowałem zbiór zawierający informację o

Dodatkowo, zbiór zawiera również wagę postratyfikacyjną (zmienna pspwght) odzwierciedlającą niejednakowe prawdopodobieństwa, z jakimi respondenci są dobierani do próby, a także niejednakowe odsteki realizacji (response rates) w różnych kategoriach. Poniżej pokazuję kilka pierwszych wierszy naszego zbioru.

##       ESS6_id cntry   gndr          eisced         eiscedp marsts icpart2
## 1 AL000000001    AL   male lower secondary         primary     NA     yes
## 2 AL000000002    AL female upper secondary            <NA>      1      no
## 3 AL000000003    AL female upper secondary            <NA>     NA     yes
## 4 AL000000004    AL   male            <NA>            <NA>     NA    <NA>
## 5 AL000000005    AL   male         primary lower secondary     NA     yes
## 6 AL000000006    AL   male         primary         primary     NA     yes
##   pspwght
## 1    3.16
## 2    0.61
## 3    4.23
## 4    2.43
## 5    4.23
## 6    0.26

W dzisiejszej notatce skupiam się na tworzeniu rozkładów liczebności i częstości, a więc na zagadnieniu dość podstawowym. Przyda nam się jednak później, gdy zajmiemy się pisaniem własnych funkcji.

Rozkłady liczebności: funkcja table()

Do sporządzenia rozkładu liczebności zmiennej bądź kilku zmiennych najczęściej wykorzystuje się funkcję table(). Dla przykładu, aby uzyskać rozkład poziomu wykształcenia w próbie wystarczy wpisać:

table(p$eisced)
## 
##         primary lower secondary upper secondary  post-secondary 
##            5897            9819           19527           19066

Tytułem przypomnienia: p to nazwa naszego zbioru danych. Wyrażenie p$eisced oznacza więc zmienną eisced ze zbioru p. Jeśli interesuje nas rozkład łączny poziomu wykształcenia i płci, wpisujemy:

table(p$eisced, p$gndr)
##                  
##                    male female
##   primary          2402   3494
##   lower secondary  4387   5429
##   upper secondary  9542   9976
##   post-secondary   8397  10665

Wreszcie, jeśli interesuje nas rozkład łączny wykształcenia i płci w każdym z krajów uczestniczących w szóstej rundzie ESS, wpisujemy:

table(p$eisced, p$gndr, p$cntry)
## , ,  = AL
## 
##                  
##                   male female
##   primary           56     94
##   lower secondary  187    227
##   upper secondary  216    223
##   post-secondary    81     98
## 
## , ,  = BE
## 
##                  
##                   male female
##   primary           97    132
##   lower secondary  176    172
##   upper secondary  261    260
##   post-secondary   370    388

W okienku powyżej widzimy rozkłady tylko dla dwóch krajów, Albanii i Belgii, choć w szóstej rundzie ESS uczestniczyło 29 krajów. Ponieważ jedank przykłady, które tu podaję służą przede wszystkim ilustracji, nie ma potrzeby, aby wyświetlić trójwymiarowy rozkład w całości.

Funkcja xtabs()

Czasami jednak chcemy sporządzić rozkład liczebności pewnej zmiennej lub grupy zmiennych, ale tylko dla części respondentów, którzy spełniają określone warunki, na przykład, respondentów w wieku 21 - 45 lat zatrudnionych na podstawie umowy o pracę na pełen etat lub respondentów będących w związku małżeńskim lub respondentów, którzy nie mają dzieci, itp., itd. W takich przypadkach wygodniej jest korzystać z funkcji xtabs(). To samo dotyczy przypadków, w których chcemy sporządzić rozkład liczebności z uwzględnieniem wagi poststratyfikacyjnej.

Aby uzyskać rozkład liczebności poziomu wykształcenia przy użyciu funkcji xtabs() możemy posłużyć się następującym poleceniem:

xtabs( ~ eisced, data=p)
## eisced
##         primary lower secondary upper secondary  post-secondary 
##            5897            9819           19527           19066

Rezultat jest taki sam, jak przy użyciu funkcji table(), choć oba polecenia mają nieco inną składnię. Jak widzimy, w przypadku funkcji xtabs() rozkład definiuje się za pomocą formuły o postaci zbliżonej do formuły, za pomocą której określa się modele liniowe w R. Dla przykładu, jeśli chcemy sporządzić rozkład łączny wykształcenia i płci, wpisujemy:

xtabs( ~ eisced + gndr, data=p)
##                  gndr
## eisced             male female
##   primary          2402   3494
##   lower secondary  4387   5429
##   upper secondary  9542   9976
##   post-secondary   8397  10665

Zauważmy, że formuła zawiera wyłącznie nazwy zmiennych. Nazwę zbioru danych, który zawiera te zmienne, określa się za pomocą argumentu data.

W powyższych przykładach, lewa strona formuły jest pusta. Funkcja xtabs() zwraca rozkład liczebności nieważonych. Dodanie wyrażenia po lewej stronie formuły zwróci liczebności odpowiednio zważone. Dla przykładu, aby uzyskać rozkład liczebności poziomu wykształcenia i płci z uwzględnieniem wagi poststratyfikacyjnej, posłużymy się poleceniem:

xtabs(pspwght ~ eisced + gndr, data=p)
##                  gndr
## eisced            male female
##   primary         2606   3525
##   lower secondary 5169   6193
##   upper secondary 9396   9064
##   post-secondary  8610   9815

Jak widzimy, rozkłady uzyskane za pomocą dwóch ostatnich poleceń mają różne liczebności, co wynika właśnie z użycia wagi poststratyfikacyjnej w ostatnim przykładzie, a pominięciu jej w przykładzie wcześniejszym. Możliwość uwzględnienia wagi postratyfikacyjnej sprawia, że funkcja xtabs() jest preferowana przy sporządzaniu rozkładów liczebności w przypadku prób dobranych przy użyciu złożonych, wielostopniowych schematów, przy których prawdopodobieństwa trafienia do próby nie są jednakowe dla wszystkich osób wchodzących w skład badanej populacji.

Przypuśćmy teraz, że chcemy uzyskać rozkład łączny wykształcenia respondenta/-ki i jego/jej żony/męża/partnerki/partnera. Odpowiednie polecenie ma następującą postać:

xtabs(pspwght ~ eisced + eiscedp, data=p)
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary            2213             541             467            217
##   lower secondary     588            2521            1674            713
##   upper secondary     424            1465            6403           2705
##   post-secondary      177             721            3091           8332

Przypuśćmy dalej, że chcemy ograniczyć się wyłącznie do respondentów, którzy faktycznie zamieszkują z osobą, z którą są w związku. Mówiąc inaczej, chcemy ograniczyć się wyłącznie do osób, które są w związku małżeńskim lub partnerskim i faktycznie mieszkają ze swoim mężem/żoną/partnerem/partnerką. Wykorzystamy w tym celu argument subset funkcji xtabs():

xtabs(pspwght ~ eisced + eiscedp, data=p, subset=icpart2=="yes")

Argument subset określa warunek logiczny, zgodnie z którym funkcja xtabs() ma uwzględnić przy sporządzaniu rozkładu łącznego kategorii wykształcenia małżonków/partnerów wyłącznie tych respondentów, dla których zmienna icpart2 przyjmuje wartość "yes". Zmienna ta przyjmuje wartość "yes", gdy respondent mieszka z osobą, z którą jest w związku, i "no" w pozostałych przypadkach. Rezultat ostatniego polecenia jest następujący:

##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary            2208             534             463            217
##   lower secondary     588            2515            1669            712
##   upper secondary     423            1458            6381           2700
##   post-secondary      177             720            3085           8321

Jak widzimy, ostatni rozkład różni się nieco od poprzedniego. Różnice te wynikają z wykluczenia poza zakres analizy tych respondentów, którzy są w stałym związku, ale nie mieszkają z partnerem/partnerką/mężem/żoną.

Ostatnie okienko zawiera rozkład łączny kategorii wykształcenia respondentów i ich partnerów/partnerek/mężów/żon. Przypuśćmy jednak, że interesuje nas rozkład łączny kategorii wykształcenia mężów/partnerów i żon/partnerek. W dalszym ciągu będę dla uproszczenia mówił o rozkładzie łącznym kategorii wykształcenia mężów i żon. Mówiąc inaczej, chcemy uzyskać rozkład, którego wiersze odpowiadać będą kategoriom wykształcenia mężów, zaś kolumny — kategoriom wykształcenia żon. W tym celu musimy najpierw utworzyć rozkład uwzględniający wyłącznie informacje o respondentach i ich żonach/partnerkach, a następnie rozkład uwzględniający wyłącznie informacje o respondentkach i ich mężach/partnerach, przy czym w tym pierwszym rozkładzie kategorie wykształcenia respondenta będą reprezentować kolejne wiersze, natomiast w tym drugim — kategorie wykształcenia respondentek będą reprezentować kolejne kolumny. W ten sposób w obu rozkładach wiersze będą odpowiadać kategoriom wykształcenia mężczyzn, zaś kolumny — kategoriom wykształcenia kobiet.

xtabs(pspwght ~ eisced + eiscedp, data=p, subset=gndr=="male" & icpart2=="yes")
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary            1131             273             201             90
##   lower secondary     310            1221             674            366
##   upper secondary     236             778            3254           1464
##   post-secondary       84             327            1485           4182
xtabs(pspwght ~ eiscedp + eisced, data=p, subset=gndr=="female" & icpart2=="yes") # Uwaga na kolejność zmiennych w formule!!!
##                  eisced
## eiscedp           primary lower secondary upper secondary post-secondary
##   primary            1077             278             187             94
##   lower secondary     262            1294             679            393
##   upper secondary     262             996            3125           1598
##   post-secondary      127             345            1234           4139

Komentarz przy ostatnim poleceniu każe nam zwrócić uwagę na kolejność zmiennych w formule. Zmiana kolejności zmiennych w formule wynika z tego, o czym pisałem wyżej: chcemy, aby kolejne wiersze odpowidały kategoriom wykształcenia partnerów/mężów respondentek, albowiem tym samym oba rozkłady zawierają informacje o poziomach wykształcenia mężczyzn w wierszach i kobiet w kolumnach. Oczywiście, wszystko to opiera się na założeniu, że wszystkie związki partnerskie i małżeńskie to związku heteroseksualne. Założenie to nie musi być prawdziwe. W Europejskim Sondażu Społecznym nie rejestruje się jednak informacji o płci partnera/współmałżonka respondenta, nie ma więc możliwości oddzielenia na potrzeby analizy związków jednopłciowych od różnopłciowych. Przyjmujemy więc, że wspominane założenie jest spełnione.

Dodając do siebie oba uzyskane wyżej rozkłady cząstkowe dostaniemy rozkład łączny kategorii wykształcenia mężów i żon:

xtabs(pspwght ~ eisced + eiscedp, data=p, subset=gndr=="male" & icpart2=="yes") + 
xtabs(pspwght ~ eiscedp + eisced, data=p, subset=gndr=="female" & icpart2=="yes") 
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary            2208             551             389            184
##   lower secondary     572            2515            1352            760
##   upper secondary     498            1774            6380           3063
##   post-secondary      211             672            2719           8320

No, i wreszcie, jeśli chcemy otrzymać taki rozkład dla każdego z krajów uczestniczących w szóstej rundzie ESS osobno, piszemy:

xtabs(pspwght ~ eisced + eiscedp + cntry, data=p, subset=gndr=="male" & icpart2=="yes") + 
xtabs(pspwght ~ eiscedp + eisced + cntry, data=p, subset=gndr=="female" & icpart2=="yes") 

Ostatnie polecenie zwraca tablicę o wymiarach \(4 \times 4 \times 29\). Ze względu na brak miejsca pokazuję tu tylko kawałek tej tablicy:

## , , cntry = AL
## 
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary            42.8            35.7             2.2            0.0
##   lower secondary    19.0           233.0            43.4            3.6
##   upper secondary    15.4            85.7           136.2           25.8
##   post-secondary      2.3             4.7            33.0           64.6
## 
## , , cntry = BE
## 
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary              86              32              22             12
##   lower secondary      37              80              44             33
##   upper secondary      21              35              92             91
##   post-secondary       19              39              87            315

Rozkłady częstości

We wszystkich dotychczasowych przykładach posługiwaliśmy się rozkładami liczebności. Często jednak przedmiotem naszego zainteresowania są rozkłady częstości. Liczebności łatwo przekształcić na częstości (odsetki) za pomocą funkcji prop.table().

tab1 <- xtabs(pspwght ~ eisced, data=p, subset=cntry=="PL")
tab1
## eisced
##         primary lower secondary upper secondary  post-secondary 
##              62             803             586             440
prop.table(tab1)
## eisced
##         primary lower secondary upper secondary  post-secondary 
##           0.033           0.425           0.310           0.233

W pierwszym kroku utworzyliśmy rozkład liczebności zmiennej poziom wykształcenia dla polskiej edycji szóstej rundy ESS. Rozkład ten nazwaliśmy tab1. W drugim kroku, zamieniliśmy liczebności na częstości.

Analogicznie postępujemy, gdy chcemy uzyskać rozkład łączny dwóch lub więcej zmiennych, aczkolwiek należy pamiętać, że przy tablicach liczących dwa lub więcej wymiarów możemy wyznaczyć kilka rodzajów częstości. Dla przykładu, przypuśćmy, że ineteresuje nas rozkład łączny liczebności kategorii wykształcenia mężów i żon w Polsce. Rozkład ten, i polecenie potrzebne do jego utworzenia, pokazano poniżej:

tab2 <- xtabs(pspwght ~ eisced + eiscedp, data=p, subset=cntry=="PL" & gndr=="male" & icpart2=="yes") + 
xtabs(pspwght ~ eiscedp + eisced, data=p, subset=cntry=="PL" & gndr=="female" & icpart2=="yes")
tab2
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary             5.9             9.1             0.0            0.0
##   lower secondary     9.9           322.9           160.4           68.1
##   upper secondary     0.0            68.9           153.9          101.7
##   post-secondary      0.0             6.9            41.9          187.8

Zastosowanie funkcji prop.table() do tego rozkładu zwraca:

prop.table(tab2)
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary          0.0052          0.0080          0.0000         0.0000
##   lower secondary  0.0087          0.2838          0.1410         0.0598
##   upper secondary  0.0000          0.0606          0.1353         0.0894
##   post-secondary   0.0000          0.0061          0.0369         0.1651

A zatem, z uzyskanego rozkładu wynika, że 16.5% wszystkich par w polskiej podpróbie ESS to związki między osobami o wyższym wykształceniu. Przypuśćmy jednak, że interesuje nas nie rozkład łączny częstości poziomów wykształcenia mężów i żon, lecz rozkłady warunkowe rozkładu wykształcenia żon ze względu na wykształcenie mężów. Do sporządzania rozkładów warunkowych częstości wykorzystuje się argument margin funkcji prop.table(). Dla przykładu, polecenie:

prop.table(tab2, margin=1)
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary           0.395           0.605           0.000          0.000
##   lower secondary   0.018           0.575           0.286          0.121
##   upper secondary   0.000           0.212           0.474          0.313
##   post-secondary    0.000           0.029           0.177          0.793

oblicza odsetki w wierszach. A zatem, z uzyskanej tabeli wynika, że wśród mężów z wykształceniem podstawowym (pierwsza kategoria) 39.5% żon ma wykształcenie podstawowe. Podobnie, wśród mężów z wykształceniem zawodowym (druga kategoria) odsetek żon z wykształceniem podstawowym wynosi zaledwie 1.8%.

Jeśli jednak chcemu obliczyć odsetki w kolumnach rozkładu, piszemy:

prop.table(tab2, margin=2)
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary           0.374           0.022           0.000          0.000
##   lower secondary   0.626           0.792           0.450          0.190
##   upper secondary   0.000           0.169           0.432          0.284
##   post-secondary    0.000           0.017           0.118          0.525

A zatem, wśród żon z wykształceniem podstawym, mężowie z wykształceniem zasadniczym stanowią 62.6%, natomiast wśród żon z wykształceniem zasadniczym odsetek ten wynosi 79.2%.

Wreszcie, w przypadku rozkładu trójwymiarowego argument margin można określić na kilka sposobów. Dla przykładu, niech tab3 oznacza rozkład łączny poziomów wykształcenia małżonków/partnerów i kraju uczestniczącego w szóstej rundzie ESS.

tab3 <- xtabs(pspwght ~ eisced + eiscedp + cntry, data=p, subset=gndr=="male" & icpart2=="yes") + 
  xtabs(pspwght ~ eiscedp + eisced + cntry, data=p, subset=gndr=="female" & icpart2=="yes")

Wówczas

prop.table(tab3)

zwróci odsetki par w odniesieniu do całej próby. Tzn., uzyskamy w ten sposób informację o tym, że, na przykład, małżeństwa między osobami z wyższym wykształceniem w Polsce stanowią 0.58% wszystkich małżeństw w próbie ESS. Z kolei,

prop.table(tab3, margin=3)

obliczy rozkłady częstości poziomów wykształcenia małżonków dla każdego z kraju osobno, co widać poniżej:

## , , cntry = AL
## 
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary          0.0573          0.0478          0.0029         0.0000
##   lower secondary  0.0254          0.3117          0.0580         0.0048
##   upper secondary  0.0206          0.1147          0.1822         0.0346
##   post-secondary   0.0031          0.0063          0.0441         0.0865
## 
## , , cntry = BE
## 
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary           0.083           0.031           0.021          0.011
##   lower secondary   0.036           0.077           0.042          0.032
##   upper secondary   0.020           0.034           0.088          0.087
##   post-secondary    0.018           0.037           0.083          0.301

Mówiąc inaczej, w przypadku ostatniego polecenia odsetki będą sumować się do 1 w przypadku każdej tabeli cząstkowej odpowiadającej poszczególnemu krajowi. W przypadku poprzedniego polecenia, odsetki sumują się do jedności w całej tabeli, obejmującej wszystkie kraje.

Wreszcie,

prop.table(tab3, margin=c(1,3))

zwróci rozkłady warunkowe w wierszach dla każdej tabeli cząstkowej osobno:

## , , cntry = AL
## 
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary           0.531           0.442           0.027          0.000
##   lower secondary   0.063           0.779           0.145          0.012
##   upper secondary   0.058           0.326           0.518          0.098
##   post-secondary    0.022           0.045           0.315          0.617
## 
## , , cntry = BE
## 
##                  eiscedp
## eisced            primary lower secondary upper secondary post-secondary
##   primary           0.567           0.213            0.14          0.078
##   lower secondary   0.192           0.411            0.23          0.172
##   upper secondary   0.087           0.147            0.39          0.380
##   post-secondary    0.041           0.085            0.19          0.685

Mówiąc inaczej, odsetki będą sumować się do 1 w każdym wierszu każdej z tabel cząstkowych. Argument margin=c(2,3) daje taki sam rezultat w przypadku kolumn.