Importação e preparo dos dados
#-----------------------------------------------------------------------
# Pacotes.
rm(list = objects())
library(tidyverse)
library(survival)
library(emmeans)
# Será usada a `ordered_cld()`.
url <- "https://raw.githubusercontent.com/walmes/wzRfun/master/R/pairwise.R"
source(url)
#-----------------------------------------------------------------------
# Importação e preparação.
# Leitura.
da <- read_tsv("frutosmaduros.txt")
attr(da, "spec") <- NULL
str(da)
## Classes 'spec_tbl_df', 'tbl_df', 'tbl' and 'data.frame': 3000 obs. of 5 variables:
## $ spp : chr "Ch" "Ch" "Ch" "Ch" ...
## $ day : num 1 1 1 1 1 1 1 1 1 1 ...
## $ trat : chr "test" "test" "test" "test" ...
## $ rep : num 1 2 3 4 5 6 7 8 9 10 ...
## $ incid: num 0 0 0 0 0 0 0 0 0 0 ...
# Tabela de frequência cruzada.
xtabs(~spp + trat, data = da)
## trat
## spp amistar top mythos nativo recop score test
## Cf 250 250 250 250 250 250
## Ch 250 250 250 250 250 250
# Existe NA em algum lugar?
u <- !complete.cases(da)
sum(u)
## [1] 1
da[u, ]
## # A tibble: 1 x 5
## spp day trat rep incid
## <chr> <dbl> <chr> <dbl> <dbl>
## 1 Ch 10 mythos 21 NA
# Substitui o NA por censura a direita.
da <- da %>%
replace_na(replace = list(incid = 0))
# Cria fatores.
da <- da %>%
mutate(trat = factor(trat),
spp = factor(spp),
ue = interaction(trat, spp, rep))
# A tabela contém o registro dia após dia de cada unidade
# experimental. O evento ocorre quando o variável `incid` troca de valor
# 0 para 1.
da %>%
filter(ue == levels(ue)[1])
## # A tibble: 10 x 6
## spp day trat rep incid ue
## <fct> <dbl> <fct> <dbl> <dbl> <fct>
## 1 Cf 1 amistar top 1 0 amistar top.Cf.1
## 2 Cf 2 amistar top 1 0 amistar top.Cf.1
## 3 Cf 3 amistar top 1 0 amistar top.Cf.1
## 4 Cf 4 amistar top 1 1 amistar top.Cf.1
## 5 Cf 5 amistar top 1 1 amistar top.Cf.1
## 6 Cf 6 amistar top 1 1 amistar top.Cf.1
## 7 Cf 7 amistar top 1 1 amistar top.Cf.1
## 8 Cf 8 amistar top 1 1 amistar top.Cf.1
## 9 Cf 9 amistar top 1 1 amistar top.Cf.1
## 10 Cf 10 amistar top 1 1 amistar top.Cf.1
# Determina a primeira data de valor `incid == 1` para cada unidade
# experimental.
da_1 <- da %>%
group_by(ue) %>%
filter(incid == 1) %>%
top_n(day, n = -1)
da_1
## # A tibble: 213 x 6
## # Groups: ue [213]
## spp day trat rep incid ue
## <fct> <dbl> <fct> <dbl> <dbl> <fct>
## 1 Ch 2 test 1 1 test.Ch.1
## 2 Ch 2 test 2 1 test.Ch.2
## 3 Ch 2 test 3 1 test.Ch.3
## 4 Ch 2 test 4 1 test.Ch.4
## 5 Ch 2 test 5 1 test.Ch.5
## 6 Ch 2 test 6 1 test.Ch.6
## 7 Ch 2 test 7 1 test.Ch.7
## 8 Ch 2 test 8 1 test.Ch.8
## 9 Ch 2 test 10 1 test.Ch.10
## 10 Ch 2 test 11 1 test.Ch.11
## # … with 203 more rows
# Determina a última data de valor `incid == 0` para cada unidade
# experimental restante, ou seja, que não apresentou `incid == 1`.
da_0 <- anti_join(da, da_1, by = "ue") %>%
group_by(ue) %>%
top_n(day, n = 1)
da_0
## # A tibble: 87 x 6
## # Groups: ue [87]
## spp day trat rep incid ue
## <fct> <dbl> <fct> <dbl> <dbl> <fct>
## 1 Ch 10 test 9 0 test.Ch.9
## 2 Ch 10 test 14 0 test.Ch.14
## 3 Ch 10 test 21 0 test.Ch.21
## 4 Ch 10 mythos 12 0 mythos.Ch.12
## 5 Ch 10 mythos 15 0 mythos.Ch.15
## 6 Ch 10 mythos 16 0 mythos.Ch.16
## 7 Ch 10 mythos 17 0 mythos.Ch.17
## 8 Ch 10 mythos 21 0 mythos.Ch.21
## 9 Cf 10 mythos 11 0 mythos.Cf.11
## 10 Ch 10 score 2 0 score.Ch.2
## # … with 77 more rows
# Junta as duas porções.
da_final <- bind_rows(da_1, da_0) %>%
ungroup()
da_final
## # A tibble: 300 x 6
## spp day trat rep incid ue
## <fct> <dbl> <fct> <dbl> <dbl> <fct>
## 1 Ch 2 test 1 1 test.Ch.1
## 2 Ch 2 test 2 1 test.Ch.2
## 3 Ch 2 test 3 1 test.Ch.3
## 4 Ch 2 test 4 1 test.Ch.4
## 5 Ch 2 test 5 1 test.Ch.5
## 6 Ch 2 test 6 1 test.Ch.6
## 7 Ch 2 test 7 1 test.Ch.7
## 8 Ch 2 test 8 1 test.Ch.8
## 9 Ch 2 test 10 1 test.Ch.10
## 10 Ch 2 test 11 1 test.Ch.11
## # … with 290 more rows
xtabs(~trat + spp, data = da_final)
## spp
## trat Cf Ch
## amistar top 25 25
## mythos 25 25
## nativo 25 25
## recop 25 25
## score 25 25
## test 25 25
xtabs(incid ~ trat + spp, data = da_final)
## spp
## trat Cf Ch
## amistar top 16 14
## mythos 24 20
## nativo 18 9
## recop 18 18
## score 20 9
## test 25 22
# Verifica.
da_final %>%
filter(spp == "Ch", trat == "mythos") %>%
print(n = Inf)
## # A tibble: 25 x 6
## spp day trat rep incid ue
## <fct> <dbl> <fct> <dbl> <dbl> <fct>
## 1 Ch 2 mythos 1 1 mythos.Ch.1
## 2 Ch 2 mythos 2 1 mythos.Ch.2
## 3 Ch 2 mythos 3 1 mythos.Ch.3
## 4 Ch 2 mythos 4 1 mythos.Ch.4
## 5 Ch 2 mythos 7 1 mythos.Ch.7
## 6 Ch 2 mythos 8 1 mythos.Ch.8
## 7 Ch 2 mythos 9 1 mythos.Ch.9
## 8 Ch 2 mythos 10 1 mythos.Ch.10
## 9 Ch 2 mythos 11 1 mythos.Ch.11
## 10 Ch 2 mythos 14 1 mythos.Ch.14
## 11 Ch 2 mythos 20 1 mythos.Ch.20
## 12 Ch 2 mythos 22 1 mythos.Ch.22
## 13 Ch 2 mythos 24 1 mythos.Ch.24
## 14 Ch 2 mythos 25 1 mythos.Ch.25
## 15 Ch 5 mythos 5 1 mythos.Ch.5
## 16 Ch 5 mythos 6 1 mythos.Ch.6
## 17 Ch 5 mythos 18 1 mythos.Ch.18
## 18 Ch 5 mythos 19 1 mythos.Ch.19
## 19 Ch 10 mythos 13 1 mythos.Ch.13
## 20 Ch 10 mythos 23 1 mythos.Ch.23
## 21 Ch 10 mythos 12 0 mythos.Ch.12
## 22 Ch 10 mythos 15 0 mythos.Ch.15
## 23 Ch 10 mythos 16 0 mythos.Ch.16
## 24 Ch 10 mythos 17 0 mythos.Ch.17
## 25 Ch 10 mythos 21 0 mythos.Ch.21
Análise exploratória
#-----------------------------------------------------------------------
# Análise exploratória.
str(da_final)
## Classes 'tbl_df', 'tbl' and 'data.frame': 300 obs. of 6 variables:
## $ spp : Factor w/ 2 levels "Cf","Ch": 2 2 2 2 2 2 2 2 2 2 ...
## $ day : num 2 2 2 2 2 2 2 2 2 2 ...
## $ trat : Factor w/ 6 levels "amistar top",..: 6 6 6 6 6 6 6 6 6 6 ...
## $ rep : num 1 2 3 4 5 6 7 8 10 11 ...
## $ incid: num 1 1 1 1 1 1 1 1 1 1 ...
## $ ue : Factor w/ 300 levels "amistar top.Cf.1",..: 12 24 36 48 60 72 84 96 120 132 ...
# Ordena pelo dia do evento dentro de cada unidade experimental.
da_final <- da_final %>%
group_by(spp, trat) %>%
arrange(day) %>%
mutate(ord = seq_along(day)/n())
# Gráfico com a linha do tempo de cada fruto que mostra quando o evento
# aconteceu e que tipo de desfecho.
ggplot(data = da_final,
mapping = aes(x = day, y = ord, shape = factor(incid))) +
facet_grid(facets = spp ~ trat) +
geom_point() +
geom_segment(mapping = aes(x = 0, y = ord, xend = day, yend = ord)) +
scale_shape_manual(breaks = c(0, 1),
values = c(1, 19),
labels = c("Censura", "Sintoma")) +
labs(shape = "Desfecho",
x = "Dias após inoculação",
y = "Ordem do fruto") +
scale_x_continuous(breaks = seq(0, max(da_final$day), by = 2))

