192 |
193 | ```{r, echo=FALSE}
194 | tibble(Model = paste0("mod", 1:4),
195 | AIC = AIC(mod1.nlme,mod2.nlme,mod3.nlme,mod4.nlme)$AIC,
196 | Deviance = -2 * c(mod1.nlme %>% logLik,
197 | mod2.nlme %>% logLik,
198 | mod3.nlme %>% logLik,
199 | mod4.nlme %>% logLik) %>% as.double) %>%
200 | kable(escape = FALSE) %>%
201 | kable_styling(bootstrap_options = c("bordered", "hover"),
202 | full_width = FALSE)
203 | ```
204 |
205 | ## lme4
206 | in progress
207 |
208 | ## glmmTMB
209 | in progress
210 |
211 | ## sommer
212 | in progress
--------------------------------------------------------------------------------
/site_libs/jqueryui-1.11.4/jquery-ui.structure.min.css:
--------------------------------------------------------------------------------
1 | /*! jQuery UI - v1.11.4 - 2016-01-05
2 | * http://jqueryui.com
3 | * Copyright jQuery Foundation and other contributors; Licensed MIT */
4 |
5 | .ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;min-height:0;font-size:100%}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;cursor:pointer}.ui-selectmenu-button span.ui-icon{right:0.5em;left:auto;margin-top:-8px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:0.4em 2.1em 0.4em 1em;display:block;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}
--------------------------------------------------------------------------------
/weighted_two_stage.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Weighted two-stage analyses"
3 | output:
4 | html_document:
5 | includes:
6 | in_header: header.html
7 | after_body: footer.html
8 | params:
9 | hilang:
10 | - sas
11 | ---
12 |
13 | ```{r, echo=FALSE, message=FALSE, warning=FALSE, purl=FALSE}
14 | # markdown options
15 | options(knitr.kable.NA = '') # show NA as empty cells in output tables
16 | pacman::p_load(kableExtra, formattable, htmltools) # packages for better formatting tables for html output
17 | ```
18 |
19 | ```{r, child="_hilang_setup.Rmd", purl=FALSE}
20 | # required for sas syntax highlighting
21 | ```
22 |
23 | ```{r, message=FALSE}
24 | # packages
25 | pacman::p_load(dplyr, purrr, tibble, tidyr, stringr, # data handling
26 | nlme, lme4, glmmTMB, sommer, # mixed modelling
27 | AICcmodavg, mixedup) # mixed model extractions
28 |
29 | # data
30 | dat <- readr::read_csv("data/Winter Wheat 2016.csv") %>%
31 | dplyr::select(Year, everything()) %>%
32 | mutate_at(vars(Year:Cultivar), as.factor)
33 | ```
34 | ```{r, echo=FALSE, purl=FALSE}
35 | dat %>%
36 | kable(escape = FALSE) %>%
37 | kable_styling(bootstrap_options = c("bordered", "hover", "condensed", "responsive"),
38 | full_width = FALSE) %>%
39 | scroll_box(height = "200px")
40 | ```
41 |
42 | # Motivation
43 |
44 | This chapter deals with a topic that may not be familiar to many readers, but it was very important to us before and during our PhD, which was in the field of biostatistics/data science for plant breeding and other agricultural fields. Therefore, we here give a very brief summary:
45 |
46 | A **two-stage analysis** is really just that: Trying to analyze a dataset not via a single model (in a single step), but in two separate stages/steps, where the output of the first stage/model is the input for the second stage/model. The motivation for doing a two-stage analysis for us was ever so often that data from a multi-environment-trial (MET) needed to be analyzed. An environment here refers to a year-location-combination, so that when multiple trials are set up at multiple locations and/or over multiple years we have a MET. Strictly speaking, data from a MET does not necessarily call for a two-stage analysis, but can indeed often just be analyzed in a single-stage analysis. However, there are arguments that speak for a two-stage analysis, such as the lower amount of required computational power and more dynamic/intuitive analyses of the single environments. For more info see SOURCES.
47 |
48 | ## Example
49 |
50 | The example in this chapter is taken from [Buntaran et al. (2020)](https://acsess.onlinelibrary.wiley.com/doi/full/10.1002/csc2.20177){target="_blank"}. It considers data from a multi-environment trial with winter wheat varieties. The trial took place in 2016 across 18 locations in Sweden. Dry matter yield was analyzed. All trials were laid out as $\alpha$-designs with two replicates. Within each replicate, there were five to seven incomplete blocks. Sweden is divided into three different agricultural zones: South, Middle, and North. A zone is represented by a number of locations. The set of cultivars was the same across locations.
51 |
52 | # Modelling in two stages
53 |
54 | In Stage I, the cultivar means per location are estimated via best linear unbiased estimation (BLUE). This is done via fitting a linear mixed model separately for each location and taking the cultivar effect as fixed. Thus, we obtain one adjusted mean yield value for each cultivar at each location.
55 |
56 | In Stage II, the cultivar means obtained in Stage II serve as the response and
57 |
58 | > In such a two-stage approach, the cultivar main effect should be taken as fixed in Stage I in order to avoid double shrinkage ([Damesa et al., 2017](https://acsess.onlinelibrary.wiley.com/doi/abs/10.2134/agronj2016.07.0395){target="_blank"}; [Piepho et al., 2012](https://onlinelibrary.wiley.com/doi/abs/10.1002/bimj.201100219){target="_blank"}).
59 |
60 | ## Stage I {.tabset .tabset-fade .tabset-pills}
61 |
62 | ### nlme
63 |
64 | in progress, but probably not possible (?)
65 |
66 | ### lme4
67 |
68 | in progress, but probably not possible (?)
69 |
70 | ### glmmTMB
71 |
72 | in progress, but probably not possible (?)
73 |
74 | ### sommer
75 |
76 | in progress, but probably not possible (?)
77 |
78 | ### SAS {.active}
79 |
80 | In order to analyze each location separately in SAS, we can use the `BY` statement. However, the dataset must then also be sorted accordingly - in this case by `Zone Location`.
81 |
82 | In order to obtain the adjusted cultivar means, we take `Cultivar` as a fixed effect in the model and add the `LSMEANS Cultivar;` statement. Furthermore, adding `ODS OUTPUT LSMeans = stageIout_CultivarMeans;` saves the means into an object called `stageIout_CultivarMeans`.
83 |
84 | ```{r, eval=FALSE, hilang="sas", purl=FALSE}
85 | PROC SORT DATA=winterwheat; BY Zone Location Cultivar Rep Alpha; RUN;
86 | PROC MIXED DATA=winterwheat LOGNOTE;
87 | BY Zone Location;
88 | CLASS Cultivar Rep Alpha;
89 | MODEL Yield = Cultivar / DDFM=KR;
90 | RANDOM Rep Rep*Alpha;
91 | LSMEANS Cultivar / COV;
92 | ODS OUTPUT LSMeans = stageIout_CultivarMeans;
93 | RUN;
94 | ```
95 |
96 | Notice that we also add `/COV;` to the `LSMEANS` statement. This is necessary for the Smith's weights weighting approach, as it provides us with the estimated covariance matrix of the adjusted means and saves it, together with the means, into the `stageIout_CultivarMeans` object.
97 |
98 | ## Stage II {.tabset .tabset-fade}
99 |
100 | ### Unweighted (not recommended) {.tabset .tabset-fade .tabset-pills}
101 |
102 | #### nlme
103 |
104 | in progress
105 |
106 | #### lme4
107 |
108 | in progress
109 |
110 | #### glmmTMB
111 |
112 | in progress
113 |
114 | #### sommer
115 |
116 | in progress
117 |
118 | #### SAS
119 |
120 | in progress
121 |
122 | ### Smith's Weights {.tabset .tabset-fade .tabset-pills .active}
123 |
124 | #### nlme
125 |
126 | in progress, but probably not possible (?)
127 |
128 | #### lme4
129 |
130 | in progress, but probably not possible (?)
131 |
132 | #### glmmTMB
133 |
134 | in progress, but probably not possible (?)
135 |
136 | #### sommer
137 |
138 | in progress, but probably not possible (?)
139 |
140 | #### SAS {.active}
141 |
142 | At this point we can conveniently make use of a [SAS-macro](https://blogs.sas.com/content/sgf/2020/04/22/how-to-create-and-use-sas-macro-functions/){target="_blank"} that is described in more detail in [Damesa et al., 2017](https://acsess.onlinelibrary.wiley.com/doi/abs/10.2134/agronj2016.07.0395){target="_blank"} and can be found in their supplemental material. Note that a copy of it can also be found [on github](https://github.com/SchmidtPaul/utilities/tree/master/SAS%20macros){target="_blank"} which makes its use in SAS via URL very convenient:
143 |
144 | ```{r, eval=FALSE, hilang="sas", purl=FALSE}
145 | FILENAME smith URL
146 | "https://raw.githubusercontent.com/SchmidtPaul/utilities/master/SAS%20macros/get_Smith_weights.sas";
147 | %INCLUDE smith;
148 |
149 | %get_smith_weights(data=stageIout_CultivarMeans,
150 | entry=Cultivar, by=Zone, by2=Location,
151 | outL=stageIIin_CultivarMeans);
152 | ```
153 |
154 | As can be seen, the macro `%get_smith_weights` basically needs the `stageIout_CultivarMeans` object as input, the name of the (main) effect for which means were calculated (*i.e.* `Cultivar`), as well as the variables that were used in the `BY` statement in Stage I. It then produces a `stageIIin_CultivarMeans` object that serves as the dataset in Stage II with an additional column `weight_Smith` with the desired weights.
155 |
156 | There are three things to consider when modelling the Smith's weights approach in SAS:
157 |
158 | 1. The `WEIGHT weight_Smith;` statement, which provides the name of the column that holds the weights
159 |
160 | 2. The `REPEATED;` statement must be provided, as it [directly changes how](https://support.sas.com/documentation/cdl/en/statug/63033/HTML/default/viewer.htm#statug_mixed_sect020.htm){target="_blank"} the `WEIGHT` statement operates
161 |
162 | 3. The `PARMS ...(1) /HOLD=n` statement makes sure that the error variance is forced to be equal to 1. Notice that the number of parameters (and thus the number of `(1)` that are required in the statement) differ between models. However, there must always at least be one, *i.e.* the error variance, and it will always be the last one in the `PARMS` statement. In this case the model has 5 parameters, *i.e.* variance components for the random effects `Cultivar`, `Zone:Cultivar`, `Zone:Location:Cultivar` and `Zone:Location` and for the error term.
163 |
164 | ```{r, eval=FALSE, hilang="sas", purl=FALSE}
165 | PROC MIXED DATA=stageIIin_CultivarMeans;
166 | CLASS Cultivar Zone Location;
167 | MODEL Estimate = Zone;
168 | WEIGHT weight_Smith;
169 | RANDOM Int Zone Zone*Location / SUB=Cultivar;
170 | RANDOM Zone*Location;
171 | REPEATED;
172 | PARMS (1)(1)(1)(1)(1) / HOLD=5;
173 | RUN;
174 | ```
175 |
176 | This model then provides us with the Cultivar-BLUPs across all environments obtained in a two-stage analyses using Smith's weights.
177 |
178 | ### Fully Efficient Weighting {.tabset .tabset-fade .tabset-pills}
179 |
180 | #### nlme
181 |
182 | in progress, but probably not possible (?)
183 |
184 | #### lme4
185 |
186 | in progress, but probably not possible (?)
187 |
188 | #### glmmTMB
189 |
190 | in progress, but probably not possible (?)
191 |
192 | #### sommer
193 |
194 | in progress, but probably not possible (?)
195 |
196 | #### SAS {.active}
197 |
198 | At this point we can conveniently make use of a [SAS-macro](https://blogs.sas.com/content/sgf/2020/04/22/how-to-create-and-use-sas-macro-functions/){target="_blank"} that is described in more detail in [Damesa et al., 2017](https://acsess.onlinelibrary.wiley.com/doi/abs/10.2134/agronj2016.07.0395){target="_blank"} and can be found in their supplemental material. Note that a copy of it can also be found [on github](https://github.com/SchmidtPaul/utilities/tree/master/SAS%20macros){target="_blank"} which makes its use in SAS via URL very convenient:
199 |
200 | ```{r, eval=FALSE, hilang="sas", purl=FALSE}
201 | FILENAME fullyeff URL
202 | "https://raw.githubusercontent.com/SchmidtPaul/utilities/master/SAS%20macros/get_one_big_omega.sas";
203 | %INCLUDE fullyeff;
204 |
205 | %get_one_big_omega(data=stageIout_CultivarMeans,
206 | entry=Cultivar, by=Zone, by2=Location,
207 | outL=stageIIin_CultivarMeans);
208 | ```
209 |
210 | As can be seen, the macro `%get_one_big_omega` basically needs the `stageIout_CultivarMeans` object as input, the name of the (main) effect for which means were calculated (*i.e.* `Cultivar`), as well as the variables that were used in the `BY` statement in Stage I. It then produces a `stageIIin_CultivarMeans` object that serves as the dataset in Stage II ....
211 |
212 | There are two things to consider when modelling the fully efficient weighting approach in SAS:
213 |
214 | 1. The `REPEATED;` statement ...
215 |
216 | 2. The `PARMS ...(1) /HOLD=n` statement makes sure that the error variance is forced to be equal to 1. Notice that the number of parameters (and thus the number of `(1)` that are required in the statement) differ between models. However, there must always at least be one, *i.e.* the error variance, and it will always be the last one in the `PARMS` statement. In this case the model has 5 parameters, *i.e.* variance components for the random effects `Cultivar`, `Zone:Cultivar`, `Zone:Location:Cultivar` and `Zone:Location` and for the error term.
217 |
218 | ```{r, eval=FALSE, hilang="sas", purl=FALSE}
219 | PROC MIXED DATA=stageIIin_CultivarMeans;
220 | CLASS Cultivar Zone Location row;
221 | MODEL Estimate = Zone /NOTEST;
222 | RANDOM Int Zone Zone*Location / SUB=Cultivar;
223 | RANDOM Zone*Location;
224 | REPEATED row / SUB=Zone*Location TYPE=lin(1) LDATA=stageIIin_CultivarMeans;
225 | PARMS (1)(1)(1)(1)(1) / HOLD=5;
226 | RUN;
227 | ```
228 |
229 |
230 |
231 |
232 |
233 |
--------------------------------------------------------------------------------
/glmmtmbdispformula0.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Covariance structures for the error term with glmmTMB - a workaround"
3 | output:
4 | html_document:
5 | includes:
6 | in_header: header.html
7 | after_body: footer.html
8 | ---
9 | ```{r, echo=F, message=F, error=F, purl=T}
10 | pacman::p_load(conflicted,
11 | tidyverse,
12 | nlme, glmmTMB,
13 | broom.mixed,
14 | emo, flair)
15 |
16 | # package function conflicts
17 | conflict_prefer("filter", "dplyr")
18 | ```
19 |
20 | ```{r, echo=F, purl=F}
21 | pacman::p_load(kableExtra)
22 | options(knitr.kable.NA = '')
23 | ```
24 |
25 |
26 |
| When fitting linear mixed models, the `glmmTMB` package is nice, because it feels like `lme4` but additionally allows for [several covariance structures](https://cran.r-project.org/web/packages/glmmTMB/vignettes/covstruct.html){target="_blank"} for the random effects.
33 | `r emo::ji("disappointed")`
| However, this only works for random terms on the [***G***-side](https://documentation.sas.com/?cdcId=pgmsascdc&cdcVersion=9.4_3.4&docsetId=statug&docsetTarget=statug_glimmix_overview05.htm&locale=en){target="_blank"} of the model and not for the error term (= [***R***-side](https://documentation.sas.com/?cdcId=pgmsascdc&cdcVersion=9.4_3.4&docsetId=statug&docsetTarget=statug_glimmix_overview05.htm&locale=en){target="_blank"}).
34 | `r emo::ji("nerd_face")`
| **But** there is a workaround! We can fix the error variance to be 0 and thus force all the variance into the ***G***-side. If we do so and also add a random ***"pseudo error term"*** that mimics the original error term, we have created a model that essentially leads to identical results.
35 | `r emo::ji("sunglasses")`
| Once this is clear, we can use all the available variance structures on our *pseudo error term*!
36 |
37 | # How?
38 |
39 | ```{r hideme, echo=FALSE, purl=F}
40 | # this is never seen but needed for code below
41 | dat <- iris %>%
42 | mutate(unit = 1:n() %>% as.factor()) %>%
43 | rename(y=Sepal.Length,
44 | fixedeffects=Species,
45 | randomeffects=Sepal.Width) %>%
46 | as_tibble()
47 | ```
48 |
49 | 1. Remove original error variance from ***R***-side via `dispformula = ~ 0`.
50 | 2. Add pseudo error variance to ***G***-side via random term.
51 | + In the simple case, this can be done via `+ (1 | unit)` where `unit` is a factor with as many levels as there are observations in the dataset.
52 |
53 |
92 |
93 | # Really?
94 |
95 | Here are two examples for the *pseudo-error* approach based on this dataset:
96 |
97 | ```{r, purl=T}
98 | dat <- agridat::mcconway.turnip %>%
99 | mutate(unit = 1:n()) %>%
100 | mutate_at(vars(density, unit), as.factor)
101 | ```
102 |
103 | * **Example 1** We assume no special variance structure for the error term and thus *independent & identically distributed* errors. We compare two `glmmTMB` models - one with a standard error term and one with a *pseudo-error* term.
104 | * **Example 2** We assume a diagonal variance structure for the factor `date` and thus allow for different heterogeneous error variances / heteroscedascity per group for the effect levels of `date`. We compare a *pseudo-error*-`glmmTMB` model with `nlme::lme()` model.
105 |
106 | ## Example 1: iid
107 |
108 |
133 |
134 | The **variance component estimates** of both models are very similar. As expected the Residual variance in the *pseudo-error model* is 0 and instead there is an additional variance for the random `unit` term.
135 |
136 |
298 |
299 |
300 |
301 | # More Details!
302 |
303 | Check out [the GitHub issue](https://github.com/glmmTMB/glmmTMB/issues/653){target="_blank"} I've written on this topic at the `glmmTMB` repository, where [Ben Bolker](https://ms.mcmaster.ca/~bolker/){target="_blank"} - the author of this R-package - replied. Here are some key points:
304 |
305 | * This works **only for gaussian mixed models** and thus not for generalized mixed models!
306 | * As is the case in Example 1, we **sometimes get a `false convergence` warning** for the pseudo-error-model but not for the standard model.
307 | * Actually, `dispformula=~0` does not fix the residual variance to be 0, but to be a small non-zero value.
308 | + Because of this, the **variance component estimates will never be exactly identical**.
309 | + At present [it is set to sqrt(.Machine$double.eps)](https://github.com/glmmTMB/glmmTMB/blob/2b14a42bd55cd0cfeebad1f4eb7a3b2313e5d359/glmmTMB/R/glmmTMB.R#L85){target="_blank"}, which is the squareroot of the [smallest possible](https://stat.ethz.ch/R-manual/R-devel/library/base/html/zMachine.html){target="_blank"} positive floating-point number.
310 | + Ben Bolker [commented](https://github.com/glmmTMB/glmmTMB/issues/653#issuecomment-749295844){target="_blank"} that "One piece of low-hanging fruit would be to allow the small non-zero value to be user-settable via `glmmTMBControl`".
311 | * **Possible covariance structures**
312 | + Find all possible structures [here](https://cran.r-project.org/web/packages/glmmTMB/vignettes/covstruct.html){target="_blank"}
313 | + Note that `cs` is **heterogeneous** compound symmetry and there is no homogeneous compound symmetry!
314 | + As can be seen in example 2, we need a `+ 0` in the `diag(date + 0 | unit)`, since leaving it out would by default lead to estimating not only the desired heterogeneous variances, but an additional overall variance.
315 | + Currently, we **cannot have Kronecker product / direct product / varComb()** as variance structure, as confirmed in [this GitHub issue](https://github.com/glmmTMB/glmmTMB/issues/592){target="_blank"}.
316 |
317 | # Mooore Details!
318 |
319 | * If you are wondering how to **extract the variance component estimates** as I did for example 2 and you are mad that I did not show the code, [click here](https://github.com/SchmidtPaul/MMFAIR/blob/master/Rpurl/glmmtmbdispformula0.R){target="_blank"} to find the R-code of this document.
320 | * Check out the chapters on this website to see more/other uses of this approach.
321 |
322 |
323 |
324 |
--------------------------------------------------------------------------------
/site_libs/jqueryui-1.11.4/jquery-ui.theme.min.css:
--------------------------------------------------------------------------------
1 | /*! jQuery UI - v1.11.4 - 2016-01-05
2 | * http://jqueryui.com
3 | * Copyright jQuery Foundation and other contributors; Licensed MIT */
4 |
5 | .ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#2b2b2b;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:0 0 0 0;padding:5px;background:#666;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
--------------------------------------------------------------------------------
/img/logo/flaviconMMFAIR.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
206 |
--------------------------------------------------------------------------------
/img/logo/hexagonMMFAIR.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
209 |
--------------------------------------------------------------------------------
/variance_structures.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Variance Structures"
3 | output:
4 | html_document:
5 | includes:
6 | after_body: footer.html
7 | ---
8 |
9 | ```{r, echo=FALSE, warning=FALSE, message=FALSE}
10 | options(knitr.kable.NA = '')
11 | # packages for better formatting tables for html output
12 | library(kableExtra)
13 | library(formattable)
14 | library(htmltools)
15 |
16 | pacman::p_load(dplyr, purrr, tibble, tidyr, # data handling
17 | ggplot2, viridis, # plot
18 | nlme, lme4, glmmTMB, sommer, # mixed modelling
19 | AICcmodavg, broom.mixed) # mixed model extractions
20 |
21 | {
22 | dat <- agridat::mcconway.turnip %>%
23 | as_tibble() %>%
24 | mutate(densf = density %>% as.factor) %>%
25 | mutate(date_densf = interaction(date, densf)) # needed for mod5
26 |
27 | mod1.nlme <- nlme::lme(fixed = yield ~ gen * date * densf,
28 | random = ~ 1|block,
29 | weights = NULL, # default, i.e. homoscedastic errors
30 | data = dat)
31 |
32 | mod4.nlme <- mod1.nlme %>%
33 | update(weights = varComb(varIdent(form=~1|date),
34 | varIdent(form=~1|densf)))
35 |
36 | mod5.nlme <- mod1.nlme %>%
37 | update(weights = varIdent(form=~1|date_densf))
38 |
39 | mod1.nlme.VC <- tibble(grp="homoscedastic", varStruct=1) %>%
40 | mutate(sigma = mod1.nlme$sigma) %>%
41 | mutate(StandardError = sigma*varStruct) %>%
42 | mutate(Variance = StandardError^2)
43 |
44 | mod4.nlme.varStruct.A <- mod4.nlme$modelStruct$varStruct$A %>%
45 | coef(unconstrained=FALSE, allCoef=TRUE) %>%
46 | enframe(name="grpA", value="varStructA")
47 |
48 | mod4.nlme.varStruct.B <- mod4.nlme$modelStruct$varStruct$B %>%
49 | coef(unconstrained=FALSE, allCoef=TRUE) %>%
50 | enframe(name="grpB", value="varStructB")
51 |
52 | mod4.nlme.VC <- expand.grid(mod4.nlme.varStruct.A$grpA,
53 | mod4.nlme.varStruct.B$grpB,
54 | stringsAsFactors=FALSE) %>%
55 | rename(grpA=Var1, grpB=Var2) %>%
56 | left_join(x=., y=mod4.nlme.varStruct.A, by="grpA") %>%
57 | left_join(x=., y=mod4.nlme.varStruct.B, by="grpB") %>%
58 | mutate(sigma = mod4.nlme$sigma) %>%
59 | mutate(StandardError = sigma*varStructA*varStructB) %>%
60 | mutate(Variance = StandardError^2)
61 |
62 | mod5.nlme.VC <- mod5.nlme$modelStruct$varStruct %>%
63 | coef(unconstrained=FALSE, allCoef=TRUE) %>%
64 | enframe(name="grp", value="varStruct") %>%
65 | separate(grp, sep="[.]", into=c("grpA","grpB")) %>%
66 | mutate(sigma = mod5.nlme$sigma) %>%
67 | mutate(StandardError = sigma*varStruct) %>%
68 | mutate(Variance = StandardError^2)
69 | } # get nlme VC from het diag example
70 |
71 | setup <- dat %>%
72 | filter(block=="B1") %>%
73 | arrange(date, density) %>%
74 | dplyr::select(-yield) %>%
75 | mutate(label=paste0(date_densf,".",block),
76 | nID=1:n())
77 |
78 | {
79 | mat1 <- left_join(x = setup %>% mutate(grp="homoscedastic"),
80 | y = mod1.nlme.VC %>% dplyr::select(-StandardError) ,
81 | by = c("grp"="grp")) %>%
82 | left_join(x = expand.grid(X=.$nID, Y=.$nID),
83 | y = .,
84 | by = c("X"="nID")) %>% as_tibble() %>%
85 | mutate(Variance = case_when(X==Y~Variance, TRUE~NA_real_))
86 |
87 | mat4 <- left_join(x = setup,
88 | y = mod4.nlme.VC %>% dplyr::select(-StandardError),
89 | by = c("date"="grpA", "densf"="grpB")) %>%
90 | left_join(x = expand.grid(X=.$nID, Y=.$nID),
91 | y = .,
92 | by = c("X"="nID")) %>% as_tibble() %>%
93 | mutate(Variance = case_when(X==Y~Variance, TRUE~NA_real_))
94 |
95 | mat5 <- left_join(x = setup,
96 | y = mod5.nlme.VC %>% dplyr::select(-StandardError),
97 | by = c("date"="grpA", "densf"="grpB")) %>%
98 | left_join(x = expand.grid(X=.$nID, Y=.$nID),
99 | y = .,
100 | by = c("X"="nID")) %>% as_tibble() %>%
101 | mutate(Variance = case_when(X==Y~Variance, TRUE~NA_real_))
102 | } # get mat1 - mat5
103 | ```
104 |
105 | Here you will find a list of variance structures (*a.k.a* covariance structures, variance-covariance-structures, correlation structures) with short explanations and possibly examples.
106 |
107 | # IID - Independent & Identically Distributed
108 | **This covariance structure has homogeneous variances and zero correlation between elements.**
109 |
110 | Number of parameters = 1 (*i.e.* $\sigma$)
111 |
112 | $$
113 | \left(\begin{array}{cc}
114 | \sigma^2 & 0 & 0 & 0\\
115 | & \sigma^2 & 0 & 0\\
116 | & & \sigma^2 & 0\\
117 | & & & \sigma^2\\
118 | \end{array}\right) =
119 | \left(\begin{array}{cc}
120 | 1 & 0 & 0 & 0\\
121 | & 1 & 0 & 0\\
122 | & & 1 & 0\\
123 | & & & 1\\
124 | \end{array}\right) \sigma^2
125 | $$
126 |
127 |
128 | This is the simplest covariance structure and the default setting in most, if not all, linear modelling packages.
129 |
130 | # Diagonal
131 | **This covariance structure has heterogenous variances and zero correlation between elements.**
132 |
133 | Number of parameters: $t$ (*i.e.* $\sigma_1$, $\sigma_2$, ..., $\sigma_t$), which is the overall dimension of the covariance matrix (*e.g.* number of treatement levels).
134 |
135 | $$
136 | \left(\begin{array}{cc}
137 | \sigma_1^2 & 0 & 0 & 0\\
138 | & \sigma_2^2 & 0 & 0\\
139 | & & \sigma_3^2 & 0\\
140 | & & & \sigma_4^2\\
141 | \end{array}\right) =
142 | \left(\begin{array}{cc}
143 | 1 & 0 & 0 & 0\\
144 | & k_1 & 0 & 0\\
145 | & & k_2 & 0\\
146 | & & & k_3\\
147 | \end{array}\right) \sigma^2
148 | $$
149 |
150 | In our [chapter on heterogeneous error variances](heterogeneous_error_variance.html){target="_blank"}, we fit models in which we allow for different error variances for two of the treatments. Thus, the off-diagonals are all 0, but there are multiple variances on the diagonal. More specifically, in `mod5` we allows for 8 different error variances - one for each factor-level-combination of the respective factor effects `date` and `density`. This is visualized in the plot below as 8 different colors. Speaking in the [syntax of `nlme`](https://cran.r-project.org/web/packages/nlme/nlme.pdf#Rfn.nlmeStruct.1){target="_blank"}, we obtain 8 parameter estimates: 1 estimate for the [model-object's `sigma`](https://cran.r-project.org/web/packages/nlme/nlme.pdf#Rfn.nlmeObject.1){target="_blank"} (= standard deviation for error term) and 7 estimates (that are different from 1) in the [model-object's `varStruct`](https://cran.r-project.org/web/packages/nlme/nlme.pdf#Rfn.nlmeStruct.1){target="_blank"} as can be seen on the y-axis:
151 |
152 | ```{r, echo=FALSE}
153 | MAT <- mat5
154 | labs <- MAT %>%
155 | dplyr::select(X, date_densf, gen, varStruct) %>% unique
156 |
157 | ggplot(data=MAT, aes(x=X, y=Y)) + coord_fixed() +
158 | geom_tile(aes( fill=Variance), color="grey") +
159 | scale_fill_viridis(option="D", na.value="white",
160 | guide ="legend", name="Variance\nEstimate",
161 | breaks = MAT %>% pull(Variance) %>% unique %>% sort,
162 | labels = scales::number_format(accuracy = 0.01)) +
163 | scale_x_continuous(name = "date-density-combination",
164 | expand = c(0,0),
165 | breaks = labs %>% pull(X),
166 | labels = labs %>% pull(date_densf),
167 | sec.axis = sec_axis(~ .,
168 | name = "genotype",
169 | breaks = labs %>% pull(X),
170 | labels = labs %>% pull(gen))) +
171 | scale_y_continuous(name = "VarStruct date-density-combination",
172 | trans = "reverse",
173 | expand = c(0,0),
174 | breaks = labs %>% pull(X),
175 | labels = labs %>% pull(varStruct) %>% round(2)) +
176 | theme(legend.text.align = 1,
177 | axis.ticks.x = element_line(color="grey"),
178 | axis.title.x = element_text(color="grey"),
179 | axis.text.x = element_text(angle=90, hjust=1, color="grey"),
180 | legend.position = "right")
181 | ```
182 |
183 | > In order to give a clearer picture, the variance matrix presented here was reduced to data of a single block in order to have dimensions 16x16. Since there were [4 complete blocks in the dataset](heterogeneous_error_variance.html){target="_blank"}, the entire variance matrix of the error term has dimensions 64x64. However, given that data/errors are sorted accordingly, our presented matrix is simply 1 out of 4 blocks in a [block diagonal matrix](https://www.wikiwand.com/en/Block_matrix#/Block_diagonal_matrices){target="_blank"}.
184 |
185 | # First order autoregressive AR(1)
186 |
187 | **This covariance structure has homogeneous variances, while the correlation between any two elements gets smaller the further apart they are separated (e.g. in terms of time or space).**
188 |
189 | Number of parameters: 2 (*i.e.* $\sigma$ and $\rho$).
190 |
191 | $$
192 | \left(\begin{array}{cc}
193 | \sigma^2 & \sigma^2\rho & \sigma^2\rho^2 & \sigma^2\rho^3\\
194 | & \sigma^2 & \sigma^2\rho & \sigma^2\rho^2\\
195 | & & \sigma^2 & \sigma^2\rho\\
196 | & & & \sigma^2\\
197 | \end{array}\right) =
198 | \left(\begin{array}{cc}
199 | 1 & \rho & \rho^2 & \rho^3\\
200 | & 1 & \rho & \rho^2\\
201 | & & 1 & \rho\\
202 | & & & 1\\
203 | \end{array}\right) \sigma^2
204 | $$
205 |
206 | As can be seen, the correlation between any two elements can be described more speficically as: it is equal to $\rho$ for adjacent elements, $\rho^2$ for elements that are separated by a third, and so on. Note that since it is a correlation, we have -1 < $\rho$ < 1 and therefore $\rho$ indeed gets smaller when squared etc. This correlation model is useful, if all time points are equally spaced.
207 |
208 | As an explicit example, take the correlation between errors of two adjacent time points, in this case weeks, to be $\rho=0.9$. The correlation between errors that are two weeks apart is then $\rho^2=0.9^2=0.81$ and when they are three weeks apart it is $\rho^3=0.9^3=0.729$ and so on. Thus, the advantage here is that correlations become smaller over time and thus we have different correlation estimates, yet only a single correlation parameter $\rho$ is fitted in the model.
209 |
210 | # Multiplicative
211 | **It is possible to combine any two or more variance structures via direct multiplication *a.k.a.* the [Kronecker product](https://www.wikiwand.com/en/Kronecker_product){target="_blank"}.**
212 |
213 | $$
214 | \left(\begin{array}{cc}
215 | 1 & 0 \\
216 | & k_1 \\
217 | \end{array}\right)
218 | \otimes
219 | \left(\begin{array}{cc}
220 | 1 & 0 & 0 \\
221 | & k_2 & 0 \\
222 | & & k_3 \\
223 | \end{array}\right) \sigma^2
224 | =
225 | \left(\begin{array}{cc}
226 | 1\cdot1 & 0 & 0 & 0 & 0 & 0 \\
227 | & 1\cdot k_2 & 0 & 0 & 0 & 0 \\
228 | & & 1\cdot k_3 & 0 & 0 & 0 \\
229 | & & & k_1\cdot 1 & 0 & 0 \\
230 | & & & & k_1\cdot k_2 & 0 \\
231 | & & & & & k_1\cdot k_3 \\
232 | \end{array}\right) \sigma^2
233 | $$
234 |
235 |
236 | This operation on two matrices of arbitrary size resulting in a block matrix is sometimes denoted by $\otimes$. To give an example, we refer to `mod4` in the [chapter on heterogeneous error variances](heterogeneous_error_variance.html){target="_blank"}. Here, a multiplicative variance structure results from the kronecker product of two diagonal variance structures. The first diagonal variance structure allows for different variances for the 2 levels of `date`, while the second diagonal variance structure allows for different variances for the 4 levels of `density`. Their Kronecker product therefore results in 8 different variances, visualized in the plot below as 8 different colors.
237 |
238 | ```{r, echo=FALSE}
239 | MAT <- mat4
240 | labs <- MAT %>%
241 | dplyr::select(X, date_densf, gen, varStructA, varStructB) %>% unique
242 |
243 | ggplot(data=MAT, aes(x=X, y=Y)) + coord_fixed() +
244 | geom_tile(aes( fill=Variance), color="grey") +
245 | scale_fill_viridis(option="D", na.value="white",
246 | guide ="legend", name="Variance\nEstimate",
247 | breaks = MAT %>% pull(Variance) %>% unique %>% sort,
248 | labels = scales::number_format(accuracy = 0.01)) +
249 | scale_x_continuous(name = "date-density-combination",
250 | expand = c(0,0),
251 | breaks = labs %>% pull(X),
252 | labels = labs %>% pull(date_densf),
253 | sec.axis = sec_axis(~ .,
254 | name = "genotype",
255 | breaks = labs %>% pull(X),
256 | labels = labs %>% pull(gen))) +
257 | scale_y_continuous(name = "VarStruct density",
258 | trans = "reverse",
259 | expand = c(0,0),
260 | breaks = labs %>% pull(X),
261 | labels = labs %>% pull(varStructB) %>% round(2),
262 | sec.axis = sec_axis(~ .,
263 | name = "VarStruct date",
264 | breaks = labs %>% pull(X),
265 | labels = labs %>% pull(varStructA) %>% round(2))) +
266 | theme(legend.text.align = 1,
267 | axis.ticks.x = element_line(color="grey"),
268 | axis.title.x = element_text(color="grey"),
269 | axis.text.x = element_text(angle=90, hjust=1, color="grey"),
270 | legend.position = "right")
271 | ```
272 |
273 | ## Advantage
274 |
275 | One may now ask where the difference lies between this multiplicative variance structure for `mod4` on the one hand, and the simple diagonal variance structure for all 8 `date`-`density`-combinations in `mod5` (see [diagonal section above](#Diagonal)) on the other hand. The question comes intuitively, since both lead to obtaining 8 different variance estimates for the error term. However, while the combinations for which the 8 estimates are obtained are the same, the estimates themselves are different between `mod4` and `mod5`. In order to understand this, one must realize that fewer parameters need to be estimated here for `mod4` (= 6 parameters) compared to the simple diagonal variance structure for [`mod5`](#Diagonal) (= 8 parameters) - even though both result in 8 different variance estimates! One can retrace this manually by counting the number of `varStruct` values on the y-axes of the two plots. There should be 5 values for `mod4` and 7 values for `mod5` **that are not equal to 1** and in addition, [`sigma`](https://cran.r-project.org/web/packages/nlme/nlme.pdf#Rfn.nlmeObject.1){target="_blank"} (= standard deviation for error term) itself is the *missing* parameter here.
276 |
277 | Therefore, **direct multiplication can lead to the desired structure with fewer parameters needing to be estimated**. Notice that the number of parameters penalizes the AIC and therefore has a direct impact on model selection decisions. In the underlying [chapter on heterogeneous error variances](heterogeneous_error_variance.html){target="_blank"}, `mod4` (= multiplicative) is indeed chosen over `mod5` based on the AIC.
278 |
279 | # Summary
280 |
281 | ```{r, echo=FALSE}
282 | tribble(
283 | ~`Variance Structure`, ~total, ~var, ~cor,~nlme, ~lme4, ~glmmTMB, ~sommer, ~SAS,
284 | "Identitiy", "1", "1", "0" ,"default" ,"default","default","default","VC",
285 | "Diagonal", "t", "t", "0" ,"varIdent", "--", "diag", "ds","UN(1)",
286 | "First order autoregressive ", "2", "1", "1" ,"corAR1" , "--", "ar1", "AR1","AR(1)"
287 | ) %>%
288 | kable(escape = FALSE) %>%
289 | kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
290 | full_width = FALSE) %>%
291 | add_header_above(c(" ",
292 | "number of parameters"=3,
293 | "name in package"=5)) %>%
294 | footnote(general = "t = overall dimension of the covariance matrix (e.g. number of treatement levels).")
295 | ```
296 |
297 |
298 | # More on this
299 |
300 | [ASReml-R documentation](https://asreml.kb.vsni.co.uk/wp-content/uploads/sites/3/2018/02/ASReml-R-Reference-Manual-4.pdf#section.4.2){target="_blank"}
301 |
302 | [SAS documentation](https://documentation.sas.com/?docsetId=statug&docsetTarget=statug_mixed_syntax14.htm&docsetVersion=14.3&locale=en#statug.mixed.repeatedstmt_type){target="_blank"}
303 |
304 | [SPSS documentation](https://www.ibm.com/support/knowledgecenter/SSLVMB_23.0.0/spss/advanced/covariance_structures.html){target="_blank"}
305 |
306 | in progress
307 |
--------------------------------------------------------------------------------