require(tidyverse)
require(dplyr)
require(DT)
require(kableExtra)
require(captioner)
require(interactions)
require(jtools)
require(car)
dados fictícios: https://www.scribbr.com/statistics/anova-in-r/
dados=read.csv("crop.data.csv")
dados = dados %>%
mutate(fertilizer=as.factor(fertilizer),
density=as.factor(density),
ind=as.factor(seq(1,nrow(dados),1)))
Descritivas
descritivas=dados %>%
group_by(fertilizer,density) %>%
summarise(media=mean(yield),sd=sd(yield),n=n())
## `summarise()` regrouping output by 'fertilizer' (override with `.groups` argument)
tab_nums=captioner(prefix="Tabela")
cap=tab_nums("tab1","Estatíticas descritivas")
datatable(descritivas,caption=cap)
One Way Anova: Fertilizante influencia na produção?
y_grupos=dados %>%
group_by(fertilizer) %>%
summarise(media=mean(yield),var=var(yield),n=n())
## `summarise()` ungrouping output (override with `.groups` argument)
cap=tab_nums("tab2","Descritivas por tipo de fertilizante")
datatable(y_grupos,cap=cap)
dados %>%
ggplot(aes(x=fertilizer,y=yield,fill=fertilizer)) +
geom_boxplot()
Figura 1: Boxplot de produção por tipos de fertilizante
one.way <- aov(yield ~ fertilizer, data = dados)
summary(one.way)
## Df Sum Sq Mean Sq F value Pr(>F)
## fertilizer 2 6.07 3.0340 7.863 7e-04 ***
## Residuals 93 35.89 0.3859
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Os pressupostos da Anova foram atendidos?
par(mfrow=c(2,2))
plot(one.way)
Figura 2: Gráficos de diagnóstico Anova
par(mfrow=c(1,1))
shapiro.test(one.way$residuals)
##
## Shapiro-Wilk normality test
##
## data: one.way$residuals
## W = 0.99088, p-value = 0.7594
Mas e sobre as somas de quadrados? Como são calculadas?
tabela <- data.frame(
col1 = c("Fonte de Variação","Entre Grupos (Fator A)","Dentro dos Grupos (Erro)","Total"),
col2 = c("Soma de Quadrados","SQA","SQE","SQT"),
col3 = c("Graus de liberdade","k-1","N-k","N-1"),
col4 = c("Quadrados médios","QMA=$\\frac{SQA}{k-1}$","QME=$\\frac{SQE}{N-k}$",""),
col5 = c("Estatística F","$F=\\frac{QMA}{QME}$","",""),
col6 = c("Valor-p","àrea sob a curva à direita de F","",""))
cap=tab_nums("tab3","Tabela Anova")
tabela %>%
kbl(caption=cap,col.names = NULL,escape = FALSE) %>%
kable_classic(full_width = F, html_font = "Cambria") %>%
kable_styling(bootstrap_options = c("striped","hold_position"),
full_width = F)
Fonte de Variação | Soma de Quadrados | Graus de liberdade | Quadrados médios | Estatística F | Valor-p |
Entre Grupos (Fator A) | SQA | k-1 | QMA=\(\frac{SQA}{k-1}\) | \(F=\frac{QMA}{QME}\) | àrea sob a curva à direita de F |
Dentro dos Grupos (Erro) | SQE | N-k | QME=\(\frac{SQE}{N-k}\) | ||
Total | SQT | N-1 |
onde \[ \begin{array}{l} SQA = \sum_{i=1}^k \sum_{j=1}^{n_i} (\bar{y}_{i.}-\bar{y}_{..})^2\\ SQE = \sum_{i=1}^k \sum_{j=1}^{n_i} (y_{ij}-\bar{y}_{i.})^2 \text{ ou também: } =\sum_{i=1}^k (n_i-1) s_i^2 \\ SQT = \sum_{i=1}^k \sum_{j=1}^{n_i} (y_{ij}-\bar{y}_{..})^2, \text{ ou também: }=SQA + SQE \end{array} \] Interpretação:
Aplicação: Cálculos das somas de quadrados e estatística do Teste.
k=3
N=96
y = dados$yield
y_bar = mean(dados$yield)
y_grupos=dados %>%
group_by(fertilizer) %>%
summarise(media=mean(yield),var=var(yield),n=n())
## `summarise()` ungrouping output (override with `.groups` argument)
SQA = sum(y_grupos$n*(y_grupos$media-y_bar)^2)
SQE = sum((y_grupos$n-1)*y_grupos$var)
SQT = SQA + SQE
QMA = SQA/(k-1)
QME = SQE/(N-k)
F = QMA/QME
tabela <- data.frame(
col1 = c("Fonte de Variação","Entre Grupos (Fator A)","Dentro dos Grupos (Erro)","Total"),
col2 = c("Soma de Quadrados",round(SQA,4),round(SQE,4),round(SQT,4)),
col3 = c("Graus de liberdade",k-1,N-k,N-1),
col4 =
c("Quadrados médios",round(SQA/(k-1),4),round(SQE/(N-k),4),""),
col5 = c("Estatística F",round(QMA/QME,4),"",""),
col6 = c("Valor-p",round(1-pf(F,k-1,N-k),4),"",""))
cap=tab_nums("tab4","Tabela Anova - aplicação")
tabela %>%
kbl(caption=cap,col.names = NULL,escape = FALSE) %>%
kable_classic(full_width = F, html_font = "Cambria") %>%
kable_styling(bootstrap_options = c("striped","hold_position"),
full_width = F)
Fonte de Variação | Soma de Quadrados | Graus de liberdade | Quadrados médios | Estatística F | Valor-p |
Entre Grupos (Fator A) | 6.068 | 2 | 3.034 | 7.8628 | 7e-04 |
Dentro dos Grupos (Erro) | 35.8862 | 93 | 0.3859 | ||
Total | 41.9542 | 95 |
Post-hoc tests: Teste de Tukey para comparação de médias:
tukey.one.way<-TukeyHSD(one.way)
tukey.one.way
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = yield ~ fertilizer, data = dados)
##
## $fertilizer
## diff lwr upr p adj
## 2-1 0.1761687 -0.19371896 0.5460564 0.4954705
## 3-1 0.5991256 0.22923789 0.9690133 0.0006125
## 3-2 0.4229569 0.05306916 0.7928445 0.0208735
Anova & modelo de regressão linear: Linear model
Alternativamente, podemos escrever o modelo de regressão na seguinte forma: \[ y_j = \left\{ \begin{array}{lll} \underbrace{\bar{x}_{1.}}_{\beta_1: \text{ média do grupo 1}} + \epsilon_j, \text{ se foi aplicado o fertilizante 1},\\ \underbrace{\bar{x}_{2.}}_{\beta_1 + \beta_2: \text{ média do grupo 2}} + \epsilon_j, \text{ se foi aplicado o fertilizante 2},\\ \underbrace{\bar{x}_{3.}}_{\beta_1 + \beta_3: \text{ média do grupo 3}} + \epsilon_j, \text{ se foi aplicado o fertilizante 3}, \end{array} \right. \]
model.1=lm(yield ~ fertilizer,data=dados)
summary(model.1)
##
## Call:
## lm(formula = yield ~ fertilizer, data = dados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.39620 -0.45303 0.02268 0.41076 1.70473
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 176.7570 0.1098 1609.643 < 2e-16 ***
## fertilizer2 0.1762 0.1553 1.134 0.259542
## fertilizer3 0.5991 0.1553 3.858 0.000211 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6212 on 93 degrees of freedom
## Multiple R-squared: 0.1446, Adjusted R-squared: 0.1262
## F-statistic: 7.863 on 2 and 93 DF, p-value: 0.0006999
Interpretação Gráfica: Modelo linear com somente 1 variável categórica
dados1 = dados %>%
mutate(predito=model.1$fitted.values)
cat_plot(model.1, pred = fertilizer, geom = "line")
## Warning: fertilizer are not included in an interaction with one another in the
## model.
dados1 %>%
ggplot(aes(fertilizer,yield))+
geom_point()+
geom_point(mapping=aes(fertilizer,predito),color="red")
Figura 3: Gráfico de pontos dos valores observados e preditos por grupo
dados fictícios: https://www.scribbr.com/statistics/anova-in-r/
Two Way Anova: Fertilizante e densidade influenciam na produção?
y_grupos=dados %>%
group_by(fertilizer,density) %>%
summarise(media=mean(yield),var=var(yield),n=n())
## `summarise()` regrouping output by 'fertilizer' (override with `.groups` argument)
cap=tab_nums("tab5","Descritivas por tipo de fertilizante e densidade")
datatable(y_grupos,cap=cap)
dados %>%
ggplot(aes(x=fertilizer,y=yield,fill=density)) +
geom_boxplot() +
facet_wrap(vars(density),nrow=3)
Figura 4: Boxplots de produção por tipos de fertilizante e densidade
dados %>%
ggplot(aes(x=density,y=yield,fill=fertilizer)) +
geom_boxplot() +
facet_wrap(vars(fertilizer),nrow=3)
O gráfico de interação:
interaction.plot(x.factor = dados$density,
trace.factor = dados$fertilizer,
response = dados$yield,
fun = mean,
type="b",
col=c("black","red","green"), ### Colors for levels of trace var.
pch=c(19, 17, 15), ### Symbols for levels of trace var.
fixed=TRUE, ### Order by factor order in data
leg.bty = "o",
ylab="Produção",
xlab="Densidade")
- Pela tabela ANOVA verificamos a interação entre fertilizante e densidade não é significativa (ao nível de 5%).
two.way <- aov(yield ~ density*fertilizer, data = dados)
summary(two.way)
## Df Sum Sq Mean Sq F value Pr(>F)
## density 1 5.122 5.122 15.195 0.000186 ***
## fertilizer 2 6.068 3.034 9.001 0.000273 ***
## density:fertilizer 2 0.428 0.214 0.635 0.532500
## Residuals 90 30.337 0.337
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Os pressupostos da Anova foram atendidos?
par(mfrow=c(2,2))
plot(two.way)
par(mfrow=c(1,1))
shapiro.test(two.way$residuals)
##
## Shapiro-Wilk normality test
##
## data: two.way$residuals
## W = 0.98527, p-value = 0.3601
Post-hoc tests: Teste de Tukey para comparação de médias:
tukey.two.way<-TukeyHSD(two.way)
tukey.two.way
## Tukey multiple comparisons of means
## 95% family-wise confidence level
##
## Fit: aov(formula = yield ~ density * fertilizer, data = dados)
##
## $density
## diff lwr upr p adj
## 2-1 0.461956 0.2265141 0.697398 0.0001864
##
## $fertilizer
## diff lwr upr p adj
## 2-1 0.1761687 -0.16972711 0.5220646 0.4482026
## 3-1 0.5991256 0.25322974 0.9450214 0.0002393
## 3-2 0.4229569 0.07706102 0.7688527 0.0123951
##
## $`density:fertilizer`
## diff lwr upr p adj
## 2:1-1:1 0.63489351 0.03715141 1.2326356 0.0306553
## 1:2-1:1 0.33868995 -0.25905215 0.9364320 0.5680611
## 2:2-1:1 0.64854101 0.05079891 1.2462831 0.0254221
## 1:3-1:1 0.69601055 0.09826845 1.2937526 0.0128711
## 2:3-1:1 1.13713411 0.53939201 1.7348762 0.0000044
## 1:2-2:1 -0.29620356 -0.89394566 0.3015385 0.7007889
## 2:2-2:1 0.01364750 -0.58409459 0.6113896 0.9999998
## 1:3-2:1 0.06111704 -0.53662505 0.6588591 0.9996758
## 2:3-2:1 0.50224060 -0.09550149 1.0999827 0.1515870
## 2:2-1:2 0.30985106 -0.28789103 0.9075932 0.6591096
## 1:3-1:2 0.35732060 -0.24042149 0.9550627 0.5089535
## 2:3-1:2 0.79844416 0.20070206 1.3961863 0.0025700
## 1:3-2:2 0.04746954 -0.55027256 0.6452116 0.9999065
## 2:3-2:2 0.48859310 -0.10914900 1.0863352 0.1742960
## 2:3-1:3 0.44112356 -0.15661854 1.0388657 0.2721714
Anova & modelo de regressão linear: Linear model
model.2=lm(yield ~ fertilizer + density + fertilizer*density,data=dados)
summary(model.2)
##
## Call:
## lm(formula = yield ~ fertilizer + density + fertilizer * density,
## data = dados)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.1917 -0.3338 -0.0402 0.3497 1.4842
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 176.4396 0.1451 1215.607 < 2e-16 ***
## fertilizer2 0.3387 0.2053 1.650 0.10243
## fertilizer3 0.6960 0.2053 3.391 0.00104 **
## density2 0.6349 0.2053 3.093 0.00264 **
## fertilizer2:density2 -0.3250 0.2903 -1.120 0.26581
## fertilizer3:density2 -0.1938 0.2903 -0.668 0.50616
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.5806 on 90 degrees of freedom
## Multiple R-squared: 0.2769, Adjusted R-squared: 0.2367
## F-statistic: 6.893 on 5 and 90 DF, p-value: 1.728e-05
anova(model.2)
## Analysis of Variance Table
##
## Response: yield
## Df Sum Sq Mean Sq F value Pr(>F)
## fertilizer 2 6.0680 3.0340 9.0011 0.0002732 ***
## density 1 5.1217 5.1217 15.1945 0.0001864 ***
## fertilizer:density 2 0.4278 0.2139 0.6346 0.5325001
## Residuals 90 30.3367 0.3371
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
dados fictícios: https://rcompanion.org/handbook/G_09.html
Input =("
Diet Country Weight_change
A USA 0.120
A USA 0.125
A USA 0.112
A UK 0.052
A UK 0.055
A UK 0.044
B USA 0.096
B USA 0.100
B USA 0.089
B UK 0.025
B UK 0.029
B UK 0.019
C USA 0.149
C USA 0.150
C USA 0.142
C UK 0.077
C UK 0.080
C UK 0.066
")
dados2 = read.table(textConnection(Input),header=TRUE)
datatable(dados2)
Two Way Anova: Dieta e país de origem influenciam no ganho de peso?
dados2_grupos=dados2 %>%
group_by(Diet,Country) %>%
summarise(media=mean(Weight_change),var=var(Weight_change),n=n())
## `summarise()` regrouping output by 'Diet' (override with `.groups` argument)
cap=tab_nums("tab6","Descritivas por tipo de dieta e país de origem")
datatable(dados2_grupos,cap=cap)
Gráfico de interação: Já vamos direto para este gráfico que mostra a relação entre as duas variáveis na interação.
interaction.plot(x.factor = dados2$Country,
trace.factor = dados2$Diet,
response = dados2$Weight_change,
fun = mean,
type="b",
col=c("black","red","green"), ### Colors for levels of trace var.
pch=c(19, 17, 15), ### Symbols for levels of trace var.
fixed=TRUE, ### Order by factor order in data
leg.bty = "o",
ylab="weight change",
xlab="Diet")
- Pela tabela ANOVA verificamos a interação entre país de origem e tipo de dieta não é significativa (ao nível de 5%); - O tipo de dieta e o país de origem são significativos.
two.way.2 <- aov(Weight_change ~ Diet*Country, data = dados2)
summary(two.way.2)
## Df Sum Sq Mean Sq F value Pr(>F)
## Diet 2 0.007804 0.003902 114.205 1.55e-08 ***
## Country 1 0.022472 0.022472 657.717 7.52e-12 ***
## Diet:Country 2 0.000012 0.000006 0.176 0.841
## Residuals 12 0.000410 0.000034
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Os pressupostos da Anova foram atendidos?
Diagnóstico
par(mfrow=c(2,2))
plot(two.way.2,1:2)
#par(mfrow=c(1,1))
shapiro.test(two.way.2$residuals)
##
## Shapiro-Wilk normality test
##
## data: two.way.2$residuals
## W = 0.87589, p-value = 0.02228
Alternativas:
Transformação de Box Cox;
Testes não paramétricos.
Pela transformação de Box-Cox, o valor de \(\lambda=1\) - significa que a variável resposta em sua forma transformada será:
\[ Y^t = \frac{Y^1-1}{1}= Y-1, \text{ diferindo de Y apenas de uma constante, então não fará diferença da variável original} \]
boxCox(two.way.2)
Curiosidades: Teste para homogeneidade dos resíduos em um modelo linear:
library(lmtest)
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
bptest(two.way.2)
##
## studentized Breusch-Pagan test
##
## data: two.way.2
## BP = 3.08, df = 5, p-value = 0.6877
Verificar outras alterativas como transformação potência Utilizada em modelos lineares, disponível no pacote car (Companion to Applied Regression).