# ATTENTION ------------------------------------------------------------
# Será feita análise de sobreviência com esses dados pois é motivada
# pelo tipo de resposta de natureza "tempo até desfecho". Para acomodar
# a estrutura de planejamento fatorial completo 2 x 6, será usada uma
# abordagem paramétrica. Por apresentar boa flexibilidade, será usada a
# distribuição Weibull para o tempo até o desfecho. Com isso consegue-se
# acomodar a censura e a estrutura experimental.
Breve reconhecimento da parametrização da Weibull
#-----------------------------------------------------------------------
# Antes de ir para o ajuste da Weibull, vamos reconhecer a
# parametrização.
# Gera números aleatórios de uma distribuição Weibull.
y <- rweibull(n = 1000, shape = 4, scale = 2)
plot(ecdf(y))
# Ajusta o modelo com a `survreg()`.
m <- survreg(formula = Surv(time = y) ~ 1, dist = "weibull")
summary(m)
##
## Call:
## survreg(formula = Surv(time = y) ~ 1, dist = "weibull")
## Value Std. Error z p
## (Intercept) 0.69441 0.00811 85.6 <2e-16
## Log(scale) -1.41257 0.02457 -57.5 <2e-16
##
## Scale= 0.244
##
## Weibull distribution
## Loglik(model)= -715.7 Loglik(intercept only)= -715.7
## Number of Newton-Raphson Iterations: 6
## n= 1000
# Compreende os coeficientes estimados.
exp(coef(m)) # scale = exp(coef) -> 2.
## (Intercept)
## 2.002531
1/m$scale # shape = 1/m$scale -> 4.
## [1] 4.106508
# Verifica o ajuste com obsevado vs ajustado.
plot(ecdf(y))
curve(pweibull(x, shape = 1/m$scale, scale = exp(coef(m))),
add = TRUE,
col = 2)

