Curso de estatística experimental com aplicações em R |
|
12 à 14 de Novembro de 2014 - Manaus - AM |
Prof. Dr. Walmes M. Zeviani |
Embrapa Amazônia Ocidental |
Lab. de Estatística e Geoinformação - LEG |
Departamento de Estatística - UFPR |
##-----------------------------------------------------------------------------
## Definições da sessão, pacotes a serem usados.
pkg <- c("lattice", "latticeExtra", "doBy", "multcomp", "reshape",
"plyr", "wzRfun")
sapply(pkg, library, character.only=TRUE, logical.return=TRUE)
## lattice latticeExtra doBy multcomp reshape plyr
## TRUE TRUE TRUE TRUE TRUE TRUE
## wzRfun
## TRUE
source("lattice_setup.R")
##-----------------------------------------------------------------------------
## Informações sobre as versões dos pacotes.
sessionInfo()
## R version 3.1.1 (2014-07-10)
## Platform: i686-pc-linux-gnu (32-bit)
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=pt_BR.UTF-8
## [4] LC_COLLATE=en_US.UTF-8 LC_MONETARY=pt_BR.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=pt_BR.UTF-8 LC_NAME=C LC_ADDRESS=C
## [10] LC_TELEPHONE=C LC_MEASUREMENT=pt_BR.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] methods splines stats graphics grDevices utils datasets base
##
## other attached packages:
## [1] wzRfun_0.3 plyr_1.8.1 reshape_0.8.5 multcomp_1.3-7
## [5] TH.data_1.0-3 mvtnorm_0.9-9997 doBy_4.5-11 MASS_7.3-34
## [9] survival_2.37-7 latticeExtra_0.6-26 RColorBrewer_1.0-5 lattice_0.20-29
## [13] rmarkdown_0.3.3 knitr_1.7
##
## loaded via a namespace (and not attached):
## [1] digest_0.6.4 evaluate_0.5.5 formatR_1.0 grid_3.1.1 htmltools_0.2.6
## [6] Matrix_1.1-4 Rcpp_0.11.3 sandwich_2.3-0 stringr_0.6.2 tools_3.1.1
## [11] yaml_2.1.13 zoo_1.7-10
## obs: Para instalar um pacote faça:
## install.packages("nome_do_pacote", dependencies=TRUE)
##-----------------------------------------------------------------------------
## Lendo arquivos de dados.
## Url de um arquivo com dados.
url <- "http://www.leg.ufpr.br/~walmes/data/ancova.txt"
## Importa os dados a partir do arquivo na web.
da <- read.table(file=url, header=TRUE, sep="\t")
## Trunca os nomes para 4 digitos.
names(da) <- substr(names(da), 1, 4)
## Mostra a estrutura do objeto.
str(da)
## 'data.frame': 72 obs. of 8 variables:
## $ ener: Factor w/ 3 levels "alto","baixo",..: 2 2 2 2 2 2 2 2 3 3 ...
## $ sexo: Factor w/ 3 levels "F","MC","MI": 2 2 2 2 2 2 2 2 2 2 ...
## $ rep : int 1 2 3 4 5 6 7 8 1 2 ...
## $ pi : num 93.3 94 91.6 89.3 91.5 93 88.8 93.7 93.9 88.5 ...
## $ id : int 134 137 133 133 144 147 138 142 134 137 ...
## $ pviv: num 127 125 126 119 122 ...
## $ rend: num 82.3 83.1 80.7 82.7 82.9 ...
## $ peso: num 127 125 126 119 122 ...
## Dados de experimento com nutrição de suínos. Animais foram pesados
## antes do experimento e tinham idade conhecida. Essas variáveis
## contínuas foram usadas para explicar/corrigir parte da variação
## presente e melhor comparar os níveis de energia na ração fornecidos.
##-----------------------------------------------------------------------------
## Análise exploratória.
## Gráficos, distribuição das id e pi nos grupos formados pelos fatores
## categóricos.
## xyplot(pi~id|sexo, groups=energia, data=da, auto.key=TRUE)
## xyplot(pi~id|energia, groups=sexo, data=da, auto.key=TRUE)
##-----------------------------------------------------------------------------
## Pode-se fazer uma anova dessas covariáveis para verificar se elas são
## separadas ou confundidas com os fatores experimentais. Como as
## variáveis são medidas antes do inicio do experimento e assumindo que
## os animais são aleatóriamente designinados aos níveis de energia,
## espera-se resultado não significativo.
## Testa se pi é separada por sexo*energia.
anova(lm(pi~sexo*ener, data=da))
## Analysis of Variance Table
##
## Response: pi
## Df Sum Sq Mean Sq F value Pr(>F)
## sexo 2 1.93 0.9654 0.1541 0.8575
## ener 2 0.84 0.4204 0.0671 0.9352
## sexo:ener 4 2.38 0.5958 0.0951 0.9837
## Residuals 63 394.75 6.2658
## Testa se id é separada por sexo*energia.
anova(lm(id~sexo*ener, data=da))
## Analysis of Variance Table
##
## Response: id
## Df Sum Sq Mean Sq F value Pr(>F)
## sexo 2 89.36 44.681 1.4778 0.2359
## ener 2 38.11 19.056 0.6303 0.5358
## sexo:ener 4 86.89 21.722 0.7185 0.5825
## Residuals 63 1904.75 30.234
## Não significativo é o resultado esperado se os tratamentos foram
## casualizados aos animais.
\[ \begin{aligned} Y|\text{fontes de variação} &\,\sim \text{Normal}(\mu_{ij}, \sigma^2) \newline \mu_{ij} &= \mu+\alpha_i+\tau_j+\gamma_{ij} \end{aligned} \]
em que \(\alpha\) é o efeito dos níveis de sexo \(i\), \(\tau_j\) o efeito dos níveis de energia (Kcal) na dieta \(j\), \(gamma_{ij}\) representa a interação . \(\mu\) é a média de \(Y\) na ausência do efeito dos termos mencioandos. \(\mu_{ij}\) é a média para as observações na combinação \(ij\) e \(\sigma^2\) é a variância das observações ao redor desse valor médio. No modelo de análise de covariância, os valores de peso inicial e idade serão usados para explicar parte da variação ao final do experimento. Sendo assim, o modelo considerando o efeito dessas variáveis é representado por
\[ \begin{aligned} Y|\text{fontes de variação} &\,\sim \text{Normal}(\mu+\beta_1 x+\beta_2 z+\mu_{ij}, \sigma^2) \newline \mu_{ij} &= \alpha_i+\tau_j+\gamma_{ij} \end{aligned} \]
em que \(\beta_1\) representa o efeito da covariável peso (\(x\)) expresso por um coeficiente angular e \(\beta_2\) o mesmo para o efeito da covariável idade inicial (\(z\)).
##-----------------------------------------------------------------------------
## Especificação dos modelos.
## A análise dos resíduos será conduzida depois. Será verificado
## primeiro o efeito da ordem dos termos.
## Só com as fontes de variação de interesse.
m0 <- lm(peso~sexo*ener, data=da)
anova(m0)
## Analysis of Variance Table
##
## Response: peso
## Df Sum Sq Mean Sq F value Pr(>F)
## sexo 2 199.81 99.903 3.6153 0.03263 *
## ener 2 55.84 27.921 1.0104 0.36990
## sexo:ener 4 35.38 8.846 0.3201 0.86348
## Residuals 63 1740.92 27.634
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Análise de variância (em experimentos não ortogonais a ordem dos
## termos é importante!).
m1 <- lm(peso~pi+id+sexo*ener, data=da)
anova(m1)
## Analysis of Variance Table
##
## Response: peso
## Df Sum Sq Mean Sq F value Pr(>F)
## pi 1 595.58 595.58 32.1128 4.209e-07 ***
## id 1 47.23 47.23 2.5464 0.11571
## sexo 2 156.97 78.48 4.2318 0.01901 *
## ener 2 66.46 33.23 1.7918 0.17531
## sexo:ener 4 34.38 8.59 0.4634 0.76228
## Residuals 61 1131.33 18.55
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Ocorre redução na SQ pois parte da varição é explicada por pi e id.
## Troca ordem de entrada apenas por curiosidade.
m1 <- lm(peso~id+pi+sexo*ener, data=da)
anova(m1)
## Analysis of Variance Table
##
## Response: peso
## Df Sum Sq Mean Sq F value Pr(>F)
## id 1 5.17 5.17 0.2789 0.59937
## pi 1 637.63 637.63 34.3803 1.98e-07 ***
## sexo 2 156.97 78.48 4.2318 0.01901 *
## ener 2 66.46 33.23 1.7918 0.17531
## sexo:ener 4 34.38 8.59 0.4634 0.76228
## Residuals 61 1131.33 18.55
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## Testa o poder de explicação dos "blocos" contínuos, termos extras.
anova(m0, m1)
## Analysis of Variance Table
##
## Model 1: peso ~ sexo * ener
## Model 2: peso ~ id + pi + sexo * ener
## Res.Df RSS Df Sum of Sq F Pr(>F)
## 1 63 1740.9
## 2 61 1131.3 2 609.59 16.434 1.953e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##-----------------------------------------------------------------------------
## Avaliação dos pressupostos.
par(mfrow=c(2,2)); plot(m1); layout(1)
## Medidas de influência para as observações.
im <- influence.measures(m1)
summary(im)
## Potentially influential observations of
## lm(formula = peso ~ id + pi + sexo * ener, data = da) :
##
## dfb.1_ dfb.id dfb.pi dfb.sxMC dfb.sxMI dfb.enrb dfb.enrm dfb.sxMC:nrb dfb.sxMI:nrb
## 25 -0.60 -0.42 0.95 -0.04 0.00 -0.02 0.02 0.05 0.68
## 37 -0.20 0.96 -0.43 0.07 0.00 0.01 -0.04 -0.04 0.09
## 46 0.40 -0.57 -0.05 -0.04 -0.82 0.00 0.02 0.01 0.53
## 48 0.28 0.30 -0.52 0.03 0.81 0.01 -0.01 -0.03 -0.54
## dfb.sxMC:nrm dfb.sxMI:nrm dffit cov.r cook.d hat
## 25 -0.01 -0.06 1.76_* 0.15_* 0.23 0.18
## 37 0.12 -0.43 -1.48_* 0.44_* 0.18 0.23
## 46 -0.09 0.51 -1.30_* 0.30_* 0.14 0.16
## 48 0.02 -0.53 1.27 0.31_* 0.13 0.15
r <- which(im$is.inf[,"dffit"])
m2 <- lm(peso~id+pi+sexo*ener, data=da[-r,])
anova(m2)
## Analysis of Variance Table
##
## Response: peso
## Df Sum Sq Mean Sq F value Pr(>F)
## id 1 0.40 0.40 0.0341 0.854171
## pi 1 459.25 459.25 39.3607 4.8e-08 ***
## sexo 2 177.89 88.94 7.6230 0.001150 **
## ener 2 144.97 72.49 6.2125 0.003592 **
## sexo:ener 4 66.83 16.71 1.4319 0.234964
## Residuals 58 676.73 11.67
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
par(mfrow=c(2,2)); plot(m2); layout(1)
##-----------------------------------------------------------------------------
## Comparações múltiplas para o desdobramento.
LSmeans(m2, effect=c("sexo","ener"))
## estimate se df t.stat p.value lwr upr sexo ener id
## 1 126.9699 1.211308 58 104.82046 8.066598e-68 124.5452 129.3946 F alto 138.0145
## 2 124.9146 1.209095 58 103.31250 1.861161e-67 122.4944 127.3349 MC alto 138.0145
## 3 129.7600 1.291111 58 100.50258 9.132251e-67 127.1755 132.3444 MI alto 138.0145
## 4 122.7648 1.211616 58 101.32318 5.713283e-67 120.3395 125.1901 F baixo 138.0145
## 5 124.0100 1.208737 58 102.59473 2.782637e-67 121.5905 126.4296 MC baixo 138.0145
## 6 124.5507 1.293884 58 96.26108 1.097349e-65 121.9607 127.1406 MI baixo 138.0145
## 7 125.6840 1.219403 58 103.07010 2.131268e-67 123.2431 128.1249 F medio 138.0145
## 8 123.9038 1.251383 58 99.01350 2.159913e-66 121.3989 126.4087 MC medio 138.0145
## 9 130.0355 1.291530 58 100.68331 8.233295e-67 127.4503 132.6208 MI medio 138.0145
## pi
## 1 92.0087
## 2 92.0087
## 3 92.0087
## 4 92.0087
## 5 92.0087
## 6 92.0087
## 7 92.0087
## 8 92.0087
## 9 92.0087
LSmeans(m2, effect=c("sexo"))
## estimate se df t.stat p.value lwr upr sexo id pi
## 1 125.1396 0.7071868 58 176.9540 5.740376e-81 123.7240 126.5552 F 138.0145 92.0087
## 2 124.2761 0.7048357 58 176.3193 7.067888e-81 122.8653 125.6870 MC 138.0145 92.0087
## 3 128.1154 0.7456101 58 171.8262 3.149698e-80 126.6229 129.6079 MI 138.0145 92.0087
LSmeans(m2, effect=c("ener"))
## estimate se df t.stat p.value lwr upr ener id pi
## 1 127.2148 0.7141424 58 178.1365 3.903753e-81 125.7853 128.6443 alto 138.0145 92.0087
## 2 123.7752 0.7138463 58 173.3919 1.863060e-80 122.3462 125.2041 baixo 138.0145 92.0087
## 3 126.5411 0.7149777 58 176.9861 5.680494e-81 125.1099 127.9723 medio 138.0145 92.0087
X <- LSmatrix(m2, effect=c("sexo"))
rownames(X) <- levels(da$sexo)
ps <- apmc(X, model=m2, focus="sexo", test="fdr")
ps
## sexo estimate lwr upr cld
## 1 F 125.1396 123.7240 126.5552 b
## 2 MC 124.2761 122.8653 125.6870 b
## 3 MI 128.1154 126.6229 129.6079 a
X <- LSmatrix(m2, effect=c("ener"))
rownames(X) <- levels(da$ener)
pe <- apmc(X, model=m2, focus="ener", test="fdr")
pe$ener <- factor(pe$ener, levels=c("alto","medio","baixo"),
labels=c("Alto","Médio","Baixo"))
pe <- arrange(pe, ener)
pe
## ener estimate lwr upr cld
## 1 Alto 127.2148 125.7853 128.6443 a
## 2 Médio 126.5411 125.1099 127.9723 a
## 3 Baixo 123.7752 122.3462 125.2041 b
## names(ps)[1] <- names(pe)[1] <- "nivel"
## p0 <- cbind(rbind(ps, pe), fator=rep(c("sexo","ener"), each=3))
## dput(levels(p0$nivel))
## str(p0)
##-----------------------------------------------------------------------------
## Representação gráfica dos resultados.
xlab <- expression("Peso aos 28 dias"~(kg))
sub <- list(
"Médias seguidas de mesma letra indicam diferença nula à 5%.",
font=1, cex=0.8)
p1 <-
segplot(sexo~lwr+upr, centers=estimate,
data=ps, draw=FALSE,
ylab="Nível de sexo", xlab=xlab, sub=sub,
letras=sprintf("%0.2f %s", ps$estimate, ps$cld),
panel=function(x, y, z, subscripts, centers, letras, ...){
panel.segplot(x=x, y=y, z=z, centers=centers,
subscripts=subscripts, ...)
panel.text(y=as.numeric(z)[subscripts],
x=centers[subscripts],
label=letras[subscripts], pos=3)
})
p2 <-
segplot(ener~lwr+upr, centers=estimate,
data=pe, draw=FALSE,
ylab="Nível de energia da dieta", xlab=xlab, sub=sub,
letras=sprintf("%0.2f %s", pe$estimate, pe$cld),
panel=function(x, y, z, subscripts, centers, letras, ...){
panel.segplot(x=x, y=y, z=z, centers=centers,
subscripts=subscripts, ...)
panel.text(y=as.numeric(z)[subscripts],
x=centers[subscripts],
label=letras[subscripts], pos=3)
})
## Gráfico final.
plot(p1, split=c(1,1,2,1), more=TRUE)
plot(p2, split=c(2,1,2,1), more=FALSE)
##-----------------------------------------------------------------------------
## Como fica o resultado sem usar as covariáveis?
mean(da$pi); mean(da$id)
## [1] 92.11667
## [1] 137.8889
X <- LSmatrix(m0, effect=c("sexo"), at=list(pi=92, id=138))
rownames(X) <- levels(da$sexo)
ps0 <- apmc(X, model=m0, focus="sexo", test="fdr")
ps0
## sexo estimate lwr upr cld
## 1 F 125.1167 122.9724 127.2610 ab
## 2 MC 124.3250 122.1807 126.4693 b
## 3 MI 128.1875 126.0432 130.3318 a
X <- LSmatrix(m1, effect=c("sexo"), at=list(pi=92, id=138))
rownames(X) <- levels(da$sexo)
ps1 <- apmc(X, model=m1, focus="sexo", test="fdr")
ps1
## sexo estimate lwr upr cld
## 1 F 125.1306 123.3506 126.9106 ab
## 2 MC 124.2653 122.4914 126.0392 b
## 3 MI 127.7405 125.9733 129.5076 a
X <- LSmatrix(m2, effect=c("sexo"), at=list(pi=92, id=138))
rownames(X) <- levels(da$sexo)
ps2 <- apmc(X, model=m2, focus="sexo", test="fdr")
ps2
## sexo estimate lwr upr cld
## 1 F 125.1316 123.7156 126.5476 b
## 2 MC 124.2682 122.8576 125.6787 b
## 3 MI 128.1074 126.6150 129.5999 a
ps0$model <- "0"; ps1$model <- "1"; ps2$model <- "2"
ps <- rbind(ps0, ps1, ps2)
ps$model <- factor(ps$model)
str(ps)
## 'data.frame': 9 obs. of 6 variables:
## $ sexo : Factor w/ 3 levels "F","MC","MI": 1 2 3 1 2 3 1 2 3
## $ estimate: num 125 124 128 125 124 ...
## $ lwr : num 123 122 126 123 122 ...
## $ upr : num 127 126 130 127 126 ...
## $ cld : chr "ab" "b" "a" "ab" ...
## $ model : Factor w/ 3 levels "0","1","2": 1 1 1 2 2 2 3 3 3
l <- c("Fatorial", "Ancova", "Limpo")
key <- list(title="Modelo", cex.title=1.1,
corner=c(0.05,0.95), type="o", divide=1,
text=list(l), lines=list(pch=1:length(l)))
segplot(sexo~lwr+upr, centers=estimate,
data=ps, groups=model, draw=FALSE,
ylab="Nível de sexo", xlab=xlab, sub=sub, key=key,
panel=panel.segplotBy, f=0.075, pch=as.integer(ps$model))