Dzisiejsze zajęcia poświęcone będą zmiennym kategorialnym w modelu liniowym. Do tej pory koncentrowaliśmy się na zmiennych liczbowych i relacjach między nimi. Teraz jednak rozszerzymy naszą wiedzę i zobaczymy, że możemy wykorzystać model liniowy również wówczas, gdy nasze zmienne objaśniające są są zmiennymi nominalnymi (kategorialnymi). Przykładem takich zmiennych może być płeć, wykształcenie, preferencje polityczne, religia, ale także – uwaga – warunek eksperymentalny, w którym znalazł się uczestnik badania (np. rodzaj terapii) albo rodzaj próby w eksperymencie.
Na początek wczytamy dane dotyczące guilty pleasure z eksperymentu omawianego na zajęciach. Następnie zakodujemy sobie od razu poszczególne wyniki tak, jak robiliśmy to na pierwszych zajęciach poświęconych regresji.
(W dzisiejszym notatniku celowo nie użyjemy pakietu
knitr
oraz pander
aby opatrzyli się Państwó
również ze standardowum outputem R.)
data <- read.csv("Study3_Results_AfterExclusion.csv", header = T)
data$ART <- apply(data[,c("ART1", "ART2", "ART3")], 1, mean)
data$IDEAL <- apply(data[,c("IDEAL1", "IDEAL2")], 1, mean)
data$PEOPLE <- apply(data[,c("PEOPLE1", "PEOPLE2")], 1, mean)
data$SOCIAL <- apply(data[,c("SOCIAL1", "SOCIAL2")], 1, mean)
data$INTELLECTUAL <- apply(data[,c("INTELLECTUAL1", "INTELLECTUAL2")], 1, mean)
Do tej pory wszystko co tutaj zrobiliśmy powinno być dla Państwa
zrozumiałe. Obliczyliśmy średnią z pytań ART1
,
ART2
i ART3
dla każdego badanego, a następnie
zapisaliśmy ją w kolumnie ART
. Tak samo postąpiliśmy z
innymi pytaniami.
Założmy, że chcielibyśmy dowiedzieć się, czy kobiety są bardziej skłonne od mężczyzn do wyższych odpowiedzi na pytania testujące wyjaśnienie odwołujące się do wartości intelektualnych dzieła (tzn. np. “This work is not very complex or intellectual”). Załóżmy, że mamy hipotezę, która głosi, że kobiety są przemądrzałe i będą prezentować wyższy poziom zgody na takie stwierdzenia dotyczące przyczyn ich guilty pleasure.
Na początek odfiltrujmy tylko te obserwacje, w których mamy
jakąkolwiek wartość w kolumnie GENDER
.
data_filtered <- data[data$GENDER != "",]
# usuwamy z naszego factora nieużywany, pusty poziom
# uwaga!
Następnie stwórzmy model, w którym za pomocą zmiennej
GENDER
przewidywać będziemy wynik na skali
INTELLECTUAL
.
fit <- lm(INTELLECTUAL ~ GENDER, data = data_filtered)
summary(fit)
##
## Call:
## lm(formula = INTELLECTUAL ~ GENDER, data = data_filtered)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.9151 -0.8557 0.0849 1.0849 2.7037
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.2963 0.2062 20.834 <2e-16 ***
## GENDERA woman 0.6188 0.2930 2.112 0.0371 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.515 on 105 degrees of freedom
## Multiple R-squared: 0.04074, Adjusted R-squared: 0.03161
## F-statistic: 4.46 on 1 and 105 DF, p-value: 0.03707
Jak widzimy GENDER
osiągnęło tutaj próg statystycznej
istotności dla \(\alpha = 0.05\).
W Państwa głowach w tym momencie powinno pojawić się pytanie. “Dlaczego nie wykorzystaliśmy po prostu testu \(t\) Studenta, tak jak to robiliśmy do tej pory?” - mogą Państwo zapytać. Pytanie jest oczywiście zasadne. Zobaczmy, czy test \(t\) Studenta da nam inny wynik niż analiza regresji:
t.test(INTELLECTUAL ~ GENDER, var.equal = T, data = data_filtered)
##
## Two Sample t-test
##
## data: INTELLECTUAL by GENDER
## t = -2.1119, df = 105, p-value = 0.03707
## alternative hypothesis: true difference in means between group A man and group A woman is not equal to 0
## 95 percent confidence interval:
## -1.19978685 -0.03780923
## sample estimates:
## mean in group A man mean in group A woman
## 4.296296 4.915094
Okazuje się, że dla zmiennej kategorialnej posiadającej dwa poziomy (tutaj: mężczyzna i kobieta), test \(t\) Studenta i analiza regresji są sobie równoważne! Dodatkowo, dzięki spojrzeniu na wynik testu \(t\) Studenta widzimy bardzo dobrze jak interpretować w tym wypadku wyraz wolny regresji oraz współczynniki regresji.
Wyraz wolny regresji (w tabeli: (Intercept)
) wynosił w
tym wypadku \(4.2963\). Patrząc na
wynik testu t-Studenta widzimy, że jest to po prostu średnia
INTELLECTUAL
dla grupy mężczyzn! Współczynnik regresji dla
GENDER: A woman
wynosi \(0.6188\) i jest to po prostu różnica między
średnią INTELLECTUAL
u kobiet i u mężczyzn.
Oczywiście w przypadku regresji mamy znacznie większe możliwości niż przy teście t Studenta. Możemy, dodając więcej zmiennych różnego rodzaju (liczbowych i nominalnych) kontrolować wpływ tych czynników na interesującą nas różnicę.
Fakt, że jakaś znana już Państwu procedura będzie równoważna modelowi liniowemu, będzie powracającym motywem na tych zajęciach.
Zobaczmy co się stanie w przypadku, gdy nasza zmienna będzie miała
więcej niż dwa poziomy. Badacze pytali również o to, z jakim innym
odczuciem łączy się guilty pleasure odczuwane przez badanych
(kolumna EMOTION
). Badani mogli wybrać jedną z pięciu opcji
(obrzydzenie, wina, zażenowanie, zawstydzenie, smutek) lub wpisać
własne.
Zobaczmy, czy to, które uczucie wskazywali, wpływa na ich wynik na
skali PEOPLE
(intersubiektywna zgoda). Na początek
odfiltrujemy tylko te obserwacje, w których badani udzielili jednej z
predefiniowanych odpowiedzi.
ls <- c("DISGUST", "GUILT", "EMBARRASSMENT", "SHAME", "SADNESS")
data_filtered <- data[data$EMOTION %in% ls, ]
Następnie stwórzmy odpowiedni model i przyjrzyjmy się mu dokładnie:
fit <- lm(PEOPLE ~ EMOTION, data = data_filtered)
summary(fit)
##
## Call:
## lm(formula = PEOPLE ~ EMOTION, data = data_filtered)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.6410 -0.6410 -0.0625 0.8958 2.8590
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.56250 0.46730 7.624 1.45e-11 ***
## EMOTIONEMBARRASSMENT 1.54167 0.50474 3.054 0.00289 **
## EMOTIONGUILT 0.07853 0.51299 0.153 0.87865
## EMOTIONSADNESS 0.31250 0.80938 0.386 0.70025
## EMOTIONSHAME 1.10417 0.71381 1.547 0.12505
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.322 on 100 degrees of freedom
## Multiple R-squared: 0.2339, Adjusted R-squared: 0.2032
## F-statistic: 7.631 on 4 and 100 DF, p-value: 2.086e-05
Widzimy, że w naszym modelu mamy cztery czynniki (zasadniczo
uniwersalnym faktem jest to, że będziemy ich mieli \(k-1\), gdzie \(k\) to liczba poziomów naszej zmiennej
kategorialnej). Jak łatwo zauważyć, brakuje nam obrzydzenia
(DISGUST
). Oznacza to, że średni wynik dla
DISGUST
jest właśnie naszą wartością referencyjną, do
której porównujemy pozostałe średnie. Łatwo możemy się o tym przekonać,
zobaczywszy średnie dla poszczególnych grup (proszę zwrócić uwagę -
DISGUST
ma średnią \(3.56\), co jest w tym wypadku równe
wyrazowi wolnemu regresji.
tapply(data_filtered$PEOPLE, data_filtered$EMOTION, mean)
## DISGUST EMBARRASSMENT GUILT SADNESS SHAME
## 3.562500 5.104167 3.641026 3.875000 4.666667
Co jednak gdybyśmy chcieli wybrać inną grupę jako grupę, do której
porównujemy pozostałe? W takim wypadku musimy ręcznie ustawić
odpowiednie kontrasty. W przypadku kontrastów prostych (a takimi się
teraz zajmowaliśmy nawet o tym nie wiedząc!) możemy zrobić to używając
funkcji contr.treatment
.
Przy wyborze grupy referencyjnej powinniśmy kierować się kilkoma zasadami.
Po pierwsze, porównania do grupy referencyjnej powinny być użyteczne. Jeśli na przykład porównujemy ze sobą jakieś terapie, to warto jako jako grupę referencyjną potraktować grupę kontrolną, gdzie uczestnicy nie dostawali żadnej terapii lub – jeżeli takiej grupy w badaniu nie było – grupę, która przyjmowała ,,standardową’’ terapię, której skuteczność powinna być najniższa (w porównaniu do fantastycznych nowych terapii, które testujemy!).
Po drugie, nie warto jako referencyjnych wybierać takich poziomów jak “Inne” albo “Nie określono”, ponieważ wtedy nasze porównania nie będą jasne (nie bardzo wiemy, do czego porównujemy, skoro jako referencyjną wybraliśmy ,,śmietnikową’’ (waste-basket) kategorię).
Po trzecie, warto wybrać grupę, w której mamy relatywnie dużo obserwacji (w porównaniu do pozostałych grup). Dzięki temu nasze wyniki będą lepiej replikowalne.
Wróćmy teraz do naszej zmiennej EMOTION
. W tym wypadku
trudno zastosować pierwszą i drugą zasadę, więc skoncentrujemy się na
trzeciej. Najwięcej obserwacji mamy w grupie, która wskazała na
EMBARASSMENT
, dlatego to właśnie ją uczynimy grupą
referencyjną.
data_filtered$EMOTION <- factor(data_filtered$EMOTION)
contrasts(data_filtered$EMOTION) <- contr.treatment(5, # sumaryczna liczba poziomów zmiennej
base = 2 # który poziom ma być referencyjny
)
Teraz możemy jeszcze raz powtórzyć naszą regresję. Tym razem
porównywać będziemy do grupy, która wskazała na emocję “zażenowanie”
(EMBARASSMENT
).
fit <- lm(PEOPLE ~ EMOTION, data = data_filtered)
summary(fit)
##
## Call:
## lm(formula = PEOPLE ~ EMOTION, data = data_filtered)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.6410 -0.6410 -0.0625 0.8958 2.8590
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 5.1042 0.1908 26.755 < 2e-16 ***
## EMOTION1 -1.5417 0.5047 -3.054 0.00289 **
## EMOTION3 -1.4631 0.2849 -5.135 1.39e-06 ***
## EMOTION4 -1.2292 0.6878 -1.787 0.07697 .
## EMOTION5 -0.4375 0.5723 -0.764 0.44641
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.322 on 100 degrees of freedom
## Multiple R-squared: 0.2339, Adjusted R-squared: 0.2032
## F-statistic: 7.631 on 4 and 100 DF, p-value: 2.086e-05
Jak widzimy zmienił się nasz wyraz wolny regresji, współczynniki
regresji oraz wartośc \(p\). Nic
dziwnego! Teraz naszej grupy odniesienia nie wyznacza już poziom
DISGUST
, ale EMBARASSMENT
.
Być może jednak takie porównania nas nie interesują. Nie zawsze jest bowiem sens porównywać średnie dla poszczególnych grup do jakiejś jednej, z góry ustalonej grupy. Czasami chcielibyśmy się dowiedzieć czegoś innego. Z pomocą nam przyjdą tutaj inne kontrasty. Pierwszym rodzajem, którym się zajmiemy, są kontrasty odchylenia.
Zanim jednak przejdziemy do innych rodzajów kontrastów, spróbujmy
zobaczyć co tak naprawdę robi funkcja contr.treatment
,
której użyliśmy przed chwilą.
contr.treatment(5)
## 2 3 4 5
## 1 0 0 0 0
## 2 1 0 0 0
## 3 0 1 0 0
## 4 0 0 1 0
## 5 0 0 0 1
Funkcja ta zwraca nam macierz kontrastów. Możemy o tym myśleć jako o sposobie kodowania naszej zmiennej kategorialnej. 5 poziomów zmiennej kategorialnej zakodowaliśmy za pomocą czterech binarnych zmiennych. Pierwszy poziom kodujemy za pomocą wektora \((0,0,0,0)\), drugi to \((1,0,0,0)\), trzeci to \((0,1,0,0)\), czwarty to \((0,0,1,0)\) i ostatni piąty to \((0,0,0,1)\). Schemat ten dość łatwo zrozumieć i jest na pierwszy rzut oka naturalny.
Każdy element takiego wektora opisuje dychotomiczną cechę obserwacji - należenie bądź nienależenie do jakiejś kategorii. Często spotkają Państwo określenie dummy coding. Inne schematy kodowania będą wyglądać podobnie, ale różnić się będą tym, jak należy analizę, w której są one użyte, interpretować.
Przyjrzyjmy się jeszcze równaniu regresji w przypadku dummy coding. Dla omawianego przez nas przykładu pięciu poziomów zmiennej kategorialnej będzie ono miało poznać:
\[ \hat{Y} = B_1C_1 + B_2C_2 + B_3C_3 + B_4C_4 + B_0 \]
Załóżmy więc, że mamy 5 kategorii: DISGUST
(\(C_1\)), EMBARRASSMENT
,
GUILT
(\(C_2\)),
SADNESS
(\(C_3\)) oraz
SHAME
(\(C_4\)) a
kategorią referencyjną jest EMBARASSMENT
. W dummy
coding grupa referencyjna zakodowana jest jako same zera, dlatego
dla tej grupy równanie możemy zredukować:
\[ \hat{Y} = B_1(0) + B_2(0) + B_3(0) + B_4(0) + B_0 = B_0 = M_{Embarassment} \]
Widzimy więc teraz, dlaczego przy dummy coding wyraz wolny
regresji to średnia dla grupy referencyjnej. Przeanalizujmy jeszcze
jeden przykład, tym razem obserwacji z grupy GUILT
.
\[ \hat{Y} = B_1(0) + B_2(1) + B_3(0) + B_4(0) + B_0 = B_0 + B_2 = M_{Guilt} \]
Teraz już rozumiemy, dlaczego współczynnik regresji dla
GUILT
był różnicą między średnią dla grupy referencyjnej a
średnią dla grupy GUILT
!
Pamiętajmy jednak, że niezależnie od tego, jak zakodujemy nasze zmienne nominalne na użytek regresjii liniowej, kilka rzeczy się nie zmienia. Będziemy mieli taką samą wartość \(R^2\) i taką samą związaną z nim wartość \(p\). Nie dodajemy ani nie odejmujemy żadnych informacji, decydując się na inny schemat kodowania, dlatego nie powinno nas to specjalnie tutaj dziwić. Inny sposób kodowania będzie jednak zmieniał interpretacje wyrazu wolnego oraz poszczególnych współczynników \(B\) dla zmiennych uwzględnionych w regresji.
(Uwaga! Standaryzowane współczynniki regresji dla zmiennych nominalnych nie są specjalnie użyteczne, ponieważ ich odchylenie standardowe zależy od tego, ile obserwacji jest w danej kategorii! Proszę o tym pamiętać! I zastanowić się dlaczego tak jest!)
To, który schemat kodowania wybierzmy, zależy od tego na jakie pytania badawcze chcemy odpowiedzieć za pomocą przeprowadzanej przez nas analizy.
Kontrasty odchylenia pozwalają nam porównywać średnie dla poszczególnych poziomów naszej zmiennej kategorialnej nie do jednego, referencyjnego poziomu, ale do ogólnej średniej ze średnich dla wszystkich poziomów naszej zmiennej.
W przypadku zmiennej EMOTION
takie porównanie może być
bardziej przydatne - nie mamy w tym wypadku powodu, dla którego jakichś
jeden jej poziom miałby mieć szczególne znaczenie. Możemy powiedzieć
R-owi, że chcemu użyć kontrastów odchylenia korzystając z funkcji
contr.sum
(proszę dla zaspokojenia ciekawości zobaczyć
sobie samemu jak wygląda macierz zwracana przez tę funkcję).
contrasts(data_filtered$EMOTION) <- contr.sum(5)
fit <- lm(PEOPLE ~ EMOTION, data = data_filtered)
summary(fit)
##
## Call:
## lm(formula = PEOPLE ~ EMOTION, data = data_filtered)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.6410 -0.6410 -0.0625 0.8958 2.8590
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.1699 0.2027 20.569 < 2e-16 ***
## EMOTION1 -0.6074 0.4149 -1.464 0.146330
## EMOTION2 0.9343 0.2509 3.724 0.000324 ***
## EMOTION3 -0.5288 0.2607 -2.028 0.045175 *
## EMOTION4 -0.2949 0.5506 -0.536 0.593447
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.322 on 100 degrees of freedom
## Multiple R-squared: 0.2339, Adjusted R-squared: 0.2032
## F-statistic: 7.631 on 4 and 100 DF, p-value: 2.086e-05
W tym wypadku wyraz wolny regresji to średnia ze średnich obliczonych dla każdego poziomu naszego czynnika. Możemy to potwierdzić obliczając ręcznie średnią ze średnich dla wszystkich poziomów naszej zmiennej.
mean(tapply(data_filtered$PEOPLE, data_filtered$EMOTION, mean))
## [1] 4.169872
Współczynniki regresji dla poszczególnych poziomów naszej zmiennej są w tym wypadku różnicami między średnimi dla danego poziomu i średnią ze średnich dla wszystkich poziomów. Możemy się o tym łatwo przekonać.
srednie <- tapply(data_filtered$PEOPLE, data_filtered$EMOTION, mean)
srednia_srednich <- mean(srednie)
srednie - srednia_srednich
## DISGUST EMBARRASSMENT GUILT SADNESS SHAME
## -0.6073718 0.9342949 -0.5288462 -0.2948718 0.4967949
Potencjalnym problemem może być jednak to, że mamy podanego współczynnika regresji oraz wyniku testu statystycznego dla jednego z poziomów naszej zmiennej. Co do zasady powinniśmy się z tym pogodzić. Tutaj, w przeciwieństwie do dummy coding jako grupę bazową powinniśmy wybrać tę, która jest dla nas z punktu widzenia stawianych przez nas pytań badawczych najmniej interesująca. Możemy z tym sobie (dość nieelegancko) poradzić przestawiając poziomy zmiennej w taki sposób, żeby inny poziom był wyłączony z modelu.
data_filtered$EMOTION_ALT <- factor(data_filtered$EMOTION, levels = ls)
Teraz możemy jeszcze raz przeprowadzić regresję liniową. Proszę zwrócić uwagę na fakt, że współczynniki regresji nie zmieniły się, chociaż na pierwszy rzut oka mamy inny zestaw predyktorów.
contrasts(data_filtered$EMOTION_ALT) <- contr.sum(5)
fit <- lm(PEOPLE ~ EMOTION_ALT, data = data_filtered)
summary(fit)
##
## Call:
## lm(formula = PEOPLE ~ EMOTION_ALT, data = data_filtered)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.6410 -0.6410 -0.0625 0.8958 2.8590
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.1699 0.2027 20.569 < 2e-16 ***
## EMOTION_ALT1 -0.6074 0.4149 -1.464 0.146330
## EMOTION_ALT2 -0.5288 0.2607 -2.028 0.045175 *
## EMOTION_ALT3 0.9343 0.2509 3.724 0.000324 ***
## EMOTION_ALT4 0.4968 0.4645 1.069 0.287441
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.322 on 100 degrees of freedom
## Multiple R-squared: 0.2339, Adjusted R-squared: 0.2032
## F-statistic: 7.631 on 4 and 100 DF, p-value: 2.086e-05
Dlaczego teraz nasze współczynniki regresji oraz wyraz wolny mają
inną interpretację, niż w wypadku dummy coding? Zobaczmy jakie
wartości przypisuje poszczególnym poziomem zmiennych funkcja
contr.sum
:
contr.sum(5)
## [,1] [,2] [,3] [,4]
## 1 1 0 0 0
## 2 0 1 0 0
## 3 0 0 1 0
## 4 0 0 0 1
## 5 -1 -1 -1 -1
Widzimy, że jedyną różnicą w porównaniu do dummy coding jest to, że grupa referencyjna zakodowana jest za pomocą wartości -1 zamiast samych zer. Zmienia to jednak całkowicie interpretację wyrazu wolnego regresji oraz współczynników regresji, o czym należy pamiętać!
Do tej pory poziomy naszej zmiennej kategorialnej nie były
uporządkowe. Trudno sensownie wskazać jakiś porządek w sytuacji, kiedy
na tapecie mamy pięć emocji albo dwie (lub więcej!) płcie. Co jednak z
sytuacjami, gdy mamy zmienną na skali porządkowej? Przykładem takiej
zmiennej z omawianego pytania jest FREQUENCY
, które dotyczy
częstotliwości występowania guilty pleasure u badanych.
Przyjmuje ona pięć wartości – “Never”, “Very rarely”, “Sometimes”,
“Often” oraz “Very often”. Załóżmy, że chcielibyśmy dowiedzieć się, czy
istnieje związek między częstością występowania guilty pleasure
a siłą przekonania o tym, że nie powinno się konsumować wywołujących
guilty pleasure dzieł kultury. Możemy oczywiście odpowiednią
zmienną uwzględnić w naszym modelu w domyślny dla R sposób:
fit <- lm(SHOULDNOT ~ FREQUENCY, data = data)
summary(fit)
##
## Call:
## lm(formula = SHOULDNOT ~ FREQUENCY, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.7941 -1.2222 0.2059 1.2059 2.7778
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.000 1.685 1.780 0.078 .
## FREQUENCYOften 1.900 1.767 1.075 0.285
## FREQUENCYSometimes 1.794 1.698 1.057 0.293
## FREQUENCYVery often 2.333 1.946 1.199 0.233
## FREQUENCYVery rarely 1.222 1.716 0.712 0.478
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.685 on 104 degrees of freedom
## Multiple R-squared: 0.03619, Adjusted R-squared: -0.000882
## F-statistic: 0.9762 on 4 and 104 DF, p-value: 0.4239
Interpretacja tak przeprowadzonej analizy nie jest jednak łatwa. R
przyjął jako referencyjny poziom naszej zmiennej “Never” (pamiętajmy,
domyślnie R używa kontrastów prostych!). Analiza ta nie pozwala nam to
ocenić występowania żadnego trendu, ponieważ poziomy nie są
uporządkowane. Spróbujmy ten problem rozwiązać. Na początek przekodujemy
sobie naszą zmienną FREQUENCY
tak, by miała typ
factor
i była uporządkowana (ordered=T
).
data$FREQUENCY <- factor(data$FREQUENCY,
levels = c("Never", "Very rarely", "Sometimes", "Often", "Very often"),
ordered = T
)
Spróbujmy po przekodowaniu zmiennej FREQUENCY
zilustrować średnie z SHOULD
dla każdego z (już teraz
uporządkowanych) poziomów powtórzyć naszą analizę.
Na początek wykonajmy wykres słupkowy.
barplot(tapply(data$SHOULDNOT, data$FREQUENCY, mean))
Następnie zróbmy wykres pudełkowy.
plot(data$SHOULDNOT ~ data$FREQUENCY)
Widzimy, że w naszych danych widoczny jest pewien trend - im częściej ktoś doświadczał guilty pleasure tym silniej zgadza się, że nie powinien go doświadczać.
Powtórzmy teraz naszą analizę.
fit <- lm(SHOULDNOT ~ FREQUENCY, data = data)
summary(fit)
##
## Call:
## lm(formula = SHOULDNOT ~ FREQUENCY, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.7941 -1.2222 0.2059 1.2059 2.7778
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.44993 0.41073 10.834 <2e-16 ***
## FREQUENCY.L 1.69006 1.24641 1.356 0.178
## FREQUENCY.Q -0.54623 1.05906 -0.516 0.607
## FREQUENCY.C 0.30920 0.73097 0.423 0.673
## FREQUENCY^4 0.07281 0.40562 0.179 0.858
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.685 on 104 degrees of freedom
## Multiple R-squared: 0.03619, Adjusted R-squared: -0.000882
## F-statistic: 0.9762 on 4 and 104 DF, p-value: 0.4239
Jak widzimy, R po przekodowaniu danych do factor
z
uporządkowanymi poziomami, zrobił coś, czego nie robił wcześniej. Użył
zamiast kontrastów prostych kontrastów wielomianowych i
testował cztery rodzaje trendu - opisywanego przez funkcję liniową,
kwadratową oraz wielomiany trzeciego i czwartego stopnia. Żaden z tych
trendów nie okazał się jednak statystycznie istotny.
Żeby unaocznić jak działają kontrasty wielomianowe rozważmy najprostszy przypadek, to znaczy wielomian pierwszego stopnia czyli – w naszym wypadku – po prostu funkcję liniową. W kolumnie FREQUENCY_QUANT możemy znaleźć dane z kolumny FREQUENCY przekodowane na wartości liczbowe.
fit <- lm(SHOULDNOT ~ FREQUENCY_QUANT, data = data)
summary(fit)
##
## Call:
## lm(formula = SHOULDNOT ~ FREQUENCY_QUANT, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.7106 -1.2910 0.2894 1.2894 2.7090
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.4519 0.6883 5.015 2.12e-06 ***
## FREQUENCY_QUANT 0.4196 0.2324 1.805 0.0738 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.667 on 107 degrees of freedom
## Multiple R-squared: 0.02956, Adjusted R-squared: 0.02049
## F-statistic: 3.259 on 1 and 107 DF, p-value: 0.07385
Domyślnie (z powodów matematycznych) contr.poly
produkuje kontrasty wielomianowe \(n-1\) stopnia gdzie \(n\) to liczba poziomów zmiennej. Możemy
jednak dość łatwo zredukować liczbę kontrastów tak, aby testować tylko
trend liniowy.
contrasts(data$FREQUENCY, 1) <- contr.poly(5)[,1:2]
fit <- lm(SHOULDNOT ~ FREQUENCY, data = data)
summary(fit)
##
## Call:
## lm(formula = SHOULDNOT ~ FREQUENCY, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.7106 -1.2910 0.2894 1.2894 2.7090
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.7106 0.1621 29.065 <2e-16 ***
## FREQUENCY.L 1.3268 0.7350 1.805 0.0738 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.667 on 107 degrees of freedom
## Multiple R-squared: 0.02956, Adjusted R-squared: 0.02049
## F-statistic: 3.259 on 1 and 107 DF, p-value: 0.07385
Jeśli to zrobimy, to zarówno wyraz wolny regresji, współczynnik
regresji jak i wartość p będą takie same jak w przypadku, gdy użyliśmy
zmiennej liczbowej (FREQUENCY_QUANT
).
Korzystając z odwróconych kontrastów Helmerta dla każdego poziomu zmiennej kategorialnej (gdzie poziomy są uporządkowane, to znaczy mamy zmienną na skali porządkowej) porównujemy średnią dla danego poziomu ze średnią ze średnich dla wszystkich poziomów poprzednich. Innymi słowy, jeżeli mamy 4 poziomy jakiejś zmiennej, to porównujemy średnią dla poziomu 2 ze średnią dla poziomu 1, średnią dla poziomu 3 ze średnią ze średnich dla poziomów 1 i 2 oraz średnią dla poziomu 4 ze średnią ze średnich dla poziomów 1, 2 oraz 3.
Do czego taka analiza mogłaby się przydać? Rozważmy relację między tym, jak źle ktoś czuje się z poziomu guilty pleasure a tym, jak często go doświadcza. Na początek narysujmy sobie wykresy ilustrujące nasze dane.
barplot(tapply(data$FEELBAD, data$FREQUENCY, mean))
plot(data$FEELBAD ~ data$FREQUENCY)
Widzimy, że po pewnej tendencji wzrostowej (“Never” - “Very rarely” - “Sometimes” - “Often”) następuje gwałtowny spadek. Im częściej ktoś odczuwa guilty pleasure tym gorzej się z tym czuje, chyba że odczuwa je bardzo często, wtedy jest mu wszystko jedno.
Spróbujmy powiedzieć R-owi żeby dla naszej zmiennej
FREQUENCY
skorzystał z odwróconych kontrastów Helmerta.
Robimy to korzystając z funkcji contr.helmert
.
contrasts(data$FREQUENCY) <- contr.helmert(5)
fit <- lm(FEELBAD ~ FREQUENCY, data = data)
summary(fit)
##
## Call:
## lm(formula = FEELBAD ~ FREQUENCY, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.5 -1.0 0.0 1.0 3.0
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.0667 0.3562 11.416 <2e-16 ***
## FREQUENCY1 0.5000 0.7442 0.672 0.503
## FREQUENCY2 0.3333 0.2550 1.307 0.194
## FREQUENCY3 0.4167 0.1702 2.449 0.016 *
## FREQUENCY4 -0.1833 0.1861 -0.985 0.327
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.462 on 104 degrees of freedom
## Multiple R-squared: 0.09167, Adjusted R-squared: 0.05673
## F-statistic: 2.624 on 4 and 104 DF, p-value: 0.03888
Wiersz FREQUENCY 1
oznacza tutaj porównanie “Very
rarely” z “Never”, FREQUENCY 2
– “Sometimes” z “Never” i
“Very rarely”, FREQUENCY 3
– “Often” z “Sometimes”, “Very
rarely” oraz “Never” i w końcu FREQUENCY 4
- “Very often” z
resztą poziomów. Widzimy, że tylko dla trzeciego kontrastu osiągnęliśmy
statystyczną istotność.
Czasami chcielibyśmy porównywać średnią dla danego poziomu nie ze
średnią ze wszystkich poprzednich poziomów, ale ze średnią z
poprzedniego poziomu. To umożliwią nam kontrasty różnicowe. W R możemy
wygenerować takie konstrasty za pomocą funkcji contr.sdif
z
pakietu MASS
.
contrasts(data$FREQUENCY) <- MASS::contr.sdif(5)
fit <- lm(FEELBAD ~ FREQUENCY, data = data)
summary(fit)
##
## Call:
## lm(formula = FEELBAD ~ FREQUENCY, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.5 -1.0 0.0 1.0 3.0
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.0667 0.3562 11.416 <2e-16 ***
## FREQUENCY2-1 1.0000 1.4884 0.672 0.5032
## FREQUENCY3-2 0.5000 0.3325 1.504 0.1356
## FREQUENCY4-3 1.0000 0.4950 2.020 0.0459 *
## FREQUENCY5-4 -2.1667 0.9621 -2.252 0.0264 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.462 on 104 degrees of freedom
## Multiple R-squared: 0.09167, Adjusted R-squared: 0.05673
## F-statistic: 2.624 on 4 and 104 DF, p-value: 0.03888
Łatwo możemy odczytać z tabeli, że statystycznie istotne są różnice między poziomami 4 a 3 (wzrost dla “Often” w porównaniu do “Sometimes”) oraz między poziomami 5 i 4 (spadek dla “Very often” w porównaniu do “Often”).