# Obtenção do tempo médio.
a <- 1/m$scale
b <- unname(exp(coef(m))[1])
c("sample_mean" = mean(y),
"estimated_mean" = b * gamma(1 + 1/a))
## sample_mean estimated_mean
## 1.817993 1.817824
Ajuste do modelo Weibull
#-----------------------------------------------------------------------
# Ajustar a Weibull acomodando a estrutura experimental.
# COMMENT: a análise de sobrevivência é a abrodagem mais adequada para
# análise destes dados, visto que de fato a variável resposta é o tempo
# para o desfecho e tem-se censura.
# A modelagem é para a variável aleatória `tempo para aparecimento de
# sintoma` (desfecho).
s <- with(da_final,
Surv(time = day,
event = incid))
# Modelo nulo que não tem efeito de nenhum fator.
m0 <- survreg(formula = s ~ 1,
data = da_final,
dist = "weibull")
# Inclui o efeito de espécie.
m1 <- survreg(formula = s ~ spp,
data = da_final,
dist = "weibull")
# Inclui o efeito de espécie e tratamentos (aditivo).
m2 <- survreg(formula = s ~ spp + trat,
data = da_final,
dist = "weibull")
# Inclui o efeito de espécie e tratamentos com interação.
m3 <- survreg(formula = s ~ spp * trat,
data = da_final,
dist = "weibull")
# Teste da razão de verossimilhanças entre modelos encaixados.
anova(m0, m1, m2, m3)
## Terms Resid. Df -2*LL Test Df Deviance Pr(>Chi)
## 1 1 298 1266.985 NA NA NA
## 2 spp 297 1251.616 = 1 15.36874 8.843933e-05
## 3 spp + trat 292 1198.358 = 5 53.25808 2.976992e-10
## 4 spp * trat 287 1186.178 = 5 12.17968 3.240697e-02
# O modelo com interação é o mais apropriado para descrever o tempo para
# o aparecimento de sintomas. Portanto, existe interação entre espécies
# e produtos ao nível de 5% pelo teste da deviance entre modelos
# encaixados.
# Modelo final.
mx <- m3
Curvas de sobreviência
#-----------------------------------------------------------------------
# Extração dos tempos médios e confecção das curvas de sobrevivência.
# Médias amostrais (que ignoram estrutura e censura).
# da_final %>%
# group_by(spp, trat) %>%
# summarise(m_day = mean(day))
# Médias ajustadas (é na interpretação do parâmetro da Weibull).
emm <- emmeans(mx,
specs = ~spp + trat)
emm
## spp trat emmean SE df lower.CL upper.CL
## Cf amistar top 2.19 0.210 287 1.777 2.60
## Ch amistar top 2.54 0.225 287 2.102 2.99
## Cf mythos 1.17 0.172 287 0.833 1.51
## Ch mythos 1.79 0.187 287 1.417 2.16
## Cf nativo 1.96 0.197 287 1.573 2.35
## Ch nativo 2.85 0.282 287 2.296 3.41
## Cf recop 2.02 0.197 287 1.627 2.40
## Ch recop 1.87 0.197 287 1.480 2.26
## Cf score 1.72 0.187 287 1.347 2.08
## Ch score 2.85 0.282 287 2.296 3.41
## Cf test 1.14 0.168 287 0.811 1.47
## Ch test 1.34 0.179 287 0.990 1.69
##
## Results are given on the log (not the response) scale.
## Confidence level used: 0.95
tb_emm <- as.data.frame(emm)
# Estimativas conforme parametrização da {p, d, q, r}weibull.
a <- 1/mx$scale # shape.
b <- exp(tb_emm$emmean) # scale.
# Obtenção do tempo médio (é uma função complexa dos dois parâmetros).
tb_emm$mean_day <- b * gamma(1 + 1/a)
tb_emm
## spp trat emmean SE df lower.CL upper.CL mean_day
## 1 Cf amistar top 2.189537 0.2096084 287 1.7769724 2.602102 8.412596
## 2 Ch amistar top 2.544112 0.2246914 287 2.1018602 2.986364 11.992785
## 3 Cf mythos 1.171612 0.1717900 287 0.8334837 1.509740 3.039839
## 4 Ch mythos 1.786291 0.1874039 287 1.4174307 2.155151 5.620856
## 5 Cf nativo 1.961678 0.1974581 287 1.5730282 2.350328 6.698415
## 6 Ch nativo 2.850903 0.2816894 287 2.2964641 3.405342 16.298874
## 7 Cf recop 2.015539 0.1974580 287 1.6268891 2.404188 7.069088
## 8 Ch recop 1.868744 0.1974632 287 1.4800845 2.257404 6.103956
## 9 Cf score 1.715966 0.1874072 287 1.3470996 2.084833 5.239150
## 10 Ch score 2.850903 0.2816894 287 2.2964641 3.405342 16.298874
## 11 Cf test 1.141479 0.1678588 287 0.8110887 1.471870 2.949608
## 12 Ch test 1.342256 0.1789124 287 0.9901091 1.694403 3.605459
# Curvas de probabilidade de desfecho.
tb_curves <- tb_emm %>%
group_by(spp, trat) %>%
do({
day <- seq(0, 20, length.out = 51)
dens <- dweibull(day, shape = a, scale = exp(.$emmean))
accu <- pweibull(day, shape = a, scale = exp(.$emmean))
data.frame(day, dens, accu)
}) %>%
ungroup()
# As curvas de densidade ajustadas.
ggplot(data = tb_curves,
mapping = aes(x = day, y = dens)) +
facet_grid(facets = spp ~ trat) +
geom_line()

# As curvas de "1 - sobreviência".
ggplot(data = tb_curves,
mapping = aes(x = day, y = accu)) +
facet_grid(facets = spp ~ trat) +
geom_line()

# Valores observados com sobreposição das curvas ajustadas.
ggplot(data = da_final,
mapping = aes(x = day, y = ord, shape = factor(incid))) +
facet_grid(facets = spp ~ trat) +
geom_point() +
scale_shape_manual(breaks = c(0, 1),
values = c(1, 19),
labels = c("Censura", "Sintoma")) +
labs(shape = "Desfecho",
x = "Dias após inoculação",
y = "Frequência acumulada") +
geom_vline(data = tb_emm,
mapping = aes(xintercept = mean_day),
color = "orange") +
geom_line(data = tb_curves,
inherit.aes = FALSE,
mapping = aes(x = day, y = accu))

Estudo da interação com comparações múltiplas.
#-----------------------------------------------------------------------
# Fazendo o estudo da interação com desdobramento com testes para o
# parâmetro de locação.
# Estudar produtos em cada espécie.
emm_trat_in <- emmeans(mx, specs = ~trat | spp)
emm_trat_in
## spp = Cf:
## trat emmean SE df lower.CL upper.CL
## amistar top 2.19 0.210 287 1.777 2.60
## mythos 1.17 0.172 287 0.833 1.51
## nativo 1.96 0.197 287 1.573 2.35
## recop 2.02 0.197 287 1.627 2.40
## score 1.72 0.187 287 1.347 2.08
## test 1.14 0.168 287 0.811 1.47
##
## spp = Ch:
## trat emmean SE df lower.CL upper.CL
## amistar top 2.54 0.225 287 2.102 2.99
## mythos 1.79 0.187 287 1.417 2.16
## nativo 2.85 0.282 287 2.296 3.41
## recop 1.87 0.197 287 1.480 2.26
## score 2.85 0.282 287 2.296 3.41
## test 1.34 0.179 287 0.990 1.69
##
## Results are given on the log (not the response) scale.
## Confidence level used: 0.95
# contrast(emm_trat_in, method = "pairwise")
trat_in_comp <- multcomp::cld(emm_trat_in)
trat_in_comp
## spp = Cf:
## trat emmean SE df lower.CL upper.CL .group
## test 1.14 0.168 287 0.811 1.47 1
## mythos 1.17 0.172 287 0.833 1.51 1
## score 1.72 0.187 287 1.347 2.08 12
## nativo 1.96 0.197 287 1.573 2.35 2
## recop 2.02 0.197 287 1.627 2.40 2
## amistar top 2.19 0.210 287 1.777 2.60 2
##
## spp = Ch:
## trat emmean SE df lower.CL upper.CL .group
## test 1.34 0.179 287 0.990 1.69 1
## mythos 1.79 0.187 287 1.417 2.16 12
## recop 1.87 0.197 287 1.480 2.26 123
## amistar top 2.54 0.225 287 2.102 2.99 23
## nativo 2.85 0.282 287 2.296 3.41 3
## score 2.85 0.282 287 2.296 3.41 3
##
## Results are given on the log (not the response) scale.
## Confidence level used: 0.95
## P value adjustment: tukey method for comparing a family of 6 estimates
## significance level used: alpha = 0.05
# Tabela com o resultado das comparações múltiplas.
tb_contr <- as.data.frame(trat_in_comp)
tb_contr
## trat spp emmean SE df lower.CL upper.CL .group
## 6 test Cf 1.141479 0.1678588 287 0.8110887 1.471870 1
## 2 mythos Cf 1.171612 0.1717900 287 0.8334837 1.509740 1
## 5 score Cf 1.715966 0.1874072 287 1.3470996 2.084833 12
## 3 nativo Cf 1.961678 0.1974581 287 1.5730282 2.350328 2
## 4 recop Cf 2.015539 0.1974580 287 1.6268891 2.404188 2
## 1 amistar top Cf 2.189537 0.2096084 287 1.7769724 2.602102 2
## 12 test Ch 1.342256 0.1789124 287 0.9901091 1.694403 1
## 8 mythos Ch 1.786291 0.1874039 287 1.4174307 2.155151 12
## 10 recop Ch 1.868744 0.1974632 287 1.4800845 2.257404 123
## 7 amistar top Ch 2.544112 0.2246914 287 2.1018602 2.986364 23
## 9 nativo Ch 2.850903 0.2816894 287 2.2964641 3.405342 3
## 11 score Ch 2.850903 0.2816894 287 2.2964641 3.405342 3
# Transformar os números para letras e ordenar as letras conforme as
# estimativas.
f <- function(x) {
l <- x %>%
str_trim() %>%
str_split("") %>%
flatten_chr() %>%
as.integer()
str_c(letters[l], collapse = "")
}
f(" 123 ")
## [1] "abc"
# Acerta a representação da significância dos contrastes com letras.
tb_contr <- tb_contr %>%
mutate(let = map_chr(.group, f)) %>%
group_by(spp) %>%
mutate(let2 = ordered_cld(let = let, means = emmean))
ggplot(data = tb_contr,
mapping = aes(x = trat, y = emmean)) +
facet_wrap(facets = ~spp) +
geom_point() +
geom_errorbar(mapping = aes(ymin = lower.CL,
ymax = upper.CL),
width = 0.05) +
geom_text(mapping = aes(label = sprintf("%0.2f %s",
emmean,
let2)),
hjust = 0.5,
vjust = -1,
angle = 90,
nudge_x = 0.075) +
labs(x = "Tratamento",
y = "Estimativa do parâmetro de locação")
