Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
mpaer
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Harbor Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Walmes Marques Zeviani
mpaer
Commits
78d12f28
"calculadora/calc" did not exist on "0b742219443a364b362de8f17aa1b7518d4da528"
Commit
78d12f28
authored
5 years ago
by
Walmes Marques Zeviani
Browse files
Options
Downloads
Patches
Plain Diff
Improves code in Latin Square Designs.
parent
91c29b64
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
04-dql.Rmd
+167
-23
167 additions, 23 deletions
04-dql.Rmd
with
167 additions
and
23 deletions
04-dql.Rmd
+
167
−
23
View file @
78d12f28
...
@@ -29,11 +29,11 @@ knitr::include_graphics("./img/quadrado-latino-drone.png")
...
@@ -29,11 +29,11 @@ knitr::include_graphics("./img/quadrado-latino-drone.png")
rm(list = objects())
rm(list = objects())
# Carrega pacotes.
# Carrega pacotes.
library(agricolae) # HSD.test()
library(agricolae) # HSD.test()
.
library(car) # linearHypothesis(), Anova()
library(car) # linearHypothesis(), Anova()
.
library(multcomp) # glht()
library(multcomp) # glht()
.
library(emmeans) # emmeans()
library(emmeans) # emmeans()
.
library(tidyverse)
library(tidyverse)
# Manipulação e visualização de dados.
# Carrega funções.
# Carrega funções.
source("mpaer_functions.R")
source("mpaer_functions.R")
...
@@ -46,8 +46,12 @@ da <- labestData::PimentelEg6.2
...
@@ -46,8 +46,12 @@ da <- labestData::PimentelEg6.2
str(da)
str(da)
# Vendo o quadrado no plano.
# Vendo o quadrado no plano.
reshape2::dcast(da, linha ~ coluna, value.var = "varied")
da %>%
reshape2::dcast(da, linha ~ coluna, value.var = "prod")
select(linha, coluna, varied) %>%
spread(key = coluna, value = varied)
da %>%
select(linha, coluna, prod) %>%
spread(key = coluna, value = prod)
# Tem registros perdidos?
# Tem registros perdidos?
sum(is.na(da$prod))
sum(is.na(da$prod))
...
@@ -101,8 +105,9 @@ gridExtra::grid.arrange(
...
@@ -101,8 +105,9 @@ gridExtra::grid.arrange(
O modelo estatístico para esse experimento é
O modelo estatístico para esse experimento é
$$
$$
\begin{aligned}
\begin{aligned}
Y|i, j, k &\sim \text{Normal}(\mu_{ijk}, \sigma^2) \\
Y_{ijk} &\sim \text{Normal}(\mu_{ijk}, \sigma^2) \\
\mu_{ijk} &= \mu + \alpha_i + \beta_j + \tau_k
\mu_{ijk} &= \mu + \alpha_i + \beta_j + \tau_k \\
\sigma^2 \propto 1
\end{aligned}
\end{aligned}
$$
$$
em que $\alpha_i$ é o efeito da linha $i$, $\beta_j$ é o efeito da
em que $\alpha_i$ é o efeito da linha $i$, $\beta_j$ é o efeito da
...
@@ -112,7 +117,18 @@ mencionados, $\mu_{ijk}$ é a média para as observações de procedência
...
@@ -112,7 +117,18 @@ mencionados, $\mu_{ijk}$ é a média para as observações de procedência
$ijk$ e $\sigma^2$ é a variância das observações ao redor desse valor
$ijk$ e $\sigma^2$ é a variância das observações ao redor desse valor
médio.
médio.
Neste caso, todos os fatores são qualitativos. Por outro lado, se o
fator experimental de interesse fosse quatitativo, como adubação,
poderia-se acomodar o efeito por meio de um polinômio, um modelo não
linear ou qualquer outra função de uma variável real. Geralmente,
procura-se obter uma descrição que utilize menos parâmetros que o número
de níveis do fator.
O código abaixo declara o modelo acima equacionado para que a função
`lm()` estime os parâmetros e compute as demais saídas relevantes.
```{r, fig.height = 7}
```{r, fig.height = 7}
# Ajuste o modelo aos dados.
m0 <- lm(prod ~ linha + coluna + varied, data = da)
m0 <- lm(prod ~ linha + coluna + varied, data = da)
# Diganóstico dos resíduos.
# Diganóstico dos resíduos.
...
@@ -126,8 +142,26 @@ Anova(m0)
...
@@ -126,8 +142,26 @@ Anova(m0)
# Estimativas dos efeitos e medidas de ajuste.
# Estimativas dos efeitos e medidas de ajuste.
summary(m0)
summary(m0)
sprintf("%0.2f", summary(m0)$sigma)/sqrt(4)
2 * summary(m0)$sigma/sqrt(2 * 5)
```
```
O quadro de análise de variância contém evidência para rejeição da
hipótese nula de igualdade entre as variedades de batatinha. Os gráficos
na fase exploratória já antecipavam isso.
O quadro de resumo do ajuste reporta a estimativa do erro padrão
residual `r sprintf("%0.2f", summary(m0)$sigma)` e que os efeitos tem o
mesmo erro-padrão que vale $2 \hat{\sigma}/\sqrt{2r}$. Lembre-se que
esses efeitos são diferenças com relação ao um ponto experimental de
referência que é a varidade A na primeira linha e primeira coluna. Na
realidade, esse ponto experimental não ocorre no experimento mas isso
não impede que sua média seja estimada.
Como as linhas e colunas são fatores experimentais de blocagem,
prefere-se obter as médias marginais das variedades.
```{r}
```{r}
# Comparações múltiplas.
# Comparações múltiplas.
...
@@ -135,11 +169,26 @@ summary(m0)
...
@@ -135,11 +169,26 @@ summary(m0)
emm <- emmeans(m0, specs = ~varied)
emm <- emmeans(m0, specs = ~varied)
emm
emm
# Erro padrão.
summary(m0)$sigma/sqrt(5)
grid <- attr(emm, "grid")
grid <- attr(emm, "grid")
L <- attr(emm, "linfct")
L <- attr(emm, "linfct")
rownames(L) <- grid[[1]]
rownames(L) <- grid[[1]]
MASS::fractions(L)
# Para entender como se calcula as médias marginais.
t(MASS::fractions(L))
# Obtém os constrastes par a par (pairwise). P-valores são ajustados
# pelo método de Tukey.
contrast(emm, method = "pairwise")
# Resumo compacto com letras.
cld(emm)
# Representação gráfica.
pwpp(emm) +
geom_vline(xintercept = 0.05, lty = 2)
# Comparações múltiplas, contrastes de Tukey.
# Comparações múltiplas, contrastes de Tukey.
# Método de correção de p-valor: single-step.
# Método de correção de p-valor: single-step.
...
@@ -150,7 +199,7 @@ tk_sgl
...
@@ -150,7 +199,7 @@ tk_sgl
# Resumo compacto com letras.
# Resumo compacto com letras.
cld(tk_sgl, decreasing = TRUE)
cld(tk_sgl, decreasing = TRUE)
# Teste HSD de Tukey.
# Teste HSD de Tukey
, baseado na amplitude total studentizada
.
tk_hsd <- HSD.test(m0, trt = "varied")
tk_hsd <- HSD.test(m0, trt = "varied")
# Detalhes da aplicação do teste HSD de Tukey.
# Detalhes da aplicação do teste HSD de Tukey.
...
@@ -176,11 +225,41 @@ ggplot(data = results,
...
@@ -176,11 +225,41 @@ ggplot(data = results,
labs(x = "Variedade", y = "Produção")
labs(x = "Variedade", y = "Produção")
```
```
TODO! Colocar teste de Scott Knott.
O teste de Scott-Knott é muito empregado, principalmente por
pesquisadores de agrárias. A preferência parece ser pela "não
abiguidade" nos resultados do teste que não apresenta resultados do tipo
"ab", por exemplo. No entanto, muito dos usuários talvez não saibam que
o teste de Scott-Knott **NÃO** é um teste de comparação múltipla de
pares de médias mas sim um teste de agrupamento (divisivo) de médias. É
muito comum as pessoas cometerem o equívoco de interpretarem o resultado
do teste de Scott-Knott como se fosse um teste de pares de médias.
```{r}
library(ScottKnott)
# Ajustando o modelo com a `aov()` para passar para a `SK()`.
m1 <- aov(formula(m0), data = m0$model)
# Faz o teste de Scott-Knott.
sk <- SK(m1, which = "varied")
summary(sk)
```
Conforme o que foi dito, pelo teste de Scott-Knott, rejeita-se a
hipótese nula de que a média da variedade C seja igual a média do grupo
formado pelas demais variáveis. Não podemos cometer o erro de
interpretar que isso implica na rejeição da hipótese de igualdade entre
as médias da variedade C e A, por exemplo.
O método `summary()` aplicado ao objeto vindo da `SK()` é um data frame
que contém as médias dos tratamentos e as letras para indicar os grupos
formados. Dessa forma é fácil construir gráficos a partir da manipulação
desse objeto.
## Variável resposta de contagem
## Variável resposta de contagem
```{r}
```{r}
# Cria objeto com os dados.
da <- labestData::ZimmermannTb16.10
da <- labestData::ZimmermannTb16.10
str(da)
str(da)
...
@@ -224,7 +303,13 @@ gg2 <-
...
@@ -224,7 +303,13 @@ gg2 <-
gridExtra::grid.arrange(gg1, gg2, nrow = 1)
gridExtra::grid.arrange(gg1, gg2, nrow = 1)
```
```
Apenas com o propósito didático, será mostradado a análise assumindo
distribuição Gaussiana. É comum dados de contagem apresentarem alguma
relação positiva de média-variância o que significa que a suposição de
homocedasticidade não é verificada.
```{r, fig.height = 7}
```{r, fig.height = 7}
# Ajusta o modelo aos dados MAS assumindo uma distribuição normal.
m0 <- lm(colmos ~ linha + coluna + trat,
m0 <- lm(colmos ~ linha + coluna + trat,
data = da)
data = da)
...
@@ -234,11 +319,35 @@ plot(m0)
...
@@ -234,11 +319,35 @@ plot(m0)
layout(1)
layout(1)
```
```
O gráfico Scale-Location indica a relação média-variância comentada. A
normalidade, no então, não mostra afastamento. A transformação Box-Cox
indica que usar o logaritmo da resposta dá mais adesão aos pressupostos
do modelo Gaussiano.
```{r}
```{r}
MASS::boxcox(m0)
MASS::boxcox(m0)
abline(v = 0, col = "red")
abline(v = 0, col = "red")
```
```
Para demonstrar o emprego de uma distribuição mais apropriada para dados
de contagem, será usado a Poisson, ou a especificação Quasi-Poisson.
O modelo estatístico para esse experimento é
$$
\begin{aligned}
y_{ijk} &= \text{Quasi-Poisson}(\lambda_{ijk}, \phi)\\
g(\lambda_{ijk}) &= \mu + \alpha_i + \beta_j + \tau_k \\
\phi \propto 1
\end{aligned}
$$
em que $\lambda_{ijk}$ é a média para a condição experimental $ijk$,
$\alpha_i$ é o efeito da linha $i$, $\beta_j$ é o efeito da coluna $j$ e
$\tau_j$ o efeito dos tratamentos $j$ sobre a variável resposta $Y$,
$\phi$ é o parâmetro de dispersão e $g(.)$ é a função de ligação. A
função de ligação canônica para a Poisson é a logarítmo neperiano.
TODO: qual a diferença da Poisson e da Quasi-Poisson.
```{r, fig.height = 7}
```{r, fig.height = 7}
# Análise com modelo linear generalizado.
# Análise com modelo linear generalizado.
m0 <- glm(colmos ~ linha + coluna + trat,
m0 <- glm(colmos ~ linha + coluna + trat,
...
@@ -260,24 +369,59 @@ summary(m0)
...
@@ -260,24 +369,59 @@ summary(m0)
```
```
```{r}
```{r}
# Comparações múltiplas.
# "Médias" ajustadas na escala do preditor linear.
# Médias marginais ajustadas.
emmeans(m0, specs = ~trat, transform = "response")
# emmeans(m0, specs = ~trat, transform = "unlink") # Igual.
# emmeans(m0, specs = ~trat, transform = "mu") # Igual.
emm <- emmeans(m0, specs = ~trat)
emm <- emmeans(m0, specs = ~trat)
emm
emm
# Passando a inversa da função ligação nas 3 colunas.
emm %>%
emm %>%
as.data.frame() %>%
as.data.frame() %>%
mutate_at(c("emmean", "asymp.LCL", "asymp.UCL"),
mutate_at(c(2, 5, 6), m0$family$linkinv)
m0$family$linkinv)
# DANGER FIXME: o que a `transform = "response"` está fazendo não é
# O resultado já transformado.
# passar o inverso da função de ligação. O que está sendo feito então?
emmeans(m0, specs = ~trat, type = "response")
# Médias amostrais (apenas para verificar).
da %>%
group_by(trat) %>%
summarise_at(vars(colmos), mean)
```
```{r, include = FALSE}
# QUESTION: qual média ajustada é mais correto de usar? Parece que a
# segunda está mais próxima das médias amostrais. Mas como obter o erro
# padrão?
# Na escala da resposta.
emmeans(m0, specs = ~trat, transform = "response")
# QUESTION: como obtém-se o erro padrão?
# Grid com todas as combinações 6 x 6 x 6 = 216.
grid <- da %>%
select(linha, coluna, trat) %>%
complete(linha, coluna, trat)
grid$mu <- predict(m0, newdata = grid, type = "response")
grid <-
bind_cols(grid,
predict(m0,
newdata = grid,
type = "response",
se.fit = TRUE)[1:2] %>%
as_tibble())
str(grid)
grid %>%
group_by(trat) %>%
summarise_at(vars(mu, fit, se.fit), mean)
# DANGER! A diferença está na ordem das operações: i) passar a inversa
# da função de ligação e ii) fazer a agregação ou ii) seguido de i).
```
```{r}
# Desvendando o computo das médias ajustadas.
grid <- attr(emm, "grid")
grid <- attr(emm, "grid")
L <- attr(emm, "linfct")
L <- attr(emm, "linfct")
rownames(L) <- grid[[1]]
rownames(L) <- grid[[1]]
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment