PRIMER EJERCICIO - NIVEL DE CAPTACIÓN DE CO2 EN PLANTAS

Se preparan las librerías a emplear en el modelo.

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.2     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(broom.mixed)
library(lme4)
## Loading required package: Matrix
## 
## Attaching package: 'Matrix'
## 
## The following objects are masked from 'package:tidyr':
## 
##     expand, pack, unpack

Añadiendo la base de datos

data("CO2")
View(CO2)

head(CO2)
## Grouped Data: uptake ~ conc | Plant
##   Plant   Type  Treatment conc uptake
## 1   Qn1 Quebec nonchilled   95   16.0
## 2   Qn1 Quebec nonchilled  175   30.4
## 3   Qn1 Quebec nonchilled  250   34.8
## 4   Qn1 Quebec nonchilled  350   37.2
## 5   Qn1 Quebec nonchilled  500   35.3
## 6   Qn1 Quebec nonchilled  675   39.2

Generando ruido en la base de datos del nivel de captación de CO2

set.seed(123)
ruido = runif(84, 0.02, 0.04)
uptake2 = CO2$uptake+ruido
data.frame(uptake2)
##      uptake2
## 1  16.025752
## 2  30.435766
## 3  34.828180
## 4  37.237660
## 5  35.338809
## 6  39.220911
## 7  39.730562
## 8  13.637848
## 9  27.331029
## 10 37.129132
## 11 41.839137
## 12 40.629067
## 13 41.433551
## 14 44.331453
## 15 16.222058
## 16 32.437996
## 17 40.324922
## 18 42.120841
## 19 42.926558
## 20 43.939090
## 21 45.537791
## 22 14.233856
## 23 24.132810
## 24 30.339885
## 25 34.633114
## 26 32.534171
## 27 35.430881
## 28 38.731883
## 29  9.325783
## 30 27.322942
## 31 35.039260
## 32 38.838046
## 33 38.633814
## 34 37.535909
## 35 42.420492
## 36 15.129556
## 37 21.035169
## 38 38.124328
## 39 34.026364
## 40 38.924633
## 41 39.622856
## 42 41.428291
## 43 10.628274
## 44 19.227377
## 45 26.223049
## 46 30.022776
## 47 30.924661
## 48 32.429319
## 49 35.525319
## 50 12.037157
## 51 22.020917
## 52 30.628844
## 53 31.835978
## 54 32.422438
## 55 31.131219
## 56 31.524131
## 57 11.322551
## 58 19.435066
## 59 25.837901
## 60 27.927489
## 61 28.533302
## 62 28.121897
## 63 27.827679
## 64 10.525488
## 65 14.936293
## 66 18.128970
## 67 18.936201
## 68 19.536248
## 69 22.235887
## 70 21.928797
## 71  7.735090
## 72 11.432584
## 73 12.334204
## 74 13.020012
## 75 12.529506
## 76 13.724402
## 77 14.427596
## 78 10.632255
## 79 18.027036
## 80 17.922223
## 81 17.924872
## 82 17.933361
## 83 18.928353
## 84 19.935764

Graficando el experimento

ggplot(CO2, aes(x = conc, y = uptake2, color = Type)) +
  geom_point(aes(shape = Treatment)) +
  geom_path(aes(group = Plant, lty = Treatment)) + 
  theme_bw()

Solucionando el modelo de tipo aleatorio

Fit1 <- lm(uptake2 ~ conc + Type + Treatment, data = CO2)
Fit2 <- lmer(uptake2 ~ conc + Type + Treatment + (1|Plant), data = CO2)

Observando los modelos

broom::glance(Fit1)
## # A tibble: 1 × 12
##   r.squared adj.r.squared sigma statistic  p.value    df logLik   AIC   BIC
##       <dbl>         <dbl> <dbl>     <dbl>    <dbl> <dbl>  <dbl> <dbl> <dbl>
## 1     0.684         0.672  6.19      57.7 5.88e-20     3  -270.  551.  563.
## # ℹ 3 more variables: deviance <dbl>, df.residual <int>, nobs <int>
broom::tidy(Fit1)
## # A tibble: 4 × 5
##   term             estimate std.error statistic  p.value
##   <chr>               <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)       29.3      1.54        19.0  1.94e-31
## 2 conc               0.0177   0.00230      7.72 2.88e-11
## 3 TypeMississippi  -12.7      1.35        -9.37 1.66e-14
## 4 Treatmentchilled  -6.86     1.35        -5.08 2.47e- 6

Empleando el modelo lineal mixto

broom.mixed::glance(Fit2)
## # A tibble: 1 × 7
##    nobs sigma logLik   AIC   BIC REMLcrit df.residual
##   <int> <dbl>  <dbl> <dbl> <dbl>    <dbl>       <int>
## 1    84  6.00  -272.  556.  571.     544.          78
broom.mixed::tidy(Fit2)
## # A tibble: 6 × 6
##   effect   group    term             estimate std.error statistic
##   <chr>    <chr>    <chr>               <dbl>     <dbl>     <dbl>
## 1 fixed    <NA>     (Intercept)       29.3      1.72        17.0 
## 2 fixed    <NA>     conc               0.0177   0.00223      7.96
## 3 fixed    <NA>     TypeMississippi  -12.7      1.64        -7.72
## 4 fixed    <NA>     Treatmentchilled  -6.86     1.64        -4.18
## 5 ran_pars Plant    sd__(Intercept)    1.71    NA           NA   
## 6 ran_pars Residual sd__Observation    6.00    NA           NA
broom.mixed::tidy(Fit2) %>% View()

Añadiendo logaritmo al modelo y mirando el comportamiento del tipo con la interacción

Fit1 <- lm(uptake2 ~ I(log(conc)) + Type:Treatment, data = CO2)

Fit2 <- lmer(uptake2 ~ I(log(conc)) + Type:Treatment + (1 | Plant), data = CO2)
## fixed-effect model matrix is rank deficient so dropping 1 column / coefficient

Resumiendo los modelos

broom::glance(Fit1)
## # A tibble: 1 × 12
##   r.squared adj.r.squared sigma statistic  p.value    df logLik   AIC   BIC
##       <dbl>         <dbl> <dbl>     <dbl>    <dbl> <dbl>  <dbl> <dbl> <dbl>
## 1     0.823         0.814  4.67      91.7 7.02e-29     4  -246.  504.  519.
## # ℹ 3 more variables: deviance <dbl>, df.residual <int>, nobs <int>
broom::tidy(Fit1)
## # A tibble: 6 × 5
##   term                                estimate std.error statistic   p.value
##   <chr>                                  <dbl>     <dbl>     <dbl>     <dbl>
## 1 (Intercept)                           -33.5      4.08      -8.22  3.21e-12
## 2 I(log(conc))                            8.48     0.678     12.5   2.04e-20
## 3 TypeQuebec:Treatmentnonchilled         19.5      1.44      13.6   2.61e-22
## 4 TypeMississippi:Treatmentnonchilled    10.1      1.44       7.04  6.35e-10
## 5 TypeQuebec:Treatmentchilled            15.9      1.44      11.1   9.95e-18
## 6 TypeMississippi:Treatmentchilled       NA       NA         NA    NA
broom.mixed::glance(Fit2)
## # A tibble: 1 × 7
##    nobs sigma logLik   AIC   BIC REMLcrit df.residual
##   <int> <dbl>  <dbl> <dbl> <dbl>    <dbl>       <int>
## 1    84  4.50  -241.  496.  513.     482.          77
broom.mixed::tidy(Fit2)
## # A tibble: 7 × 6
##   effect   group    term                            estimate std.error statistic
##   <chr>    <chr>    <chr>                              <dbl>     <dbl>     <dbl>
## 1 fixed    <NA>     (Intercept)                       -33.5      4.02      -8.34
## 2 fixed    <NA>     I(log(conc))                        8.48     0.654     13.0 
## 3 fixed    <NA>     TypeQuebec:Treatmentnonchilled     19.5      1.83      10.6 
## 4 fixed    <NA>     TypeMississippi:Treatmentnonch…    10.1      1.83       5.52
## 5 fixed    <NA>     TypeQuebec:Treatmentchilled        15.9      1.83       8.69
## 6 ran_pars Plant    sd__(Intercept)                     1.47    NA         NA   
## 7 ran_pars Residual sd__Observation                     4.50    NA         NA
broom.mixed::tidy(Fit2) %>% View()

SEGUNDO EJERCICIO - PESO DE POLLOS

Agregando la base de datos y graficando el experimento

data("Chickweight")
## Warning in data("Chickweight"): data set 'Chickweight' not found
view(ChickWeight)

ggplot(ChickWeight, aes(x = Time, y = weight)) + 
  geom_point(aes(color = Diet)) +
  geom_path(aes(color = Diet, group = Chick))

Proyectando la base de datos del experimento

ChickWeight$Chick
##   [1] 1  1  1  1  1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  2  2  2  2  2  3 
##  [26] 3  3  3  3  3  3  3  3  3  3  3  4  4  4  4  4  4  4  4  4  4  4  4  5  5 
##  [51] 5  5  5  5  5  5  5  5  5  5  6  6  6  6  6  6  6  6  6  6  6  6  7  7  7 
##  [76] 7  7  7  7  7  7  7  7  7  8  8  8  8  8  8  8  8  8  8  8  9  9  9  9  9 
## [101] 9  9  9  9  9  9  9  10 10 10 10 10 10 10 10 10 10 10 10 11 11 11 11 11 11
## [126] 11 11 11 11 11 11 12 12 12 12 12 12 12 12 12 12 12 12 13 13 13 13 13 13 13
## [151] 13 13 13 13 13 14 14 14 14 14 14 14 14 14 14 14 14 15 15 15 15 15 15 15 15
## [176] 16 16 16 16 16 16 16 17 17 17 17 17 17 17 17 17 17 17 17 18 18 19 19 19 19
## [201] 19 19 19 19 19 19 19 19 20 20 20 20 20 20 20 20 20 20 20 20 21 21 21 21 21
## [226] 21 21 21 21 21 21 21 22 22 22 22 22 22 22 22 22 22 22 22 23 23 23 23 23 23
## [251] 23 23 23 23 23 23 24 24 24 24 24 24 24 24 24 24 24 24 25 25 25 25 25 25 25
## [276] 25 25 25 25 25 26 26 26 26 26 26 26 26 26 26 26 26 27 27 27 27 27 27 27 27
## [301] 27 27 27 27 28 28 28 28 28 28 28 28 28 28 28 28 29 29 29 29 29 29 29 29 29
## [326] 29 29 29 30 30 30 30 30 30 30 30 30 30 30 30 31 31 31 31 31 31 31 31 31 31
## [351] 31 31 32 32 32 32 32 32 32 32 32 32 32 32 33 33 33 33 33 33 33 33 33 33 33
## [376] 33 34 34 34 34 34 34 34 34 34 34 34 34 35 35 35 35 35 35 35 35 35 35 35 35
## [401] 36 36 36 36 36 36 36 36 36 36 36 36 37 37 37 37 37 37 37 37 37 37 37 37 38
## [426] 38 38 38 38 38 38 38 38 38 38 38 39 39 39 39 39 39 39 39 39 39 39 39 40 40
## [451] 40 40 40 40 40 40 40 40 40 40 41 41 41 41 41 41 41 41 41 41 41 41 42 42 42
## [476] 42 42 42 42 42 42 42 42 42 43 43 43 43 43 43 43 43 43 43 43 43 44 44 44 44
## [501] 44 44 44 44 44 44 45 45 45 45 45 45 45 45 45 45 45 45 46 46 46 46 46 46 46
## [526] 46 46 46 46 46 47 47 47 47 47 47 47 47 47 47 47 47 48 48 48 48 48 48 48 48
## [551] 48 48 48 48 49 49 49 49 49 49 49 49 49 49 49 49 50 50 50 50 50 50 50 50 50
## [576] 50 50 50
## 50 Levels: 18 < 16 < 15 < 13 < 9 < 20 < 10 < 8 < 17 < 19 < 4 < 6 < 11 < ... < 48
ChickWeight$Chick %>% length()
## [1] 578
ChickWeight$Chick %>% unique() %>% length()
## [1] 50
view(ChickWeight)

Modelo del experimento

Fit1_Poisson <- glm(weight ~ Diet:Time, data = ChickWeight, family = poisson)
tidy(Fit1_Poisson)
## # A tibble: 5 × 5
##   term        estimate std.error statistic p.value
##   <chr>          <dbl>     <dbl>     <dbl>   <dbl>
## 1 (Intercept)   3.86    0.00931      415.        0
## 2 Diet1:Time    0.0656  0.000722      90.8       0
## 3 Diet2:Time    0.0754  0.000768      98.1       0
## 4 Diet3:Time    0.0862  0.000729     118.        0
## 5 Diet4:Time    0.0823  0.000756     109.        0

Modelo lineal mixto

Fit2_Poisson <- glmer(weight ~ Diet:Time + (1|Chick), data = ChickWeight, family = poisson)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control$checkConv, : Model is nearly unidentifiable: very large eigenvalue
##  - Rescale variables?
broom::tidy(Fit1_Poisson)
## # A tibble: 5 × 5
##   term        estimate std.error statistic p.value
##   <chr>          <dbl>     <dbl>     <dbl>   <dbl>
## 1 (Intercept)   3.86    0.00931      415.        0
## 2 Diet1:Time    0.0656  0.000722      90.8       0
## 3 Diet2:Time    0.0754  0.000768      98.1       0
## 4 Diet3:Time    0.0862  0.000729     118.        0
## 5 Diet4:Time    0.0823  0.000756     109.        0
broom.mixed::tidy(Fit2_Poisson)
## # A tibble: 6 × 7
##   effect   group term            estimate std.error statistic p.value
##   <chr>    <chr> <chr>              <dbl>     <dbl>     <dbl>   <dbl>
## 1 fixed    <NA>  (Intercept)       3.84     0.0315      122.        0
## 2 fixed    <NA>  Diet1:Time        0.0666   0.00105      63.7       0
## 3 fixed    <NA>  Diet2:Time        0.0749   0.00129      57.9       0
## 4 fixed    <NA>  Diet3:Time        0.0868   0.00123      70.5       0
## 5 fixed    <NA>  Diet4:Time        0.0763   0.00126      60.4       0
## 6 ran_pars Chick sd__(Intercept)   0.213   NA            NA        NA
view(broom.mixed::tidy(Fit2_Poisson))
view(broom::tidy(Fit1_Poisson))

Generando un plot_model de tipo efecto

sjPlot::plot_model(Fit1_Poisson,type = "eff")
## Package `effects` is not available, but needed for `ggeffect()`. Either
##   install package `effects`, or use `ggpredict()`. Calling `ggpredict()`
##   now.
## $Diet

## 
## $Time

RESUMIENDO

RESOLUCIÓN DE LAS PREGUNTAS

#1. ¿Por qué utiliza modelo mixto?

#2. ¿Qué ventajas tiene este tipo de modelos en agricultura?