├── .Rbuildignore
├── .gitignore
├── .travis.yml
├── DESCRIPTION
├── NAMESPACE
├── NEWS.md
├── R
├── anova_contrasts.R
├── contest.R
├── contrast_utils.R
├── data_documentation.R
├── drop1.R
├── estimability.R
├── legacy.R
├── lmer.R
├── lmerTest.R
├── lmer_anova.R
├── lmer_summary.R
├── ls_means.R
├── ranova.R
├── step.R
├── terms_utils.R
└── utils.R
├── README.md
├── data
├── TVbo.rda
├── carrots.rda
└── ham.rda
├── inst
├── CITATION
└── testdata
│ ├── legacy_fits.RData
│ ├── potdata.RData
│ └── test_paper_objects.RData
├── man
├── TVbo.Rd
├── anova.lmerModLmerTest.Rd
├── as.data.frame.ls_means.Rd
├── as_lmerModLmerTest.Rd
├── carrots.Rd
├── containment.Rd
├── contest.Rd
├── contest.lmerModLmerTest.Rd
├── contest1D.lmerModLmerTest.Rd
├── contestMD.lmerModLmerTest.Rd
├── devfun_vp.Rd
├── doolittle.Rd
├── drop1.lmerModLmerTest.Rd
├── ensure_full_rank.Rd
├── get_Fstat_ddf.Rd
├── get_contrasts_type1.Rd
├── get_contrasts_type3.Rd
├── get_covbeta.Rd
├── get_model.Rd
├── get_model_matrix.Rd
├── get_rdX.Rd
├── ham.Rd
├── is_estimable.Rd
├── legacy.Rd
├── lmer.Rd
├── lmerModLmerTest-class.Rd
├── lmerTest-package.Rd
├── ls_means.Rd
├── ls_means.lmerModLmerTest.Rd
├── merModLmerTest-class.Rd
├── nullspace.Rd
├── plot.ls_means.Rd
├── plot.step_list.Rd
├── qform.Rd
├── ranova.Rd
├── rbindall.Rd
├── rm_complete_terms.Rd
├── show_tests.Rd
├── show_tests.anova.Rd
├── show_tests.ls_means.Rd
├── single_anova.Rd
├── step.Rd
├── step.lmerModLmerTest.Rd
├── summary.lmerModLmerTest.Rd
└── term_contain.Rd
├── misc
├── copyright_header.txt
└── modify_copyright_header.R
├── pkg_notes
├── Satterthwaite_for_LMMs.Rmd
├── Satterthwaite_for_LMMs.html
├── Satterthwaite_for_LMMs.md
├── Satterthwaite_for_LMMs.pdf
├── implementation.Rmd
├── implementation.html
├── implementation_notes.Rmd
├── implementation_notes.html
├── new_lmerTest.Rmd
├── new_lmerTest.html
├── new_lmerTest.pdf
└── view_html.md
└── tests
├── test_a_utils.R
├── test_anova.R
├── test_compare_sas.R
├── test_contest1D.R
├── test_contestMD.R
├── test_contrast_utils.R
├── test_drop1.R
├── test_legacy.R
├── test_lmer.R
├── test_lmerTest_paper.R
├── test_ls_means.R
├── test_ranova_step.R
├── test_summary.R
├── test_zerovar.R
└── zlmerTest_zeroDenom.R
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^\.gitignore
4 | ^\.git$
5 | .*~$
6 | README.md
7 | NEWS.html
8 | ^build$
9 | ^revdep$
10 | ^revdep_archive$
11 | ^pkg_notes$
12 | ^misc$
13 | TODO.md
14 | .Rhistory
15 | ^.*\.Rproj$
16 | ^\.travis.yml$
17 |
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .Rproj.user
2 | .Rhistory
3 | .RData
4 | .Ruserdata
5 | lmerTestR.Rproj
6 | # Ignore all files ending with a 'tilde' (autogenerated by some
7 | # programs, e.g. emacs):
8 | *~
9 | revdep
10 | revdep_archive
11 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # .travis.yml for Travis CI
2 | # https://docs.travis-ci.com/user/languages/r
3 | # https://github.com/craigcitro/r-travis/wiki/Porting-to-native-R-support-in-Travis
4 |
5 | language: r
6 | r:
7 | - oldrel
8 | - release
9 | - devel
10 | cache: packages
11 | # helpful when preparing your package for submission to CRAN
12 | warnings_are_errors: true
13 | # No need for sudo as R is natively supported now.
14 | sudo: false
15 | # r_build_args: --no-build-vignettes
16 | # r_check_args: --as-cran --no-build-vignettes
17 |
18 | # chicago.bst not needed for the vignette bibliographi:
19 | # before_install:
20 | # - tlmgr install chicago
21 |
22 | # need to add nloptr this way to make it build in 'oldrel':
23 | addons:
24 | apt:
25 | packages:
26 | - libnlopt-dev
27 |
28 | env:
29 | global:
30 | - CRAN: http://cran.rstudio.com
31 |
32 | notifications:
33 | email:
34 | on_success: change
35 | on_failure: change
36 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: lmerTest
2 | Type: Package
3 | Title: Tests in Linear Mixed Effects Models
4 | Version: 3.1-3
5 | Authors@R: c(person("Alexandra", "Kuznetsova", role = c("aut")),
6 | person("Per", "Bruun Brockhoff", role = c("aut", "ths"),
7 | email = "perbb@dtu.dk"),
8 | person("Rune", "Haubo Bojesen Christensen", role = c("aut", "cre"),
9 | email = "Rune.Haubo@gmail.com"),
10 | person("Sofie", "Pødenphant Jensen", role=c("ctb"), email="sofp@dtu.dk"))
11 | Depends:
12 | R (>= 3.2.5),
13 | lme4 (>= 1.1-10),
14 | stats,
15 | methods
16 | Imports:
17 | numDeriv,
18 | MASS,
19 | ggplot2
20 | Suggests:
21 | pbkrtest (>= 0.4-3),
22 | tools
23 | Description: Provides p-values in type I, II or III anova and summary tables
24 | for lmer model fits (cf. lme4) via Satterthwaite's degrees of freedom method. A
25 | Kenward-Roger method is also available via the pbkrtest package. Model selection
26 | methods include step, drop1 and anova-like tables for random effects (ranova).
27 | Methods for Least-Square means (LS-means) and tests of linear contrasts of fixed
28 | effects are also available.
29 | License: GPL (>= 2)
30 | Encoding: UTF-8
31 | LazyData: true
32 | URL: https://github.com/runehaubo/lmerTestR
33 | BugReports: https://github.com/runehaubo/lmerTestR/issues
34 | RoxygenNote: 7.1.1
35 | Collate:
36 | 'anova_contrasts.R'
37 | 'contest.R'
38 | 'contrast_utils.R'
39 | 'data_documentation.R'
40 | 'drop1.R'
41 | 'estimability.R'
42 | 'legacy.R'
43 | 'lmer.R'
44 | 'lmerTest.R'
45 | 'lmer_anova.R'
46 | 'lmer_summary.R'
47 | 'ls_means.R'
48 | 'ranova.R'
49 | 'step.R'
50 | 'terms_utils.R'
51 | 'utils.R'
52 |
--------------------------------------------------------------------------------
/NAMESPACE:
--------------------------------------------------------------------------------
1 | # Generated by roxygen2: do not edit by hand
2 |
3 |
4 | if(getRversion() >= "3.3.0") {
5 | importFrom("stats", sigma)
6 | } else {
7 | export(sigma)
8 | }
9 |
10 | S3method(anova,lmerModLmerTest)
11 | S3method(anova,merModLmerTest)
12 | S3method(as.data.frame,ls_means)
13 | S3method(contest,lmerMod)
14 | S3method(contest,lmerModLmerTest)
15 | S3method(contest1D,lmerMod)
16 | S3method(contest1D,lmerModLmerTest)
17 | S3method(contestMD,lmerMod)
18 | S3method(contestMD,lmerModLmerTest)
19 | S3method(difflsmeans,lmerModLmerTest)
20 | S3method(difflsmeans,merModLmerTest)
21 | S3method(drop1,lmerModLmerTest)
22 | S3method(drop1,merModLmerTest)
23 | S3method(get_model,step_list)
24 | S3method(ls_means,lmerModLmerTest)
25 | S3method(ls_means,merModLmerTest)
26 | S3method(lsmeansLT,lmerModLmerTest)
27 | S3method(lsmeansLT,merModLmerTest)
28 | S3method(plot,ls_means)
29 | S3method(plot,step_list)
30 | S3method(print,ls_means)
31 | S3method(print,step_list)
32 | S3method(show_tests,anova)
33 | S3method(show_tests,default)
34 | S3method(show_tests,ls_means)
35 | S3method(step,default)
36 | S3method(step,lmerModLmerTest)
37 | S3method(step,merModLmerTest)
38 | S3method(summary,lmerModLmerTest)
39 | S3method(summary,merModLmerTest)
40 | S3method(update,lmerModLmerTest)
41 | export(as_lmerModLmerTest)
42 | export(calcSatterth)
43 | export(contest)
44 | export(contest1D)
45 | export(contestMD)
46 | export(difflsmeans)
47 | export(get_model)
48 | export(lmer)
49 | export(ls_means)
50 | export(lsmeansLT)
51 | export(rand)
52 | export(ranova)
53 | export(show_tests)
54 | export(step)
55 | exportClasses(lmerModLmerTest)
56 | exportClasses(merModLmerTest)
57 | importClassesFrom(lme4,lmerMod)
58 | importFrom(MASS,fractions)
59 | importFrom(MASS,ginv)
60 | importFrom(ggplot2,aes)
61 | importFrom(ggplot2,element_text)
62 | importFrom(ggplot2,facet_wrap)
63 | importFrom(ggplot2,geom_bar)
64 | importFrom(ggplot2,geom_errorbar)
65 | importFrom(ggplot2,ggplot)
66 | importFrom(ggplot2,rel)
67 | importFrom(ggplot2,scale_fill_manual)
68 | importFrom(ggplot2,theme)
69 | importFrom(ggplot2,xlab)
70 | importFrom(ggplot2,ylab)
71 | importFrom(graphics,plot)
72 | importFrom(lme4,findbars)
73 | importFrom(lme4,fixef)
74 | importFrom(lme4,getME)
75 | importFrom(lme4,lmerControl)
76 | importFrom(lme4,nobars)
77 | importFrom(methods,as)
78 | importFrom(methods,callNextMethod)
79 | importFrom(methods,is)
80 | importFrom(methods,new)
81 | importFrom(methods,signature)
82 | importFrom(numDeriv,hessian)
83 | importFrom(numDeriv,jacobian)
84 | importFrom(stats,.getXlevels)
85 | importFrom(stats,.lm.fit)
86 | importFrom(stats,anova)
87 | importFrom(stats,as.formula)
88 | importFrom(stats,coef)
89 | importFrom(stats,delete.response)
90 | importFrom(stats,drop.scope)
91 | importFrom(stats,drop1)
92 | importFrom(stats,formula)
93 | importFrom(stats,getCall)
94 | importFrom(stats,lm.fit)
95 | importFrom(stats,logLik)
96 | importFrom(stats,model.frame)
97 | importFrom(stats,model.matrix)
98 | importFrom(stats,nobs)
99 | importFrom(stats,pchisq)
100 | importFrom(stats,pf)
101 | importFrom(stats,printCoefmat)
102 | importFrom(stats,pt)
103 | importFrom(stats,qt)
104 | importFrom(stats,resid)
105 | importFrom(stats,setNames)
106 | importFrom(stats,terms)
107 | importFrom(stats,update)
108 | importFrom(stats,update.formula)
109 | importFrom(stats,vcov)
110 | importFrom(utils,as.roman)
111 | importFrom(utils,combn)
112 |
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 | lmerTest 3.1-3 (October 2020)
2 | ------------------
3 |
4 | - Update a test to accomodate `lme4::anova` reporting `NA` instead of `1` for p-value when df=0.
5 | - No longer print message about missing cells with mean centered covariates for type III anova tables (issue #19)
6 | - Fix step such that fixed effects are reduced even if all random effects are reduced away (issue #23).
7 |
8 | lmerTest 3.1-2 (April 2020)
9 | ------------------
10 |
11 | - Remove argument "..." to accomodate new version of `lme4` (from version `1.1-22`)
12 | - Minor fix to tests to accomodate new version of `lme4` (from version `1.1-22`)
13 |
14 | lmerTest 3.1-1
15 | ------------------
16 |
17 | - Sofie P Jensen is taking over as maintainer replacing Per B Brockhoff.
18 | - Fixing "noLD" CRAN issue (a check that ensures the package works on systems without long doubles). This was caused by an over sensitive test.
19 |
20 | lmerTest 3.1-0
21 | ------------------
22 |
23 | - Adding support for legacy model fits, i.e. `merModLmerTest` objects generated with lmerTest version `< 3.0-0`. This includes defining the `merModLmerTest` class and `anova`, `summary`, `drop1`, `ls_means`, `lsmeansLT` and `difflsmeans` methods. The usual `lme4` methods also work with objects of class `merModLmerTest`.
24 |
25 | lmerTest 3.0-1
26 | ------------------
27 |
28 | - over-sensitive tests (failing on Solaris) have reduced tolerance
29 | - `sigma` and `sigma.merMod` defined and exported for `R <= 3.3.0`
30 | - Warn if Kenward-Roger is used with `R <= 3.3.0` since it may give incorrect results
31 | - Add `lme4 (>= 1.1-10)` and `R (>= 3.2.5)` to `Depends` (last available version where `lmerTest` checks out)
32 | - `pbkrtest` package loaded conditional on availability in tests
33 |
34 |
35 | lmerTest 3.0-0
36 | ------------------
37 |
38 | * The new and completely re-written lmerTest package. Details of changes are
39 | available in [pdf](https://github.com/runehaubo/lmerTestR/blob/master/pkg_notes/new_lmerTest.pdf) or [html](http://htmlpreview.github.io/?https://github.com/runehaubo/lmerTestR/blob/master/pkg_notes/new_lmerTest.html)
40 |
41 |
42 | lmerTest < 3.0-0
43 | ------------------
44 |
45 | * Signficant news and changes for the 2.0-xx release series is provided below.
46 |
47 | 2.0-34
48 |
49 | - included citation info for JSS
50 |
51 | 2.0-33
52 |
53 | - lsmeans and difflsmeans are now deprecated functions. Changed the names to lsmeansLT and dlsmeansLT
54 | - changed the maintainer field
55 |
56 |
57 | 2.0-32
58 |
59 | - changed the message of identifiability to the more appropriate one
60 |
61 | 2.0-31
62 |
63 | - removed lmerTestFunctions.R and restructured the package. added calcSatterth(model, L) for calculating Satterthwaite's approximation for a specified L matrix
64 |
65 | 2.0-30
66 |
67 | - envir.R failed with the newest version of lme4. Changed the code to pass the check. TODO: remove updating the model
68 |
69 | 2.0-28
70 |
71 | - changes in general summary function. callNextMethod changed to as(model, "lmerMod)
72 |
73 | 2.0-25
74 |
75 | - updated according to comments from CRAN
76 |
77 | 2.0-24 changes:
78 |
79 | - cleaned the code
80 |
81 |
82 | 2.0-23 changes:
83 |
84 | - hessian and grad changed to mygrad and myhess (deriv.R functions of Rune)
85 | - plots use ggplot2
86 | - look for previous changes in R-Forge
87 |
88 | 2.0-11 changes:
89 |
90 | - elimRandEffs deleted. now the rand table contains all the information
91 |
92 | 2.0-9 changes:
93 |
94 | - fixed.calc option is added to step function
95 | - elimRand effs changed: random effects that are 1 approx to 1e-6 are eliminated
96 | - las=2 in barplots: verical axis names
97 | contrast with the name "l" changed to "l.lmerTest.private.contrasts"
98 |
99 | 2.0-8 changes:
100 |
101 | - throws error for lsmeans, difflsmeans, rand and step functions if the model does not inherit lmerMod class
102 |
103 | 2.0-7 changes:
104 |
105 | - in utils calcSatterth changed: solve of 0 dim matrix now catches in tryCatch - example MAMex.R in tests is added to check the bug
106 | - messages are printed if some computational errors occurr in anova or summary and the ones from lme4 are returned (bugSummary.R for testing)
107 |
108 | 2.0.6 changes:
109 |
110 | - added a number of tests in the tests folder and inst/datasets for the testing data sets - will not be included in the R-forge nor CRAN (for a moment)
111 | - model is not updated automatically to REML (tests for random effects are ML!)
112 | - man functions updated
113 |
114 | 2.0.5 changes:
115 |
116 | - fixed bug from Ben - summary(model, "lme4") changed to summary(model, ddf="lme4")
117 | - fixed bug for summary from Cyrus
118 | - added in manual notes regarding random coefficient models simplification
119 | - Rune changed solve to chol2inv in lmerTestFunctions.R
120 | - changed updateModel function so that the bugs with the environmentgs are solved
121 |
122 | 2.0.4 new:
123 |
124 | - rewritten rand table elimination
125 | - added elimrand.R
126 |
127 |
128 | Modifications in lmerTest 2.0.1
129 |
130 | - The elim.num column now has KEEP instead of 0
131 | - X'X deficiancy was fixed by Rune, lmerTest was fixed accordingly
132 |
--------------------------------------------------------------------------------
/R/data_documentation.R:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # Copyright (c) 2013-2020 Alexandra Kuznetsova, Per Bruun Brockhoff, and
3 | # Rune Haubo Bojesen Christensen
4 | #
5 | # This file is part of the lmerTest package for R (*lmerTest*)
6 | #
7 | # *lmerTest* is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 2 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # *lmerTest* is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # A copy of the GNU General Public License is available at
18 | # and/or
19 | # .
20 | #############################################################################
21 | #
22 | # data_documentation.R - roxygen2 documentation for datasets.
23 |
24 | # Datasets documented in this file:
25 | #
26 | # - carrots
27 | # - ham
28 | # - TVbo
29 |
30 | ##############################################
31 | ######## carrots
32 | ##############################################
33 | #' Consumer Preference Mapping of Carrots
34 | #'
35 | #' In a consumer study 103 consumers scored their preference of 12 danish
36 | #' carrot types on a scale from 1 to 7. Moreover the consumers scored the
37 | #' degree of sweetness, bitterness and crispiness in the products.
38 | #'
39 | #' The carrots were harvested in autumn 1996 and tested in march 1997. In
40 | #' addition to the consumer survey, the carrot products were evaluated by
41 | #' a trained panel of tasters, the sensory panel, with respect to a
42 | #' number of sensory (taste, odour and texture) properties. Since usually
43 | #' a high number of (correlated) properties (variables) are used, in this
44 | #' case 14, it is a common procedure to use a few, often 2, combined
45 | #' variables that contain as much of the information in the sensory
46 | #' variables as possible. This is achieved by extracting the first two
47 | #' principal components in a principal components analysis (PCA) on the
48 | #' product-by-property panel average data matrix. In this data set the
49 | #' variables for the first two principal components are named
50 | #' (\code{sens1} and \code{sens2}).
51 | #'
52 | #' @docType data
53 | #'
54 | #' @usage data(carrots)
55 | #'
56 | #' @format
57 | #' \describe{
58 | #' \item{Consumer}{factor with 103 levels: numbering identifying consumers.}
59 | #' \item{Frequency}{factor with 5 levels; "How often do you eat carrots?"
60 | #' 1: once a week or more, 2: once
61 | #' every two weeks, 3: once every three weeks, 4: at least once month,
62 | #' 5: less than once a month.}
63 | #' \item{Gender}{factor with 2 levels. 1: male, 2:female.}
64 | #' \item{Age}{factor with 4 levels. 1: less than 25 years, 2: 26-40 years,
65 | #' 3: 41-60 years, 4 more than 61 years.}
66 | #' \item{Homesize}{factor with two levels. Number of persons in the household.
67 | #' 1: 1 or 2 persons, 2: 3 or more persons.}
68 | #' \item{Work}{factor with 7 levels. different types of employment.
69 | #' 1: unskilled worker(no education),
70 | #' 2: skilled worker(with education), 3: office worker, 4: housewife (or man),
71 | #' 5: independent
72 | #' businessman/ self-employment, 6: student, 7: retired}
73 | #' \item{Income}{factor with 4 levels. 1: <150000, 2: 150000-300000,
74 | #' 3: 300000-500000, 4: >500000}
75 | #' \item{Preference}{consumer score on a seven-point scale.}
76 | #' \item{Sweetness}{consumer score on a seven-point scale.}
77 | #' \item{Bitterness}{consumer score on a seven-point scale.}
78 | #' \item{Crispness}{consumer score on a seven-point scale.}
79 | #' \item{sens1}{first sensory variable derived from a PCA.}
80 | #' \item{sens2}{second sensory variable derived from a PCA.}
81 | #' \item{Product}{factor on 12 levels.}
82 | #' }
83 | #'
84 | #' @keywords datasets
85 | #' @source Per Bruun Brockhoff, The Royal Veterinary and Agricultural University,
86 | #' Denmark.
87 | #'
88 | #' @examples
89 | #'
90 | #' fm <- lmer(Preference ~ sens2 + Homesize + (1 + sens2 | Consumer), data=carrots)
91 | #' anova(fm)
92 | #'
93 | "carrots"
94 |
95 |
96 | ##############################################
97 | ######## ham
98 | ##############################################
99 | #' Conjoint Study of Dry Cured Ham
100 | #'
101 | #' One of the purposes of the study was to investigate the effect of
102 | #' information given to the consumers measured in hedonic liking for the
103 | #' hams. Two of the hams were Spanish and two were Norwegian, each origin
104 | #' representing different salt levels and different aging time. The
105 | #' information about origin was given in such way that both true and
106 | #' false information was given. Essentially a 4x2 design with 4 samples
107 | #' and 2 information levels. A total of 81 Consumers participated in the
108 | #' study.
109 | #'
110 | #' @docType data
111 | #'
112 | #' @usage data(ham)
113 | #'
114 | #' @format
115 | #' \describe{
116 | #' \item{Consumer}{factor with 81 levels: numbering identifying consumers.}
117 | #' \item{Product}{factor with four levels.}
118 | #' \item{Informed.liking}{numeric: hedonic liking for the products.}
119 | #' \item{Information}{factor with two levels.}
120 | #' \item{Gender}{factor with two levels.}
121 | #' \item{Age}{numeric: age of Consumer.}
122 | #' }
123 | #'
124 | #' @keywords datasets
125 | #'
126 | #' @references
127 | #' T. Næs, V. Lengard, S. Bølling Johansen, M. Hersleth (2010)
128 | #' Alternative methods for combining design variables and consumer preference
129 | #' with information about attitudes and demographics in conjoint analysis,
130 | #' \emph{Food Quality and Preference}, 10-4, 368-378, ISSN 0950-3293,
131 | #' \url{https://doi.org/10.1016/j.foodqual.2009.09.004}.
132 | #'
133 | #' @examples
134 | #'
135 | #' # Simple model for the ham data:
136 | #' fm <- lmer(Informed.liking ~ Product*Information + (1|Consumer) , data=ham)
137 | #'
138 | #' # Anova table for the fixed effects:
139 | #' anova(fm)
140 | #'
141 | #' \dontrun{
142 | #' # Fit 'big' model:
143 | #' fm <- lmer(Informed.liking ~ Product*Information*Gender*Age +
144 | #' + (1|Consumer) + (1|Consumer:Product) +
145 | #' (1|Consumer:Information),
146 | #' data=ham)
147 | #' step_fm <- step(fm)
148 | #' step_fm # Display elimination results
149 | #' final_fm <- get_model(step_fm)
150 | #' }
151 | #'
152 | "ham"
153 |
154 |
155 | ##############################################
156 | ######## TVbo
157 | ##############################################
158 | #' Sensory Assesment of B&O TVs
159 | #'
160 | #' The TVbo dataset has kindly been made available by the Danish high-end
161 | #' consumer electronics company
162 | #' \href{https://www.bang-olufsen.com}{Bang & Olufsen}.
163 | #' The main purpose was to assess 12 different TV sets (products) specified by
164 | #' the two attributes Picture and TVset.
165 | #' 15 different response variables (characteristics of the
166 | #' product) were assessed by a trained panel with 8 assessors.
167 | #'
168 | #' @format
169 | #' \describe{
170 | #' \item{Assessor}{factor with 8 levels assessors.}
171 | #' \item{TVset}{product factor with 3 levels.}
172 | #' \item{Picture}{product factor with 4 levels.}
173 | #' }
174 | #' In addition the following 15 numeric (response) variables are the
175 | #' characteristics on which the TV sets (products) are assessed:
176 | #'
177 | #' Coloursaturation, Colourbalance, Noise, Depth, Sharpness, Lightlevel,
178 | #' Contrast, Sharpnessofmovement, Flickeringstationary, Flickeringmovement,
179 | #' Distortion, Dimglasseffect, Cutting, Flossyedges, Elasticeffect.
180 | #'
181 | #' @docType data
182 | #'
183 | #' @usage data(TVbo)
184 | #'
185 | #' @examples
186 | #'
187 | #' fm <- lmer(Coloursaturation ~ TVset + Picture + (1|Assessor:TVset) +
188 | #' (1|Assessor), data=TVbo)
189 | #' ranova(fm)
190 | #' anova(fm)
191 | #'
192 | "TVbo"
193 |
--------------------------------------------------------------------------------
/R/drop1.R:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # Copyright (c) 2013-2020 Alexandra Kuznetsova, Per Bruun Brockhoff, and
3 | # Rune Haubo Bojesen Christensen
4 | #
5 | # This file is part of the lmerTest package for R (*lmerTest*)
6 | #
7 | # *lmerTest* is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 2 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # *lmerTest* is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # A copy of the GNU General Public License is available at
18 | # and/or
19 | # .
20 | #############################################################################
21 | #
22 | # drop1.R - drop1 method for lmerModLmerTest objects
23 |
24 | # ------- Contents: --------
25 | #
26 | # drop1.lmerModLmerTest
27 | #
28 | # --- Utility functions: ---
29 | #
30 | # get_Ldiffmat
31 | # get_Ldiffmat2
32 | #
33 |
34 | ##############################################
35 | ######## drop1.lmerModLmerTest
36 | ##############################################
37 | #' Drop Marginal Terms from Model
38 | #'
39 | #' Computes the F-test for all marginal terms, i.e. terms that can be dropped
40 | #' from the model while respecting the hierarchy of terms in the model.
41 | #'
42 | #' Simple marginal contrasts are used for all marginal terms unless the design
43 | #' matrix is rank deficient. In that case (and if \code{force_get_contrasts} is
44 | #' \code{TRUE}) the contrasts (i.e. restriction matrices on the design matrix
45 | #' of the full model) are computed by comparison of the design matrices
46 | #' for full and restricted models. The set of marginal terms considered for
47 | #' dropping are computed using \code{drop.scope(terms(object))}.
48 | #'
49 | #' Since all tests are based on tests of contrasts in the full model, no
50 | #' models are being (re)fitted.
51 | #'
52 | #' @param object an \code{\link{lmer}} model fit (of class
53 | #' \code{"lmerModLmerTest"}.)
54 | #' @param scope optional character vector naming terms to be dropped from the
55 | #' model. Note that only marginal terms can be dropped. To see which terms are
56 | #' marginal, use \code{drop.scope(terms(object))}.
57 | #' @param ddf the method for computing the denominator degrees of freedom and
58 | #' F-statistics. \code{ddf="Satterthwaite"} (default) uses Satterthwaite's method;
59 | #' \code{ddf="Kenward-Roger"} uses Kenward-Roger's method.
60 | #' \code{ddf = "lme4"} returns the \code{drop1} table for \code{merMod} objects
61 | #' as defined in package \pkg{lme4}.
62 | #' @param force_get_contrasts enforce computation of contrast matrices by a
63 | #' method in which the design matrices for full and restricted models are
64 | #' compared.
65 | #' @param ... currently not used.
66 | #'
67 | #' @author Rune Haubo B. Christensen
68 | #' @seealso \code{\link{ranova}} for tests of marginal random terms.
69 | #' @return An anova-like table with F-tests of marginal terms.
70 | #' @export
71 | #'
72 | #' @importFrom stats drop1 drop.scope terms formula
73 | #' @examples
74 | #'
75 | #' # Basic usage:
76 | #' fm <- lmer(angle ~ recipe + temp + (1|recipe:replicate), cake)
77 | #' drop1(fm) # Using Satterthwaite degrees of freedom
78 | #' if(requireNamespace("pbkrtest", quietly = TRUE))
79 | #' drop1(fm, ddf="Kenward-Roger") # Alternative DenDF and F-test method
80 | #' drop1(fm, ddf="lme4", test="Chi") # Asymptotic Likelihood ratio tests
81 | #'
82 | #' # Consider a rank-deficient design matrix:
83 | #' fm <- lmer(angle ~ recipe + temp + temperature + (1|recipe:replicate), cake)
84 | #' # Here temp accounts for the linear effect of temperature, and
85 | #' # temperature is an (ordered) factor that accounts for the remaining
86 | #' # variation between temperatures (4 df).
87 | #' drop1(fm)
88 | #' # While temperature is in the model, we cannot test the effect of dropping
89 | #' # temp. After removing temperature we can test the effect of dropping temp:
90 | #' drop1(lmer(angle ~ recipe + temp + (1|recipe:replicate), cake))
91 | #'
92 | #' # Polynomials:
93 | #' # Note that linear terms should usually not be dropped before squared terms.
94 | #' # Therefore 'Days' should not be dropped before 'I(Days^2)' despite it being
95 | #' # tested here:
96 | #' fm <- lmer(Reaction ~ Days + I(Days^2) + (Days|Subject), sleepstudy)
97 | #' drop1(fm)
98 | #' # Using poly() provides a test of the whole polynomial structure - not a
99 | #' # separate test for the highest order (squared) term:
100 | #' fm <- lmer(Reaction ~ poly(Days, 2) + (Days|Subject), sleepstudy)
101 | #' drop1(fm)
102 | #'
103 | drop1.lmerModLmerTest <- function(object, scope, ddf=c("Satterthwaite", "Kenward-Roger", "lme4"),
104 | force_get_contrasts=FALSE, ...) {
105 | ddf <- match.arg(ddf)
106 | if(ddf == "lme4") return(NextMethod())
107 | marg_terms <- drop.scope(terms(object))
108 | if(missing(scope)) scope <- marg_terms else {
109 | if(length(scope) == 0 || !is.character(scope))
110 | stop("'scope' should be a character vector naming terms to be dropped")
111 | if(!all(scope %in% marg_terms))
112 | stop("Only marginal terms can be dropped from the model")
113 | }
114 | # Get contrasts for marginal terms:
115 | X <- model.matrix(object)
116 | Llist <- get_contrasts_marginal(object)
117 | if(length(scope)) {
118 | Llist <- Llist[scope] # retain contrasts for terms in scope
119 | if(!is.null(attr(X, "col.dropped")) || force_get_contrasts) {
120 | # Compute L directly if model is rank deficient or force_get_contrasts is TRUE:
121 | orig_form <- formula(object)
122 | new_forms <- lapply(rm_complete_terms(scope, orig_form, random=FALSE), nobars)
123 | # Compute list of contrast matrices as 'diffs' to orig. X:
124 | Llist <- if(!length(new_forms)) list() else
125 | lapply(new_forms, function(form) {
126 | suppressWarnings(x <- model.matrix(form[-2], data=model.frame(object),
127 | contrasts.arg = attr(X, "contrasts")))
128 | L <- get_Ldiffmat2(x, X) # L may be length 0 if x == X (rank-deficint fits.)
129 | if(!length(L)) rep(NA_real_, ncol(X)) else L
130 | })
131 | }
132 | }
133 | # Compute anova-like table:
134 | aov <- rbindall(lapply(Llist, function(L) contestMD(object, L, ddf = ddf)))
135 | # Format results:
136 | method <- switch(ddf, "Satterthwaite" = "Satterthwaite's",
137 | "Kenward-Roger" = "Kenward-Roger's")
138 | attr(aov, "heading") <-
139 | c(paste("Single term deletions using", method, "method:"),
140 | "\nModel:", deparse2(formula(object)))
141 | attr(aov, "hypotheses") <- Llist
142 | attr(aov, "ddf") <- ddf
143 | class(aov) <- c("anova", "data.frame")
144 | aov
145 | }
146 |
147 |
148 | get_Ldiffmat <- function(A0, A) {
149 | Rank <- function(X) qr(X)$rank
150 | Q <- qr.Q(qr(cbind(A0, A)))
151 | rA0 <- Rank(A0)
152 | rA <- Rank(A)
153 | set <- if(rA0 < rA) (rA0+1):rA else numeric(0L)
154 | Q2 <- Q[, set, drop=FALSE]
155 | L <- t(Q2) %*% A
156 | L <- t(qr.Q(qr(t(L)))) # Orthonormalize contrast
157 | L
158 | }
159 |
160 | #' @importFrom stats .lm.fit resid
161 | get_Ldiffmat2 <- function(X0, X) {
162 | # X : design matrix for the full model
163 | # X0: design matrix for the restricted model
164 | # R is the residual of the orthogonal projection of X on X0, thus
165 | # R is orthogonal to X0 and a subspace of X, and
166 | # Lt is a restriction matrix on X.
167 | R <- resid(.lm.fit(x=X0, y=X))
168 | R <- R[, colSums(abs(R)) > 1e-8]
169 | Lt <- crossprod(X, R)
170 | Lt[] <- zapsmall(qr.Q(qr(Lt))) # orthonormalize contrasts
171 | t(Lt)
172 | }
173 |
--------------------------------------------------------------------------------
/R/estimability.R:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # Copyright (c) 2013-2020 Alexandra Kuznetsova, Per Bruun Brockhoff, and
3 | # Rune Haubo Bojesen Christensen
4 | #
5 | # This file is part of the lmerTest package for R (*lmerTest*)
6 | #
7 | # *lmerTest* is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 2 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # *lmerTest* is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # A copy of the GNU General Public License is available at
18 | # and/or
19 | # .
20 | #############################################################################
21 | #
22 | # estimability.R - functions for assessing model estimability
23 |
24 | # ------- Contents: --------
25 | #
26 | # is_estimable
27 | # nullspace
28 | #
29 |
30 |
31 | ##############################################
32 | ######## is_estimable
33 | ##############################################
34 | #' Estimability of Contrasts
35 | #'
36 | #' Computes the estimability of a vector or matrix of contrasts (i.e. linear
37 | #' functions of the coefficients) from the nullspace of a design matrix or
38 | #' potentially directly from the design matrix.
39 | #'
40 | #' @param contrast a numeric matrix where each row is a contrast vector for
41 | #' which estimability is computed. The matrix should have as many columns as
42 | #' there are columns in the design matrix (which equals the number of
43 | #' coefficients). If \code{contrast} is a vector it is coerced to a matrix.
44 | #' @param nullspace the nullspace of the design matrix.
45 | #' @param X design matrix.
46 | #' @param tol tolerance for determining if a contrast is orthogonal to the
47 | # nullspace.
48 | #'
49 | #' @return a logical vector of length \code{nrow(contrast)} determining if each
50 | #' contrast is estimable
51 | #' @importFrom stats setNames
52 | #' @keywords internal
53 | #' @seealso \code{\link{nullspace}}
54 | #'
55 | #' @author Rune Haubo B. Christensen
56 | #' @keywords internal
57 | #' @examples
58 | #'
59 | #' # FIXME: We need some examples here
60 | #'
61 | is_estimable <- function(contrast, nullspace=NULL, X=NULL,
62 | tol=sqrt(.Machine$double.eps)) {
63 | if(!is.matrix(contrast)) contrast <- matrix(contrast, ncol=length(contrast))
64 | N <- if(!is.null(nullspace)) { # get nullspace
65 | nullspace
66 | } else if(!is.null(X)) {
67 | nullspace(X)
68 | } else {
69 | stop("Need non-null 'nullspace' or 'X' to compute estimability")
70 | }
71 | if(ncol(contrast) != nrow(N))
72 | stop(sprintf("'contrast' has %i columns: expecting %i columns",
73 | ncol(contrast), nrow(N)))
74 | # Determine estimability:
75 | res <- if(length(N) == 0) rep(TRUE, nrow(contrast)) else
76 | c(abs(rowSums(contrast %*% N)) < tol)
77 | setNames(res, rownames(contrast))
78 | }
79 | #
80 | # XX <- model.matrix(terms(model), data=model.frame(model))
81 | # nullspaceX <- nullspace(XX)
82 | # is_estimable(Llist$DAY, nullspaceX)
83 | # is_estimable(c(Llist$DAY[1, ]), nullspaceX)
84 | # is_estimable(Llist$DAY, X=XX)
85 | # NCOL(0:1)
86 | #
87 | # X <- model.matrix(model)
88 | # str(Llist$DAY[, -9] %*% nullspace(X))
89 | # is_estimable(Llist$DAY[, -9], X=X)
90 | # is_estimable(0:1, X=X)
91 | # contrast <- 0:1
92 | # nrow(matrix(0:1, ncol=2))
93 | # rep(TRUE, 1)
94 | #
95 | # length(Llist$DAY[, -9] %*% nullspace(X))
96 | # apply(Llist$DAY[, -9] %*% nullspace(X), 1, length)
97 | # length(nullspace(X))
98 |
99 | ##############################################
100 | ######## nullspace
101 | ##############################################
102 | #' Nullspace
103 | #'
104 | #' Compute the (right or left) nullspace of matrix using a (semi-complete)
105 | #' Singular Value Decomposition.
106 | #'
107 | #' This implementation is fastest on matrices with more rows
108 | #' than columns such as a typical design matrix for a linear model.
109 | #'
110 | #' @param A a numeric matrix.
111 | #' @param type \code{"right"} (default) gives is the standard nullspace,
112 | #' \code{"left"} gives left nullspace of \code{A}.
113 | #' @param tol tolerance multiple of the first singular value to determine if
114 | #' subsequent singular values are (sufficiently) positive to be determined
115 | #' greater than zero.
116 | #'
117 | #' @return a matrix with as many rows as there are columns in \code{A}. The
118 | #' number of columns (which may be zero) determine the dimensionality of the
119 | #' nullspace of \code{A}.
120 | #' @author Rune Haubo B. Christensen
121 | #'
122 | #' @keywords internal
123 | #' @examples
124 | #'
125 | #' # FIXME: We need some examples here
126 | #'
127 | nullspace <- function(A, type = c("right", "left"),
128 | tol=sqrt(.Machine$double.eps)) {
129 | # Compute the right (standard and default) or left null space of a matrix A.
130 | # using SVD.
131 | type <- match.arg(type)
132 | if(type == "left") return(nullspace(t(A), type="right", tol=tol))
133 | if(length(A) == 0L) return(matrix(numeric(0L))) # length(A) == 0 if any(dim(A) == 0)
134 | svdA <- svd(A, nv = ncol(A))
135 | tol <- 1e-8
136 | positive <- svdA$d > max(tol * svdA$d[1L], 0)
137 | rank <- sum(positive)
138 | set <- if(rank == 0) 1:ncol(A) else -(1:rank)
139 | svdA$v[, set, drop=FALSE]
140 | }
141 |
142 |
143 |
--------------------------------------------------------------------------------
/R/legacy.R:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # Copyright (c) 2013-2020 Alexandra Kuznetsova, Per Bruun Brockhoff, and
3 | # Rune Haubo Bojesen Christensen
4 | #
5 | # This file is part of the lmerTest package for R (*lmerTest*)
6 | #
7 | # *lmerTest* is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 2 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # *lmerTest* is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # A copy of the GNU General Public License is available at
18 | # and/or
19 | # .
20 | #############################################################################
21 | #
22 | # legacy.R - support for lecacy 'merModLmerTest' objects.
23 |
24 | # ------- Contents: --------
25 | #
26 | # --- Classes: ---
27 | #
28 | # merModLmerTest
29 | #
30 | # --- methods: ---
31 | #
32 | # anova.merModLmerTest
33 | # summary.merModLmerTest
34 | # ls_means.merModLmerTest
35 | # lsmeansLT.merModLmerTest
36 | # difflsmeans.merModLmerTest
37 | # drop1.merModLmerTest
38 | #
39 |
40 | ##############################################
41 | ######## merModLmerTest class
42 | ##############################################
43 | #' Legacy lmerTest representation of Linear Mixed-Effects Models
44 | #'
45 | #' The \code{merModLmerTest} class extends \code{lmerMod} (which extends
46 | #' \code{merMod}) from the \pkg{lme4}-package.
47 | #'
48 | #' @export
49 | #' @keywords internal
50 | #' @author Rune Haubo B. Christensen
51 | #' @importClassesFrom lme4 lmerMod
52 | merModLmerTest <- setClass("merModLmerTest", contains = c("lmerMod"))
53 |
54 | ##############################################
55 | ######## anova method for merModLmerTest
56 | ##############################################
57 | #' Methods for Legacy lmerTest Objects
58 | #'
59 | #' Methods are defined for legacy lmerTest objects of class
60 | #' \code{merModLmerTest} generated with \pkg{lmerTest} version \code{< 3.0-0}.
61 | #' These methods are defined by interfacing code for \code{lmerModLmerTest}
62 | #' methods and therefore behaves like these methods do (which may differ from
63 | #' the behavior of \pkg{lmerTest} version \code{< 3.0-0}.)
64 | #'
65 | #' @inheritParams anova.lmerModLmerTest
66 | #' @param ... for the anova method optionally additional models; for other
67 | #' methods see the corresponding \code{lmerModLmerTest} methods for details.
68 | #' @rdname legacy
69 | #' @aliases legacy
70 | #' @keywords internal
71 | #' @author Rune Haubo B. Christensen
72 | #' @export
73 | #' @examples
74 | #' # Load model fits fm1 and fm2 generated with lmerTest version 2.3-37:
75 | #' load(system.file("testdata","legacy_fits.RData", package="lmerTest"))
76 | #'
77 | #' # Apply some methods defined by lmerTest:
78 | #' anova(fm1)
79 | #' summary(fm1)
80 | #' contest(fm1, c(0, 1))
81 | #' contest(fm1, c(0, 1), joint=FALSE)
82 | #' drop1(fm1)
83 | #' ranova(fm1)
84 | #'
85 | #' # lme4-methods also work:
86 | #' fixef(fm1)
87 | #'
88 | #' # Ditto for second model fit:
89 | #' anova(fm2)
90 | #' summary(fm2)
91 | #' ls_means(fm2)
92 | #' difflsmeans(fm2)
93 | anova.merModLmerTest <- function(object, ..., type = c("III", "II", "I", "3", "2", "1"),
94 | ddf = c("Satterthwaite", "Kenward-Roger", "lme4")) {
95 | class(object) <- "lmerMod"
96 | dots <- list(...)
97 | models <- if (length(dots))
98 | sapply(dots, is, "merModLmerTest") | sapply(dots, is, "lmerModLmerTest") |
99 | sapply(dots, is, "merMod") | sapply(dots, is, "lm")
100 | else logical(0)
101 | if(any(models)) return(NextMethod())
102 | df <- match.arg(ddf)
103 | if (df == "lme4")
104 | return(anova(object, ...))
105 |
106 | object <- as_lmerModLmerTest(object)
107 | anova(object, ..., type=type, ddf=ddf)
108 | }
109 |
110 | ##############################################
111 | ######## summary method for merModLmerTest
112 | ##############################################
113 | #' @rdname legacy
114 | #' @export
115 | summary.merModLmerTest <- function(object, ...,
116 | ddf=c("Satterthwaite", "Kenward-Roger", "lme4")) {
117 | class(object) <- "lmerMod"
118 | object <- as_lmerModLmerTest(object)
119 | summary.lmerModLmerTest(object=object, ..., ddf=ddf)
120 | }
121 |
122 | ##############################################
123 | ######## ls_means method for merModLmerTest
124 | ##############################################
125 | #' @rdname legacy
126 | #' @inheritParams ls_means.lmerModLmerTest
127 | #' @export
128 | ls_means.merModLmerTest <- function(model, which=NULL, level=0.95,
129 | ddf=c("Satterthwaite", "Kenward-Roger"),
130 | pairwise=FALSE, ...) {
131 | class(model) <- "lmerMod"
132 | model <- as_lmerModLmerTest(model)
133 | ls_means(model=model, which=which, level=level, ddf=ddf, pairwise=pairwise)
134 | }
135 |
136 | ##############################################
137 | ######## lsmeansLT method for merModLmerTest
138 | ##############################################
139 | #' @rdname legacy
140 | #' @export
141 | lsmeansLT.merModLmerTest <- ls_means.merModLmerTest
142 |
143 | ##############################################
144 | ######## difflsmeans method for merModLmerTest
145 | ##############################################
146 | #' @rdname legacy
147 | #' @export
148 | difflsmeans.merModLmerTest <- function(model, which=NULL, level=0.95,
149 | ddf=c("Satterthwaite", "Kenward-Roger"), ...) {
150 | ls_means(model, which=which, level=level, ddf=ddf, pairwise = TRUE)
151 | }
152 |
153 | ##############################################
154 | ######## drop1 method for merModLmerTest
155 | ##############################################
156 | #' @rdname legacy
157 | #' @inheritParams drop1.lmerModLmerTest
158 | #' @export
159 | drop1.merModLmerTest <- function(object, scope, ddf=c("Satterthwaite", "Kenward-Roger", "lme4"),
160 | force_get_contrasts=FALSE, ...) {
161 | class(object) <- "lmerMod"
162 | object <- as_lmerModLmerTest(object)
163 | drop1(object=object, scope=scope, ddf=ddf, force_get_contrasts=FALSE, ...)
164 | }
165 |
166 | ##############################################
167 | ######## step method for merModLmerTest
168 | ##############################################
169 | #' @rdname legacy
170 | #' @inheritParams step.lmerModLmerTest
171 | #' @export
172 | step.merModLmerTest <- function(object, ddf=c("Satterthwaite", "Kenward-Roger"),
173 | alpha.random=0.1, alpha.fixed=0.05,
174 | reduce.fixed=TRUE, reduce.random=TRUE,
175 | keep, ...) {
176 | class(object) <- "lmerMod"
177 | object <- as_lmerModLmerTest(object)
178 | step(object, ddf=ddf, alpha.random=alpha.random, alpha.fixed=alpha.fixed,
179 | reduce.fixed=reduce.fixed, reduce.random=reduce.random,
180 | keep=keep, ...)
181 | }
182 |
--------------------------------------------------------------------------------
/R/lmerTest.R:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # Copyright (c) 2013-2020 Alexandra Kuznetsova, Per Bruun Brockhoff, and
3 | # Rune Haubo Bojesen Christensen
4 | #
5 | # This file is part of the lmerTest package for R (*lmerTest*)
6 | #
7 | # *lmerTest* is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 2 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # *lmerTest* is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # A copy of the GNU General Public License is available at
18 | # and/or
19 | # .
20 | #############################################################################
21 | #
22 | # lmerTest.R - package documentation page
23 |
24 | #' lmerTest: Tests in Linear Mixed Effects Models
25 | #'
26 | #' The \pkg{lmerTest} package provides p-values in type I, II or III
27 | #' \code{anova} and \code{summary}
28 | #' tables for linear mixed models (\code{\link{lmer}} model fits cf. \pkg{lme4})
29 | #' via Satterthwaite's degrees of freedom method; a Kenward-Roger method is also
30 | #' available via the \pkg{pbkrtest} package.
31 | #' Model selection and assessment methods include \code{\link{step}},
32 | #' \code{\link{drop1}}, anova-like tables for random effects (\code{\link{ranova}}),
33 | #' least-square means (LS-means; \code{\link{ls_means}})
34 | #' and tests of linear contrasts of fixed effects (\code{\link{contest}}).
35 | #'
36 | #'
37 | #' @section Key Functions and Methods:
38 | #'
39 | #' \describe{
40 | #' \item{lmer}{overloads \code{lme4::lmer} and produced an object of class
41 | #' \code{lmerModLmerTest} which inherits from \code{lmerMod}. In addition to
42 | #' computing the model (using \code{lme4::lmer}), \code{lmerTest::lmer}
43 | #' computes a couple of components needed for the evaluation of Satterthwaite's
44 | #' denominator degrees of freedom.}
45 | #' \item{anova}{anova method for \code{\link{lmer}} model fits produces
46 | #' type I, II, and III anova tables for fixed-effect terms with
47 | #' Satterthwaite and Kenward-Roger methods for denominator degrees of freedom
48 | #' for F-tests.}
49 | #' \item{summary}{summary method for \code{\link{lmer}} model fits adds
50 | #' denominator degrees of freedom and p-values to the coefficient table.}
51 | #' \item{ranova}{anova-like table of random effects via likelihood ratio tests
52 | #' with methods for both \code{lmerMod} and \code{lmerModLmerTest} objects.
53 | #' \code{ranova} can either test reduction of random-effect terms to simpler
54 | #' structures or it can test removal of entire random-effect terms.}
55 | #' \item{drop1}{F-tests of fixed-effect terms using Satterthwaite or
56 | #' Kenward-Roger methods for denominator degrees of freedom. These 'single term
57 | #' deletion' tables are useful for model selection and tests of marginal terms.
58 | #' Compared to the likelihood ratio tests of \code{lme4::drop1} the F-tests and
59 | #' p-values of \code{lmerTest::drop1} are more accurate and considerably faster
60 | #' since no additional model fitting is required.}
61 | #' \item{contest}{tests of contrasts, i.e. tests of linear functions of the
62 | #' fixed-effect coefficients. A user-friendly interface for tests of contrasts
63 | #' with outputs either as a summary-like table of t-tests or an anova-like table
64 | #' of F-tests (or a list of either). Contrasts can optionally be tested for
65 | #' estimability. Contrasts are allowed to be rank-deficient as the rank is
66 | #' automatically detected and appropriate adjustments made. Methods for
67 | #' \code{lmerModLmerTest} as well as \code{lmerMod} objects -- the latter avoids
68 | #' the Satterthwaite specific computations when the Kenward-Roger method is used.}
69 | #' \item{show_test}{a function which operates on anova tables and LS-means tables
70 | #' makes it possible to see exactly which
71 | #' functions of the coefficients are being tested. This is helpful when
72 | #' differences between type I, II and III anova tables are being considered and
73 | #' discussed.}
74 | #' \item{ls_means}{computes the so-called least-squares means (classical Yates
75 | #' contrasts) as well as pairwise differences of these.}
76 | #' \item{step}{performs automatic backward model selection of fixed and random
77 | #' parts of the linear mixed model.}
78 | #' \item{as_lmerModLmerTest}{an explicit coerce function from class
79 | #' \code{lmerMod} to \code{lmerModLmerTest}.}
80 | #' }
81 | #'
82 | #' @section Details:
83 | #' The computational approach is to let \code{lmerTest::lmer} compute the
84 | #' Hessian and derivatives needed for evaluation of degrees of freedom and
85 | #' t- and F-tests and to store these in the model object. The
86 | #' Hessian and derivatives are therefore computed only once per model fit
87 | #' and reused with each call to \code{anova}, \code{summary}, etc. Evaluation of
88 | #' t and F-tests does not involve model re-fitting.
89 | #'
90 | #' \code{lmerTest::lmer} roughly amounts to calling \code{lme4::lmer} followed by
91 | #' \code{lmerTest::as_lmerModLmerTest}, so for computationally intensive model
92 | #' fits it can make sense to use \code{lme4::lmer} rather than \code{lmerTest::lmer}
93 | #' if computational time is an issue and summary tables and anova tables will
94 | #' not be needed.
95 | #'
96 | #' @author Alexandra Kuznetsova, Per Bruun Brockhoff, Rune Haubo Bojesen Christensen
97 | #'
98 | #' @references
99 | #'
100 | #' Alexandra Kuznetsova, Per B. Brockhoff and Rune H. B. Christensen (2017)
101 | #' lmerTest Package: Tests in Linear Mixed Effects Models.
102 | #' \emph{Journal of Statistical Software}, 82(13), 1--26. doi:10.18637/jss.v082.i13
103 | #'
104 | #'
105 | #' @docType package
106 | #' @name lmerTest-package
107 | #' @aliases lmerTest
108 | #'
109 | #' @examples
110 | #'
111 | #' ## load lmerTest package
112 | #' library(lmerTest)
113 | #'
114 | #' ## Fit linear mixed model to the ham data:
115 | #' fm <- lmer(Informed.liking ~ Gender + Information * Product + (1 | Consumer) +
116 | #' (1 | Consumer:Product), data=ham)
117 | #'
118 | #' ## Summary including coefficient table with p-values for t-statistics using
119 | #' ## Satterthwaite's method for denominator degrees of freedom:
120 | #' summary(fm)
121 | #'
122 | #' ## Type III anova table with p-values for F-tests based on Satterthwaite's
123 | #' ## method:
124 | #' (aov <- anova(fm))
125 | #'
126 | #' ## Inspect the contrast matrix for the Type III test of Product:
127 | #' show_tests(aov, fractions = TRUE)$Product
128 | #'
129 | #' ## Choose type II anova table with Kenward-Roger method for the F-test:
130 | #' \dontrun{
131 | #' if(requireNamespace("pbkrtest", quietly = TRUE))
132 | #' anova(fm, type=2, ddf="Kenward-Roger")
133 | #' }
134 | #'
135 | #' ## Anova-like table of random-effect terms using likelihood ratio tests:
136 | #' ranova(fm)
137 | #'
138 | #' ## F-tests of 'single term deletions' for all marginal terms:
139 | #' drop1(fm)
140 | #'
141 | #' ## Least-Square means and pairwise differences:
142 | #' (lsm <- ls_means(fm))
143 | #' ls_means(fm, which = "Product", pairwise = TRUE)
144 | #'
145 | #' ## ls_means also have plot and as.data.frame methods:
146 | #' \dontrun{
147 | #' plot(lsm, which=c("Product", "Information"))
148 | #' as.data.frame(lsm)
149 | #' ## Inspect the LS-means contrasts:
150 | #' show_tests(lsm, fractions=TRUE)$Product
151 | #' }
152 | #'
153 | #' ## Contrast test (contest) using a custom contrast:
154 | #' ## Here we make the 2-df joint test of the main effects of Gender and Information
155 | #' (L <- diag(length(fixef(fm)))[2:3, ])
156 | #' contest(fm, L = L)
157 | #'
158 | #' ## backward elimination of non-significant effects:
159 | #' step_result <- step(fm)
160 | #'
161 | #' ## Elimination tables for random- and fixed-effect terms:
162 | #' step_result
163 | #'
164 | #' # Extract the model that step found:
165 | #' final_model <- get_model(step_result)
166 | #'
167 | NULL
168 |
--------------------------------------------------------------------------------
/R/lmer_summary.R:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # Copyright (c) 2013-2020 Alexandra Kuznetsova, Per Bruun Brockhoff, and
3 | # Rune Haubo Bojesen Christensen
4 | #
5 | # This file is part of the lmerTest package for R (*lmerTest*)
6 | #
7 | # *lmerTest* is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 2 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # *lmerTest* is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # A copy of the GNU General Public License is available at
18 | # and/or
19 | # .
20 | #############################################################################
21 | #
22 | # lmer_summary.R - summary method for lmerModLmerTest objects
23 |
24 | # ------- Contents: --------
25 | #
26 | # summary.lmerModLmerTest
27 | #
28 | # --- utility functions: ---
29 | #
30 | # get_coefmat
31 | #
32 |
33 | #' @include lmer.R
34 | NULL
35 |
36 | ##############################################
37 | ######## summary method for lmerModLmerTest
38 | ##############################################
39 | #' Summary Method for Linear Mixed Models
40 | #'
41 | #' Summaries of Linear Mixed Models with coefficient tables including t-tests
42 | #' and p-values using Satterthwaites's or Kenward-Roger's methods for
43 | #' degrees-of-freedom and t-statistics.
44 | #'
45 | #' The returned object is of class
46 | #' \code{c("summary.lmerModLmerTest", "summary.merMod")} utilizing \code{print},
47 | #' \code{coef} and other methods defined for \code{summary.merMod} objects.
48 | #' The \code{"Kenward-Roger"} method use methods from the \pkg{pbkrtest} package internally
49 | #' to compute t-statistics and associated degrees-of-freedom.
50 | #'
51 | #' @param object an lmerModLmerTest object.
52 | #' @param ddf the method for computing the degrees of freedom and
53 | #' t-statistics. \code{ddf="Satterthwaite"} (default) uses Satterthwaite's method;
54 | #' \code{ddf="Kenward-Roger"} uses Kenward-Roger's method,
55 | #' \code{ddf = "lme4"} returns the lme4-summary i.e., using the summary
56 | #' method for \code{lmerMod} objects as defined in the \pkg{lme4}-package and
57 | #' ignores the \code{type} argument. Partial matching is allowed.
58 | #' @param ... additional arguments passed on to \code{lme4::summary.merMod}
59 | #'
60 | #' @return A summary object with a coefficient table (a \code{matrix}) including
61 | #' t-values and p-values. The coefficient table can be extracted with
62 | #' \code{coef(summary())}.
63 | #'
64 | #' @seealso \code{\link{contest1D}} for one degree-of-freedom contrast tests
65 | #' and \code{\link[pbkrtest]{KRmodcomp}} for Kenward-Roger F-tests.
66 | #' @author Rune Haubo B. Christensen and Alexandra Kuznetsova
67 | #' @export
68 | #' @importFrom methods as signature
69 | #'
70 | #' @examples
71 | #'
72 | #' # Fit example model:
73 | #' data("sleepstudy", package="lme4")
74 | #' fm <- lmer(Reaction ~ Days + (1|Subject) + (0+Days|Subject), sleepstudy)
75 | #'
76 | #' # Get model summary:
77 | #' summary(fm) # Satterthwaite df and t-tests
78 | #'
79 | #' # Extract coefficient table:
80 | #' coef(summary(fm))
81 | #'
82 | #' # Use the Kenward-Roger method
83 | #' if(requireNamespace("pbkrtest", quietly = TRUE))
84 | #' summary(fm, ddf="Kenward-Roger")
85 | #'
86 | #' # The lme4-summary table:
87 | #' summary(fm, ddf="lme4") # same as summary(as(fm, "lmerMod"))
88 | #'
89 | #' \dontshow{
90 | #' # Check that summaries are as expected:
91 | #' summ_fm <- coef(summary(fm))
92 | #' summ_fm_lme4 <- coef(summary(fm, ddf="lme4"))
93 | #' stopifnot(
94 | #' all(colnames(summ_fm) == c("Estimate", "Std. Error", "df", "t value", "Pr(>|t|)")),
95 | #' all(colnames(summ_fm_lme4) == c("Estimate", "Std. Error", "t value")),
96 | #' all(!(is.na(summ_fm))),
97 | #' all(!(is.na(summ_fm_lme4)))
98 | #' )
99 | #' if(requireNamespace("pbkrtest", quietly = TRUE) && getRversion() >= "3.3.3") {
100 | #' summ_fm_kr <- coef(summary(fm, ddf="Kenward-Roger"))
101 | #' stopifnot(
102 | #' all(colnames(summ_fm_kr) == c("Estimate", "Std. Error", "df", "t value", "Pr(>|t|)")),
103 | #' all(!(is.na(summ_fm_kr)))
104 | #' )
105 | #' }
106 | #' }
107 | summary.lmerModLmerTest <- function(object, ...,
108 | ddf=c("Satterthwaite", "Kenward-Roger", "lme4")) {
109 | ddf <- match.arg(ddf)
110 | if(!inherits(object, "lmerModLmerTest") && !inherits(object, "lmerMod")) {
111 | stop("Cannot compute summary for objects of class: ",
112 | paste(class(object), collapse = ", "))
113 | }
114 | if(!inherits(object, "lmerModLmerTest") && inherits(object, "lmerMod")) {
115 | message("Coercing object to class 'lmerModLmerTest'")
116 | object <- as_lmerModLmerTest(object)
117 | if(!inherits(object, "lmerModLmerTest")) {
118 | warning("Failed to coerce object to class 'lmerModLmerTest'")
119 | return(summary(object))
120 | }
121 | }
122 | summ <- summary(as(object, "lmerMod"), ...)
123 | if(ddf == "lme4") return(summ)
124 | summ$coefficients <- get_coefmat(object, ddf=ddf)
125 | ddf_nm <- switch(ddf, "Satterthwaite" = "Satterthwaite's",
126 | "Kenward-Roger" = "Kenward-Roger's")
127 | summ$objClass <- class(object) # Used by lme4:::print.summary.lmerMod
128 | summ$methTitle <- paste0(summ$methTitle, ". t-tests use ", ddf_nm, " method")
129 | class(summ) <- c("summary.lmerModLmerTest", class(summ))
130 | summ
131 | }
132 |
133 |
134 | ##############################################
135 | ######## get_coefmat
136 | ##############################################
137 | #' @importFrom lme4 fixef
138 | get_coefmat <- function(model, ddf=c("Satterthwaite", "Kenward-Roger")) {
139 | ddf <- match.arg(ddf)
140 | p <- length(fixef(model))
141 | if(p < 1)
142 | return(as.matrix(contest1D(model, numeric(0L), ddf=ddf)))
143 | Lmat <- diag(p)
144 | tab <- rbindall(lapply(1:p, function(i) contest1D(model, Lmat[i, ], ddf=ddf)))
145 | rownames(tab) <- names(fixef(model))
146 | as.matrix(tab)
147 | }
148 |
--------------------------------------------------------------------------------
/R/terms_utils.R:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # Copyright (c) 2013-2020 Alexandra Kuznetsova, Per Bruun Brockhoff, and
3 | # Rune Haubo Bojesen Christensen
4 | #
5 | # This file is part of the lmerTest package for R (*lmerTest*)
6 | #
7 | # *lmerTest* is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 2 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # *lmerTest* is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # A copy of the GNU General Public License is available at
18 | # and/or
19 | # .
20 | #############################################################################
21 | #
22 | # terms_utils.R - utilities for computing on terms objects and friends
23 |
24 | # ------- Contents: --------
25 | #
26 | # --- utility functions: ---
27 | #
28 | # term2colX
29 | # need_yates
30 | # no_yates
31 | # numeric_terms
32 | # get_model_matrix
33 | # get_contrast_coding
34 | # get_min_data
35 | # get_var_list
36 | # get_fac_list
37 | # get_num_list
38 | # get_pairs
39 | # get_trts
40 | #
41 |
42 | ##############################################
43 | ######## term2colX()
44 | ##############################################
45 | term2colX <- function(terms, X) {
46 | # Compute map from terms to columns in X using the assign attribute of X.
47 | # Returns a list with one element for each term containing indices of columns
48 | # in X belonging to that term.
49 | if(is.null(asgn <- attr(X, "assign")))
50 | stop("Invalid design matrix:",
51 | "design matrix 'X' should have a non-null 'assign' attribute",
52 | call. = FALSE)
53 | term_names <- attr(terms, "term.labels")
54 | has_intercept <- attr(terms, "intercept") > 0
55 | col_terms <- if(has_intercept) c("(Intercept)", term_names)[asgn + 1] else
56 | term_names[asgn[asgn > 0]]
57 | if(!length(col_terms) == ncol(X)) # should never happen.
58 | stop("An error happended when mapping terms to columns of X")
59 | # get names of terms (including aliased terms)
60 | nm <- union(unique(col_terms), term_names)
61 | res <- lapply(setNames(as.list(nm), nm), function(x) numeric(0L))
62 | map <- split(seq_along(col_terms), col_terms)
63 | res[names(map)] <- map
64 | res[nm] # order appropriately
65 | }
66 |
67 | ##############################################
68 | ######## need_yates()
69 | ##############################################
70 | need_yates <- function(model) {
71 | ## Do not need yates for:
72 | ## - continuous variables
73 | ## - factors that are not contained in other factors
74 | ## Need yates for all other terms, i.e. terms which are:
75 | ## - contained in other terms, AND
76 | ## - which are not numeric/continuous
77 | term_names <- attr(terms(model), "term.labels")
78 | cont <- containment(model)
79 | is_contained <- names(cont[sapply(cont, function(x) length(x) > 0)])
80 | nmt <- numeric_terms(model)
81 | num_terms <- names(nmt[nmt])
82 | term_names[!term_names %in% num_terms &
83 | term_names %in% is_contained]
84 | }
85 |
86 | ##############################################
87 | ######## no_yates()
88 | ##############################################
89 | no_yates <- function(model) {
90 | setdiff(attr(terms(model), "term.labels"), need_yates(model))
91 | }
92 |
93 | ##############################################
94 | ######## numeric_terms()
95 | ##############################################
96 | #' @importFrom stats delete.response terms
97 | numeric_terms <- function(model) {
98 | ## Determines for all terms (not just all variables) if the 'dataClass'
99 | ## is numeric
100 | ## (interactions involving one or more numerics variables are numeric).
101 | Terms <- delete.response(terms(model))
102 | all_vars <- all.vars(attr(Terms, "variables"))
103 | data_classes <- attr(terms(model, fixed.only=FALSE), "dataClasses")
104 | var_class <- data_classes[names(data_classes) %in% all_vars]
105 | factor_vars <- names(var_class[var_class %in% c("factor", "ordered")])
106 | num_vars <- setdiff(all_vars, factor_vars)
107 |
108 | term_names <- attr(terms(model), "term.labels")
109 | # term_names <- setNames(as.list(term_names), term_names)
110 | sapply(term_names, function(term) {
111 | vars <- unlist(strsplit(term, ":"))
112 | any(vars %in% num_vars)
113 | })
114 | }
115 |
116 | ##############################################
117 | ######## get_model_matrix()
118 | ##############################################
119 | #' Extract or remake model matrix from model
120 | #'
121 | #' Extract or remake model matrix from model and potentially change the
122 | #' contrast coding
123 | #'
124 | #' @param model an \code{lm} or \code{lmerMod} model object.
125 | #' @param type extract or remake model matrix?
126 | #' @param contrasts contrasts settings. These may be restored to those in the
127 | #' model or they may be changed. If a length one character vector (e.g.
128 | #' \code{"contr.SAS"}) this is applied to all factors in the model, but it can
129 | #' also be a list naming factors for which the contrasts should be set as specified.
130 | #'
131 | #' @return the model (or 'design') matrix.
132 | #' @keywords internal
133 | #' @author Rune Haubo B Christensen
134 | get_model_matrix <- function(model, type=c("extract", "remake"),
135 | contrasts="restore") {
136 | type <- match.arg(type)
137 | stopifnot(inherits(model, "lm") || inherits(model, "lmerMod"))
138 |
139 | if(type == "extract") return(model.matrix(model))
140 | # Set appropriate contrasts:
141 | Contrasts <- get_contrast_coding(model, contrasts=contrasts)
142 | model.matrix(terms(model), data=model.frame(model),
143 | contrasts.arg = Contrasts)
144 | }
145 |
146 | ##############################################
147 | ######## get_contrast_coding()
148 | ##############################################
149 | get_contrast_coding <- function(model, contrasts="restore") {
150 | # Compute a list of contrasts for all factors in model
151 | Contrasts <- contrasts
152 | if(length(contrasts) == 1 && is.character(contrasts) &&
153 | contrasts == "restore") {
154 | Contrasts <- attr(model.matrix(model), "contrasts")
155 | } else if(length(contrasts) == 1 && is.character(contrasts) &&
156 | contrasts != "restore") {
157 | Contrasts <- .getXlevels(terms(model), model.frame(model))
158 | Contrasts[] <- contrasts
159 | Contrasts
160 | }
161 | Contrasts
162 | }
163 |
164 |
165 | get_min_data <- function(model, FUN=mean)
166 | # Get a minimum complete model.frame based on the variables in the model
167 | do.call(expand.grid, get_var_list(model, FUN=FUN))
168 |
169 | get_var_list <- function(model, FUN=mean)
170 | # Extract a named list of variables in the model containing the levels of
171 | # factors and the mean value of numeric variables
172 | c(get_fac_list(model), get_num_list(model, FUN=FUN))
173 |
174 | #' @importFrom stats .getXlevels
175 | get_fac_list <- function(model) {
176 | # Extract a named list of factor levels for each factor in the model
177 | res <- .getXlevels(Terms=terms(model), m=model.frame(model))
178 | if(is.null(res)) list() else res
179 | }
180 |
181 | get_num_list <- function(model, FUN=mean) { # FUN=function(x) mean(x, na.rm=TRUE)) {
182 | # Extract named list of mean/FUN values of numeric variables in model
183 | Terms <- terms(model)
184 | mf <- model.frame(model)
185 | xvars <- sapply(attr(Terms, "variables"), deparse2)[-1L]
186 | if((yvar <- attr(Terms, "response")) > 0)
187 | xvars <- xvars[-yvar]
188 | if(!length(xvars)) return(list())
189 | xlev <- lapply(mf[xvars], function(x) {
190 | if (is.numeric(x)) FUN(x) else NULL
191 | })
192 | res <- xlev[!vapply(xlev, is.null, NA)]
193 | if(is.null(res)) list() else res
194 | }
195 |
196 | #' @importFrom utils combn
197 | get_pairs <- function(levs) {
198 | stopifnot(is.character(levs), length(levs) > 1)
199 | combs <- combn(seq_along(levs), 2)
200 | ind <- seq_len(ncombs <- ncol(combs))
201 | A <- as.data.frame(array(0, dim=c(length(levs), ncombs)))
202 | dimnames(A) <- list(levs, paste(levs[combs[1, ]], levs[combs[2, ]], sep=" - "))
203 | A[cbind(combs[1, ], ind)] <- 1
204 | A[cbind(combs[2, ], ind)] <- -1
205 | A
206 | }
207 |
208 | get_trts <- function(levs) {
209 | nlevs <- length(levs)
210 | ans <- t(cbind(-1, diag(nlevs - 1)))
211 | rownames(ans) <- levs
212 | colnames(ans) <- paste(levs[-1], levs[1], sep=" - ")
213 | ans
214 | }
215 |
216 | # get_trts(letters[1:5])
217 | # get_pairs(letters[1:5])
218 |
219 |
--------------------------------------------------------------------------------
/R/utils.R:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # Copyright (c) 2013-2020 Alexandra Kuznetsova, Per Bruun Brockhoff, and
3 | # Rune Haubo Bojesen Christensen
4 | #
5 | # This file is part of the lmerTest package for R (*lmerTest*)
6 | #
7 | # *lmerTest* is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 2 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # *lmerTest* is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # A copy of the GNU General Public License is available at
18 | # and/or
19 | # .
20 | #############################################################################
21 | #
22 | # utils.R - Utility functions
23 |
24 | # ------- Contents: --------
25 | #
26 | # --- utility functions: ---
27 | #
28 | # qform
29 | # rbindall
30 | # cond
31 | # safeDeparse, deparse2
32 | # waldCI
33 | #
34 |
35 | ##############################################
36 | ######## qform
37 | ##############################################
38 |
39 | #' Compute Quadratic Form
40 | #'
41 | #' Efficiently computes \eqn{x' A x} - or in R-notation:
42 | #'
43 | #' Length of \code{x} should equal the number of rows and columns of \code{A}.
44 | #'
45 | #' @param x a numeric vector
46 | #' @param A a symmetric numeric matrix
47 | #'
48 | #' @return a numerical scalar
49 | #' @keywords internal
50 | qform <- function(x, A) {
51 | sum(x * (A %*% x)) # quadratic form: x'Ax
52 | }
53 |
54 | ##############################################
55 | ######## rbindall
56 | ##############################################
57 |
58 | #' \code{rbind} Multiple Objects
59 | #'
60 | #' @param ... objects to be \code{rbind}'ed - typically matrices or vectors
61 | #'
62 | #' @keywords internal
63 | rbindall <- function(...) do.call(rbind, ...)
64 |
65 | cbindall <- function(...) do.call(cbind, ...)
66 |
67 | ##############################################
68 | ######## cond
69 | ##############################################
70 | cond <- function(X) with(eigen(X, only.values=TRUE), max(values) / min(values))
71 |
72 | ##############################################
73 | ######## safeDeparse
74 | ##############################################
75 | safeDeparse <- function(expr, width.cutoff=500L, backtick = mode(expr) %in%
76 | c("call", "expression", "(", "function"),
77 | control = c("keepInteger","showAttributes", "keepNA"),
78 | nlines = -1L) {
79 | deparse(expr=expr, width.cutoff=width.cutoff, backtick=backtick,
80 | control=control, nlines=nlines)
81 | }
82 |
83 | deparse2 <- function(x) paste(safeDeparse(x), collapse = " ")
84 |
85 | ##############################################
86 | ######## waldCI
87 | ##############################################
88 | #' @importFrom stats qt
89 | waldCI <- function(estimate, se, df=Inf, level=0.95) {
90 | stopifnot(length(level) == 1,
91 | is.numeric(level),
92 | level > 0, level < 1)
93 | # all(se > 0))
94 | alpha <- (1 - level)/2
95 | fac <- qt(alpha, df=df, lower.tail = FALSE)
96 | res <- cbind(lower = estimate - se * fac,
97 | upper = estimate + se * fac)
98 | if(!is.null(names(estimate))) rownames(res) <- names(estimate)
99 | res
100 | }
101 |
102 | # waldCI(setNames(1, "est"), .2)
103 |
104 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # lmerTest - Tests in Linear Mixed Effects Models
2 |
3 | This is the repo for the _new_ **lmerTest** package, the old package is available [here](https://github.com/runehaubo/lmerTest).
4 |
5 | [](https://travis-ci.org/runehaubo/lmerTestR)
6 | [](https://cran.r-project.org/package=lmerTest)
7 | [](https://cran.r-project.org/package=lmerTest)
8 | [](http://cranlogs.r-pkg.org/badges/grand-total/lmerTest)
9 | [](http://depsy.org/package/r/lmerTest)
10 |
11 | ## Main features
12 |
13 | The **lmerTest** package provides _p_-values in type I, II or III `anova` and `summary`
14 | tables for linear mixed models (`lmer` model fits cf. **lme4**) via Satterthwaite's degrees of freedom method; a Kenward-Roger method is also available via the **pbkrtest**
15 | package. Model selection and assessment methods include `step`, `drop1`, anova-like
16 | tables for random effects (`ranova`), least-square means (LS-means; `ls_means`)
17 | and tests of linear contrasts of fixed effects (`contest`).
18 |
19 | ## Citation
20 |
21 | To cite **lmerTest** in publications use:
22 |
23 | Kuznetsova A., Brockhoff P.B. and Christensen R.H.B. (2017). "lmerTest Package: Tests in Linear Mixed Effects Models." _Journal of Statistical Software_, 82(13), pp. 1–26. doi: 10.18637/jss.v082.i13.
24 |
25 | Corresponding BibTeX entry:
26 |
27 | @Article{,
28 | title = {{lmerTest} Package: Tests in Linear Mixed Effects Models},
29 | author = {Alexandra Kuznetsova and Per B. Brockhoff and Rune H. B.
30 | Christensen},
31 | journal = {Journal of Statistical Software},
32 | year = {2017},
33 | volume = {82},
34 | number = {13},
35 | pages = {1--26},
36 | doi = {10.18637/jss.v082.i13},
37 | }
38 |
39 | ## Discovered a bug?
40 |
41 | Please raise a new issue! Preferably add code that illustrates the problem using one of the datasets from **lmerTest**.
42 |
43 | ## Installation
44 |
45 | Basically there are two options for installing **lmerTest**:
46 |
47 | 1. Released (stable version) from CRAN: in **R** run `install.packages("lmerTest")`.
48 | 2. Development version from GitHub: First load the **devtools** package (and install it if you do not have it) and install the default (master) branch:
49 | ```
50 | library("devtools")
51 | install_github("runehaubo/lmerTestR")
52 | ```
53 | If you haven't already installed a previous version of **lmerTest** you need to also install dependencies (other packages that **lmerTest** depends on and requires you to install to function properly). We recommend that you install **lmerTest** from CRAN (using `install.packages("lmerTest")`) before installing from GitHub as described above.
54 |
55 | An alternative is to use
56 | ```
57 | library("devtools")
58 | install_github("runehaubo/lmerTestR", dependencies=TRUE)
59 | ```
60 | but that requires you to install all dependent packages from source (which only works if you have the correct compilers installed and set up correctly); installing the pre-compiled packages from CRAN is usually easier.
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/data/TVbo.rda:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runehaubo/lmerTestR/35dc5885205d709cdc395b369b08ca2b7273cb78/data/TVbo.rda
--------------------------------------------------------------------------------
/data/carrots.rda:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runehaubo/lmerTestR/35dc5885205d709cdc395b369b08ca2b7273cb78/data/carrots.rda
--------------------------------------------------------------------------------
/data/ham.rda:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runehaubo/lmerTestR/35dc5885205d709cdc395b369b08ca2b7273cb78/data/ham.rda
--------------------------------------------------------------------------------
/inst/CITATION:
--------------------------------------------------------------------------------
1 | bibentry(bibtype = "Article",
2 | title = "{lmerTest} Package: Tests in Linear Mixed Effects Models",
3 | author = c(person(given = "Alexandra",
4 | family = "Kuznetsova",
5 | email = "alku@dtu.dk"),
6 | person(given = c("Per", "B."),
7 | family = "Brockhoff",
8 | email = "perbb@dtu.dk"),
9 | person(given = c("Rune", "H.", "B."),
10 | family = "Christensen",
11 | email = "Rune@ChristensenStatistics.dk")),
12 | journal = "Journal of Statistical Software",
13 | year = "2017",
14 | volume = "82",
15 | number = "13",
16 | pages = "1--26",
17 | doi = "10.18637/jss.v082.i13",
18 |
19 | header = "To cite lmerTest in publications use:"
20 | )
21 |
22 |
--------------------------------------------------------------------------------
/inst/testdata/legacy_fits.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runehaubo/lmerTestR/35dc5885205d709cdc395b369b08ca2b7273cb78/inst/testdata/legacy_fits.RData
--------------------------------------------------------------------------------
/inst/testdata/potdata.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runehaubo/lmerTestR/35dc5885205d709cdc395b369b08ca2b7273cb78/inst/testdata/potdata.RData
--------------------------------------------------------------------------------
/inst/testdata/test_paper_objects.RData:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runehaubo/lmerTestR/35dc5885205d709cdc395b369b08ca2b7273cb78/inst/testdata/test_paper_objects.RData
--------------------------------------------------------------------------------
/man/TVbo.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/data_documentation.R
3 | \docType{data}
4 | \name{TVbo}
5 | \alias{TVbo}
6 | \title{Sensory Assesment of B&O TVs}
7 | \format{
8 | \describe{
9 | \item{Assessor}{factor with 8 levels assessors.}
10 | \item{TVset}{product factor with 3 levels.}
11 | \item{Picture}{product factor with 4 levels.}
12 | }
13 | In addition the following 15 numeric (response) variables are the
14 | characteristics on which the TV sets (products) are assessed:
15 |
16 | Coloursaturation, Colourbalance, Noise, Depth, Sharpness, Lightlevel,
17 | Contrast, Sharpnessofmovement, Flickeringstationary, Flickeringmovement,
18 | Distortion, Dimglasseffect, Cutting, Flossyedges, Elasticeffect.
19 | }
20 | \usage{
21 | data(TVbo)
22 | }
23 | \description{
24 | The TVbo dataset has kindly been made available by the Danish high-end
25 | consumer electronics company
26 | \href{https://www.bang-olufsen.com}{Bang & Olufsen}.
27 | The main purpose was to assess 12 different TV sets (products) specified by
28 | the two attributes Picture and TVset.
29 | 15 different response variables (characteristics of the
30 | product) were assessed by a trained panel with 8 assessors.
31 | }
32 | \examples{
33 |
34 | fm <- lmer(Coloursaturation ~ TVset + Picture + (1|Assessor:TVset) +
35 | (1|Assessor), data=TVbo)
36 | ranova(fm)
37 | anova(fm)
38 |
39 | }
40 | \keyword{datasets}
41 |
--------------------------------------------------------------------------------
/man/anova.lmerModLmerTest.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lmer_anova.R
3 | \name{anova.lmerModLmerTest}
4 | \alias{anova.lmerModLmerTest}
5 | \title{ANOVA Tables for Linear Mixed Models}
6 | \usage{
7 | \method{anova}{lmerModLmerTest}(
8 | object,
9 | ...,
10 | type = c("III", "II", "I", "3", "2", "1"),
11 | ddf = c("Satterthwaite", "Kenward-Roger", "lme4")
12 | )
13 | }
14 | \arguments{
15 | \item{object}{an \code{lmerModLmerTest} object; the result of \code{lmer()}
16 | after loading the \pkg{lmerTest}-package.}
17 |
18 | \item{...}{potentially additional \code{lmer} or \code{lm} model objects for
19 | comparison of models in which case \code{type} and \code{ddf} arguments are
20 | ignored.}
21 |
22 | \item{type}{the type of ANOVA table requested (using SAS terminology)
23 | with Type I being the familiar sequential ANOVA table.}
24 |
25 | \item{ddf}{the method for computing the denominator degrees of freedom and
26 | F-statistics. \code{ddf="Satterthwaite"} (default) uses Satterthwaite's method;
27 | \code{ddf="Kenward-Roger"} uses Kenward-Roger's method,
28 | \code{ddf = "lme4"} returns the lme4-anova table, i.e., using the anova
29 | method for \code{lmerMod} objects as defined in the \pkg{lme4}-package and
30 | ignores the \code{type} argument. Partial matching is allowed.}
31 | }
32 | \value{
33 | an ANOVA table
34 | }
35 | \description{
36 | ANOVA table with F-tests and p-values using Satterthwaite's or
37 | Kenward-Roger's method for denominator degrees-of-freedom and F-statistic.
38 | Models should be fitted with
39 | \code{\link{lmer}} from the \pkg{lmerTest}-package.
40 | }
41 | \details{
42 | The \code{"Kenward-Roger"} method calls \code{pbkrtest::KRmodcomp} internally and
43 | reports scaled F-statistics and associated denominator degrees-of-freedom.
44 | }
45 | \examples{
46 |
47 | data("sleepstudy", package="lme4")
48 | m <- lmer(Reaction ~ Days + (Days | Subject), sleepstudy)
49 | anova(m) # with p-values from F-tests using Satterthwaite's denominator df
50 | anova(m, ddf="lme4") # no p-values
51 |
52 | # Use the Kenward-Roger method
53 | if(requireNamespace("pbkrtest", quietly = TRUE))
54 | anova(m, ddf="Kenward-Roger")
55 |
56 | \dontshow{
57 | an1 <- anova(m) # with p-values from F-tests using Satterthwaite's denominator df
58 | an2 <- anova(m, ddf="lme4")
59 | stopifnot(
60 | all(colnames(an1) == c("Sum Sq", "Mean Sq", "NumDF", "DenDF", "F value", "Pr(>F)")),
61 | !"Pr(>F)" \%in\% colnames(an2),
62 | all(!is.na(an1)),
63 | all(!is.na(an2))
64 | )
65 | }
66 | }
67 | \seealso{
68 | \code{\link{contestMD}} for multi degree-of-freedom contrast tests
69 | and \code{\link[pbkrtest]{KRmodcomp}} for the \code{"Kenward-Roger"} method.
70 | }
71 | \author{
72 | Rune Haubo B. Christensen and Alexandra Kuznetsova
73 | }
74 |
--------------------------------------------------------------------------------
/man/as.data.frame.ls_means.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/ls_means.R
3 | \name{as.data.frame.ls_means}
4 | \alias{as.data.frame.ls_means}
5 | \title{Coerce \code{ls_means} Objects to \code{data.frame}s}
6 | \usage{
7 | \method{as.data.frame}{ls_means}(x, ..., add_levels = TRUE)
8 | }
9 | \arguments{
10 | \item{x}{an \code{\link{ls_means}} object.}
11 |
12 | \item{...}{currently not used.}
13 |
14 | \item{add_levels}{add \code{term} and \code{levels} columns to returned
15 | \code{data.frame}?}
16 | }
17 | \description{
18 | Coerce \code{ls_means} Objects to \code{data.frame}s
19 | }
20 | \examples{
21 |
22 | # Fit example model:
23 | data("cake", package="lme4")
24 | cake$Temp <- factor(cake$temperature, ordered = FALSE)
25 | model <- lmer(angle ~ recipe + Temp + (1|recipe:replicate), cake)
26 |
27 | # Extract LS-means:
28 | head(lsm <- ls_means(model))
29 |
30 | # Coerce LS-means objects to data.frames:
31 | head(as.data.frame(lsm))
32 | head(as.data.frame(lsm, add_levels=FALSE))
33 |
34 | }
35 | \seealso{
36 | \code{\link{ls_means.lmerModLmerTest}}
37 | }
38 | \author{
39 | Rune Haubo B. Christensen
40 | }
41 | \keyword{internal}
42 |
--------------------------------------------------------------------------------
/man/as_lmerModLmerTest.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lmer.R
3 | \name{as_lmerModLmerTest}
4 | \alias{as_lmerModLmerTest}
5 | \title{Coerce lmerMod Objects to lmerModLmerTest}
6 | \usage{
7 | as_lmerModLmerTest(model, tol = 1e-08)
8 | }
9 | \arguments{
10 | \item{model}{and lmer model-object (of class 'lmerMod') -- the result of a
11 | call to \code{lme4::lmer()}}
12 |
13 | \item{tol}{tolerance for determining of eigenvalues are negative, zero or
14 | positive}
15 | }
16 | \value{
17 | an object of class \code{'lmerModLmerTest'} which sets the following
18 | slots:
19 | \item{vcov_varpar}{the asymptotic covariance matrix of the variance parameters
20 | (theta, sigma).}
21 | \item{Jac_list}{list of Jacobian matrices; gradients of vcov(beta) with
22 | respect to the variance parameters.}
23 | \item{vcov_beta}{the asymptotic covariance matrix of the fixed-effect
24 | regression parameters (beta; vcov(beta)).}
25 | \item{sigma}{the residual standard deviation.}
26 | }
27 | \description{
28 | Coercing an lme4::lmer model-object (of class 'lmerMod') to a model-object
29 | of class 'lmerModLmerTest' involves computing the covariance
30 | matrix of the variance parameters and the gradient (Jacobian) of cov(beta)
31 | with respect to the variance parameters.
32 | }
33 | \examples{
34 | m <- lme4::lmer(Reaction ~ Days + (Days | Subject), sleepstudy)
35 | bm <- as_lmerModLmerTest(m)
36 | slotNames(bm)
37 |
38 | }
39 | \seealso{
40 | the class definition in \code{\link{lmerModLmerTest}}) and
41 | \code{\link{lmer}}
42 | }
43 | \author{
44 | Rune Haubo B. Christensen
45 | }
46 |
--------------------------------------------------------------------------------
/man/carrots.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/data_documentation.R
3 | \docType{data}
4 | \name{carrots}
5 | \alias{carrots}
6 | \title{Consumer Preference Mapping of Carrots}
7 | \format{
8 | \describe{
9 | \item{Consumer}{factor with 103 levels: numbering identifying consumers.}
10 | \item{Frequency}{factor with 5 levels; "How often do you eat carrots?"
11 | 1: once a week or more, 2: once
12 | every two weeks, 3: once every three weeks, 4: at least once month,
13 | 5: less than once a month.}
14 | \item{Gender}{factor with 2 levels. 1: male, 2:female.}
15 | \item{Age}{factor with 4 levels. 1: less than 25 years, 2: 26-40 years,
16 | 3: 41-60 years, 4 more than 61 years.}
17 | \item{Homesize}{factor with two levels. Number of persons in the household.
18 | 1: 1 or 2 persons, 2: 3 or more persons.}
19 | \item{Work}{factor with 7 levels. different types of employment.
20 | 1: unskilled worker(no education),
21 | 2: skilled worker(with education), 3: office worker, 4: housewife (or man),
22 | 5: independent
23 | businessman/ self-employment, 6: student, 7: retired}
24 | \item{Income}{factor with 4 levels. 1: <150000, 2: 150000-300000,
25 | 3: 300000-500000, 4: >500000}
26 | \item{Preference}{consumer score on a seven-point scale.}
27 | \item{Sweetness}{consumer score on a seven-point scale.}
28 | \item{Bitterness}{consumer score on a seven-point scale.}
29 | \item{Crispness}{consumer score on a seven-point scale.}
30 | \item{sens1}{first sensory variable derived from a PCA.}
31 | \item{sens2}{second sensory variable derived from a PCA.}
32 | \item{Product}{factor on 12 levels.}
33 | }
34 | }
35 | \source{
36 | Per Bruun Brockhoff, The Royal Veterinary and Agricultural University,
37 | Denmark.
38 | }
39 | \usage{
40 | data(carrots)
41 | }
42 | \description{
43 | In a consumer study 103 consumers scored their preference of 12 danish
44 | carrot types on a scale from 1 to 7. Moreover the consumers scored the
45 | degree of sweetness, bitterness and crispiness in the products.
46 | }
47 | \details{
48 | The carrots were harvested in autumn 1996 and tested in march 1997. In
49 | addition to the consumer survey, the carrot products were evaluated by
50 | a trained panel of tasters, the sensory panel, with respect to a
51 | number of sensory (taste, odour and texture) properties. Since usually
52 | a high number of (correlated) properties (variables) are used, in this
53 | case 14, it is a common procedure to use a few, often 2, combined
54 | variables that contain as much of the information in the sensory
55 | variables as possible. This is achieved by extracting the first two
56 | principal components in a principal components analysis (PCA) on the
57 | product-by-property panel average data matrix. In this data set the
58 | variables for the first two principal components are named
59 | (\code{sens1} and \code{sens2}).
60 | }
61 | \examples{
62 |
63 | fm <- lmer(Preference ~ sens2 + Homesize + (1 + sens2 | Consumer), data=carrots)
64 | anova(fm)
65 |
66 | }
67 | \keyword{datasets}
68 |
--------------------------------------------------------------------------------
/man/containment.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/contrast_utils.R
3 | \name{containment}
4 | \alias{containment}
5 | \title{Determine the Containment Structure for All Terms in a Model}
6 | \usage{
7 | containment(object)
8 | }
9 | \arguments{
10 | \item{object}{a model object, e.g. of class \code{lm} or \code{merMod}.}
11 | }
12 | \value{
13 | a list with one element for each term in the model. Each element/term
14 | is a character vector of terms that the term is contained in.
15 | }
16 | \description{
17 | See \code{\link{term_contain}} for details about containment.
18 | }
19 | \keyword{internal}
20 |
--------------------------------------------------------------------------------
/man/contest.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/contest.R
3 | \name{contest}
4 | \alias{contest}
5 | \alias{contest1D}
6 | \alias{contestMD}
7 | \title{Generic Contrast Test Functions}
8 | \usage{
9 | contest(model, L, ...)
10 |
11 | contest1D(model, L, ...)
12 |
13 | contestMD(model, L, ...)
14 | }
15 | \arguments{
16 | \item{model}{a model object.}
17 |
18 | \item{L}{a contrast vector or matrix.}
19 |
20 | \item{...}{additional arguments passed to methods.}
21 | }
22 | \description{
23 | Generic functions for tests contrasts.
24 | }
25 | \seealso{
26 | contest methods for \code{\link{lmer}} objects:
27 | \code{\link[=contest.lmerModLmerTest]{contest}},
28 | \code{\link[=contest1D.lmerModLmerTest]{contest1D}}, and
29 | \code{\link[=contestMD.lmerModLmerTest]{contestMD}}.
30 | }
31 | \author{
32 | Rune Haubo B. Christensen
33 | }
34 | \keyword{internal}
35 |
--------------------------------------------------------------------------------
/man/contest.lmerModLmerTest.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/contest.R
3 | \name{contest.lmerModLmerTest}
4 | \alias{contest.lmerModLmerTest}
5 | \alias{contest.lmerMod}
6 | \title{Test of Contrasts}
7 | \usage{
8 | \method{contest}{lmerModLmerTest}(
9 | model,
10 | L,
11 | rhs = 0,
12 | joint = TRUE,
13 | collect = TRUE,
14 | confint = TRUE,
15 | level = 0.95,
16 | check_estimability = FALSE,
17 | ddf = c("Satterthwaite", "Kenward-Roger", "lme4"),
18 | ...
19 | )
20 |
21 | \method{contest}{lmerMod}(
22 | model,
23 | L,
24 | rhs = 0,
25 | joint = TRUE,
26 | collect = TRUE,
27 | confint = TRUE,
28 | level = 0.95,
29 | check_estimability = FALSE,
30 | ddf = c("Satterthwaite", "Kenward-Roger", "lme4"),
31 | ...
32 | )
33 | }
34 | \arguments{
35 | \item{model}{a model object fitted with \code{lmer} from package
36 | \pkg{lmerTest}, i.e., an object of class \code{\link{lmerModLmerTest}}.}
37 |
38 | \item{L}{a contrast vector or matrix or a list of these.
39 | The \code{length}/\code{ncol} of each contrasts should equal
40 | \code{length(fixef(model))}.}
41 |
42 | \item{rhs}{right-hand-side of the statistical test, i.e. the hypothesized
43 | value (a numeric scalar).}
44 |
45 | \item{joint}{make an F-test of potentially several contrast vectors? If
46 | \code{FALSE} single DF t-tests are applied to each vector or each row of
47 | contrasts matrices.}
48 |
49 | \item{collect}{collect list of tests in a matrix?}
50 |
51 | \item{confint}{include columns for lower and upper confidence limits? Applies
52 | when \code{joint} is \code{FALSE}.}
53 |
54 | \item{level}{confidence level.}
55 |
56 | \item{check_estimability}{check estimability of contrasts? Only single DF
57 | contrasts are checked for estimability thus requiring \code{joint = FALSE} to
58 | take effect. See details section for necessary adjustments to \code{L} when
59 | estimability is checked with rank deficient design matrices.}
60 |
61 | \item{ddf}{the method for computing the denominator degrees of freedom.
62 | \code{ddf="Kenward-Roger"} uses Kenward-Roger's method.}
63 |
64 | \item{...}{passed to \code{\link{contestMD}}.}
65 | }
66 | \value{
67 | a \code{data.frame} or a list of \code{data.frame}s.
68 | }
69 | \description{
70 | Tests of vector or matrix contrasts for \code{\link{lmer}} model fits.
71 | }
72 | \details{
73 | If the design matrix is rank deficient, \code{lmer} drops columns for the
74 | aliased coefficients from the design matrix and excludes the corresponding
75 | aliased coefficients from \code{fixef(model)}. When estimability is checked
76 | the original rank-deficient design matrix is recontructed and therefore
77 | \code{L} contrast vectors need to include elements for the aliased
78 | coefficients. Similarly when \code{L} is a matrix, its number of columns
79 | needs to match that of the reconstructed rank-deficient design matrix.
80 | }
81 | \examples{
82 |
83 | data("sleepstudy", package="lme4")
84 | fm <- lmer(Reaction ~ Days + I(Days^2) + (1|Subject) + (0+Days|Subject),
85 | sleepstudy)
86 | # F-test of third coeffcients - I(Days^2):
87 | contest(fm, c(0, 0, 1))
88 | # Equivalent t-test:
89 | contest(fm, L=c(0, 0, 1), joint=FALSE)
90 | # Test of 'Days + I(Days^2)':
91 | contest(fm, L=diag(3)[2:3, ])
92 | # Other options:
93 | contest(fm, L=diag(3)[2:3, ], joint=FALSE)
94 | contest(fm, L=diag(3)[2:3, ], joint=FALSE, collect=FALSE)
95 |
96 | # Illustrate a list argument:
97 | L <- list("First"=diag(3)[3, ], "Second"=diag(3)[-1, ])
98 | contest(fm, L)
99 | contest(fm, L, collect = FALSE)
100 | contest(fm, L, joint=FALSE, confint = FALSE)
101 | contest(fm, L, joint=FALSE, collect = FALSE, level=0.99)
102 |
103 | # Illustrate testing of estimability:
104 | # Consider the 'cake' dataset with a missing cell:
105 | data("cake", package="lme4")
106 | cake$temperature <- factor(cake$temperature, ordered=FALSE)
107 | cake <- droplevels(subset(cake, temperature \%in\% levels(cake$temperature)[1:2] &
108 | !(recipe == "C" & temperature == "185")))
109 | with(cake, table(recipe, temperature))
110 | fm <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake)
111 | fixef(fm)
112 | # The coefficient for recipeC:temperature185 is dropped:
113 | attr(model.matrix(fm), "col.dropped")
114 | # so any contrast involving this coefficient is not estimable:
115 | Lmat <- diag(6)
116 | contest(fm, Lmat, joint=FALSE, check_estimability = TRUE)
117 |
118 | }
119 | \seealso{
120 | \code{\link[=contestMD.lmerModLmerTest]{contestMD}} for multi
121 | degree-of-freedom contrast tests,
122 | and \code{\link[=contest1D.lmerModLmerTest]{contest1D}} for tests of
123 | 1-dimensional contrasts.
124 | }
125 | \author{
126 | Rune Haubo B. Christensen
127 | }
128 |
--------------------------------------------------------------------------------
/man/contest1D.lmerModLmerTest.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/contest.R
3 | \name{contest1D.lmerModLmerTest}
4 | \alias{contest1D.lmerModLmerTest}
5 | \alias{contest1D.lmerMod}
6 | \title{Contrast Tests in 1D}
7 | \usage{
8 | \method{contest1D}{lmerModLmerTest}(
9 | model,
10 | L,
11 | rhs = 0,
12 | ddf = c("Satterthwaite", "Kenward-Roger"),
13 | confint = FALSE,
14 | level = 0.95,
15 | ...
16 | )
17 |
18 | \method{contest1D}{lmerMod}(
19 | model,
20 | L,
21 | rhs = 0,
22 | ddf = c("Satterthwaite", "Kenward-Roger"),
23 | confint = FALSE,
24 | level = 0.95,
25 | ...
26 | )
27 | }
28 | \arguments{
29 | \item{model}{a model object fitted with \code{lmer} from package
30 | \pkg{lmerTest}, i.e., an object of class \code{\link{lmerModLmerTest}}.}
31 |
32 | \item{L}{a numeric (contrast) vector of the same length as
33 | \code{fixef(model)}.}
34 |
35 | \item{rhs}{right-hand-side of the statistical test, i.e. the hypothesized
36 | value (a numeric scalar).}
37 |
38 | \item{ddf}{the method for computing the denominator degrees of freedom.
39 | \code{ddf="Kenward-Roger"} uses Kenward-Roger's method.}
40 |
41 | \item{confint}{include columns for lower and upper confidence limits?}
42 |
43 | \item{level}{confidence level.}
44 |
45 | \item{...}{currently not used.}
46 | }
47 | \value{
48 | A \code{data.frame} with one row and columns with \code{"Estimate"},
49 | \code{"Std. Error"}, \code{"t value"}, \code{"df"}, and \code{"Pr(>|t|)"}
50 | (p-value). If \code{confint = TRUE} \code{"lower"} and \code{"upper"} columns
51 | are included before the p-value column.
52 | }
53 | \description{
54 | Compute the test of a one-dimensional (vector) contrast in a
55 | linear mixed model fitted with lmer from package \pkg{lmerTest}.
56 | The contrast should specify a linear function of the
57 | mean-value parameters, beta. The Satterthwaite or Kenward-Roger method is
58 | used to compute the (denominator) df for the t-test.
59 | }
60 | \details{
61 | The t-value and associated p-value is for the hypothesis
62 | \eqn{L' \beta = \mathrm{rhs}}{L' \beta = rhs} in which rhs may be non-zero
63 | and \eqn{\beta} is \code{fixef(model)}.
64 | The estimated value (\code{"Estimate"}) is \eqn{L' \beta} with associated
65 | standard error and (optionally) confidence interval.
66 | }
67 | \examples{
68 |
69 | # Fit model using lmer with data from the lme4-package:
70 | data("sleepstudy", package="lme4")
71 | fm <- lmer(Reaction ~ Days + (1 + Days|Subject), sleepstudy)
72 |
73 | # Tests and CI of model coefficients are obtained with:
74 | contest1D(fm, c(1, 0), confint=TRUE) # Test for Intercept
75 | contest1D(fm, c(0, 1), confint=TRUE) # Test for Days
76 |
77 | # Tests of coefficients are also part of:
78 | summary(fm)
79 |
80 | # Illustrate use of rhs argument:
81 | contest1D(fm, c(0, 1), confint=TRUE, rhs=10) # Test for Days-coef == 10
82 |
83 |
84 | }
85 | \seealso{
86 | \code{\link[=contest.lmerModLmerTest]{contest}} for a flexible
87 | and general interface to tests of contrasts among fixed-effect parameters.
88 | \code{\link[=contestMD.lmerModLmerTest]{contestMD}} is also available as a
89 | direct interface for tests of multi degree-of-freedom contrast.
90 | }
91 | \author{
92 | Rune Haubo B. Christensen
93 | }
94 |
--------------------------------------------------------------------------------
/man/contestMD.lmerModLmerTest.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/contest.R
3 | \name{contestMD.lmerModLmerTest}
4 | \alias{contestMD.lmerModLmerTest}
5 | \alias{calcSatterth}
6 | \alias{contestMD.lmerMod}
7 | \title{Multiple Degrees-of-Freedom Contrast Tests}
8 | \usage{
9 | \method{contestMD}{lmerModLmerTest}(
10 | model,
11 | L,
12 | rhs = 0,
13 | ddf = c("Satterthwaite", "Kenward-Roger"),
14 | eps = sqrt(.Machine$double.eps),
15 | ...
16 | )
17 |
18 | calcSatterth(model, L)
19 |
20 | \method{contestMD}{lmerMod}(
21 | model,
22 | L,
23 | rhs = 0,
24 | ddf = c("Satterthwaite", "Kenward-Roger"),
25 | eps = sqrt(.Machine$double.eps),
26 | ...
27 | )
28 | }
29 | \arguments{
30 | \item{model}{a model object fitted with \code{lmer} from package
31 | \pkg{lmerTest}, i.e., an object of class \code{\link{lmerModLmerTest}}.}
32 |
33 | \item{L}{a contrast matrix with nrow >= 1 and ncol ==
34 | \code{length(fixef(model))}.}
35 |
36 | \item{rhs}{right-hand-side of the statistical test, i.e. the hypothesized
37 | value. A numeric vector of length \code{nrow(L)} or a numeric scalar.}
38 |
39 | \item{ddf}{the method for computing the denominator degrees of freedom and
40 | F-statistics. \code{ddf="Kenward-Roger"} uses Kenward-Roger's method.}
41 |
42 | \item{eps}{tolerance on eigenvalues to determine if an eigenvalue is
43 | positive. The number of positive eigenvalues determine the rank of
44 | L and the numerator df of the F-test.}
45 |
46 | \item{...}{currently not used.}
47 | }
48 | \value{
49 | a \code{data.frame} with one row and columns with \code{"Sum Sq"},
50 | \code{"Mean Sq"}, \code{"F value"}, \code{"NumDF"} (numerator df),
51 | \code{"DenDF"} (denominator df) and \code{"Pr(>F)"} (p-value).
52 | }
53 | \description{
54 | Compute the multi degrees-of-freedom test in a linear mixed model fitted
55 | by \code{\link{lmer}}. The contrast (L) specifies a linear function of the
56 | mean-value parameters, beta. Satterthwaite's method is used to compute the
57 | denominator df for the F-test.
58 | }
59 | \details{
60 | The F-value and associated p-value is for the hypothesis
61 | \eqn{L \beta = \mathrm{rhs}}{L \beta = rhs} in which rhs may be non-zero
62 | and \eqn{\beta} is \code{fixef(model)}.
63 |
64 | Note: NumDF = row-rank(L) is determined automatically so row rank-deficient L
65 | are allowed. One-dimensional contrasts are also allowed (L has 1 row).
66 | }
67 | \examples{
68 |
69 | data("sleepstudy", package="lme4")
70 | fm <- lmer(Reaction ~ Days + I(Days^2) + (1|Subject) + (0+Days|Subject),
71 | sleepstudy)
72 |
73 | # Define 2-df contrast - since L has 2 (linearly independent) rows
74 | # the F-test is on 2 (numerator) df:
75 | L <- rbind(c(0, 1, 0), # Note: ncol(L) == length(fixef(fm))
76 | c(0, 0, 1))
77 |
78 | # Make the 2-df F-test of any effect of Days:
79 | contestMD(fm, L)
80 |
81 | # Illustrate rhs argument:
82 | contestMD(fm, L, rhs=c(5, .1))
83 |
84 | # Make the 1-df F-test of the effect of Days^2:
85 | contestMD(fm, L[2, , drop=FALSE])
86 | # Same test, but now as a t-test instead:
87 | contest1D(fm, L[2, , drop=TRUE])
88 |
89 | }
90 | \seealso{
91 | \code{\link[=contest.lmerModLmerTest]{contest}} for a flexible and
92 | general interface to tests of contrasts among fixed-effect parameters.
93 | \code{\link[=contest1D.lmerModLmerTest]{contest1D}} is a direct interface for
94 | tests of 1-dimensional contrasts.
95 | }
96 | \author{
97 | Rune Haubo B. Christensen
98 | }
99 |
--------------------------------------------------------------------------------
/man/devfun_vp.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lmer.R
3 | \name{devfun_vp}
4 | \alias{devfun_vp}
5 | \title{Compute Deviance of an LMM as a Function of Variance Parameters}
6 | \usage{
7 | devfun_vp(varpar, devfun, reml)
8 | }
9 | \arguments{
10 | \item{varpar}{variance parameters; \code{varpar = c(theta, sigma)}.}
11 |
12 | \item{devfun}{deviance function as a function of theta only.}
13 |
14 | \item{reml}{if \code{TRUE} the REML deviance is computed;
15 | if \code{FALSE}, the ML deviance is computed.}
16 | }
17 | \value{
18 | the REML or ML deviance.
19 | }
20 | \description{
21 | This function is used for extracting the asymptotic variance-covariance matrix
22 | of the variance parameters.
23 | }
24 | \author{
25 | Rune Haubo B. Christensen
26 | }
27 | \keyword{internal}
28 |
--------------------------------------------------------------------------------
/man/doolittle.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/contrast_utils.R
3 | \name{doolittle}
4 | \alias{doolittle}
5 | \title{Doolittle Decomposition}
6 | \usage{
7 | doolittle(x, eps = 1e-06)
8 | }
9 | \arguments{
10 | \item{x}{a numeric square matrix with at least 2 columns/rows.}
11 |
12 | \item{eps}{numerical tolerance on the whether to normalize with components
13 | in \code{L} with the diagonal elements of \code{U}.}
14 | }
15 | \value{
16 | a list with two matrices of the same dimension as \code{x}:
17 | \item{L}{lower-left unit-triangular matrix}
18 | \item{U}{upper-right triangular matrix (\emph{not} unit-triangular)}
19 | }
20 | \description{
21 | Doolittle Decomposition
22 | }
23 | \keyword{internal}
24 |
--------------------------------------------------------------------------------
/man/drop1.lmerModLmerTest.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drop1.R
3 | \name{drop1.lmerModLmerTest}
4 | \alias{drop1.lmerModLmerTest}
5 | \title{Drop Marginal Terms from Model}
6 | \usage{
7 | \method{drop1}{lmerModLmerTest}(
8 | object,
9 | scope,
10 | ddf = c("Satterthwaite", "Kenward-Roger", "lme4"),
11 | force_get_contrasts = FALSE,
12 | ...
13 | )
14 | }
15 | \arguments{
16 | \item{object}{an \code{\link{lmer}} model fit (of class
17 | \code{"lmerModLmerTest"}.)}
18 |
19 | \item{scope}{optional character vector naming terms to be dropped from the
20 | model. Note that only marginal terms can be dropped. To see which terms are
21 | marginal, use \code{drop.scope(terms(object))}.}
22 |
23 | \item{ddf}{the method for computing the denominator degrees of freedom and
24 | F-statistics. \code{ddf="Satterthwaite"} (default) uses Satterthwaite's method;
25 | \code{ddf="Kenward-Roger"} uses Kenward-Roger's method.
26 | \code{ddf = "lme4"} returns the \code{drop1} table for \code{merMod} objects
27 | as defined in package \pkg{lme4}.}
28 |
29 | \item{force_get_contrasts}{enforce computation of contrast matrices by a
30 | method in which the design matrices for full and restricted models are
31 | compared.}
32 |
33 | \item{...}{currently not used.}
34 | }
35 | \value{
36 | An anova-like table with F-tests of marginal terms.
37 | }
38 | \description{
39 | Computes the F-test for all marginal terms, i.e. terms that can be dropped
40 | from the model while respecting the hierarchy of terms in the model.
41 | }
42 | \details{
43 | Simple marginal contrasts are used for all marginal terms unless the design
44 | matrix is rank deficient. In that case (and if \code{force_get_contrasts} is
45 | \code{TRUE}) the contrasts (i.e. restriction matrices on the design matrix
46 | of the full model) are computed by comparison of the design matrices
47 | for full and restricted models. The set of marginal terms considered for
48 | dropping are computed using \code{drop.scope(terms(object))}.
49 |
50 | Since all tests are based on tests of contrasts in the full model, no
51 | models are being (re)fitted.
52 | }
53 | \examples{
54 |
55 | # Basic usage:
56 | fm <- lmer(angle ~ recipe + temp + (1|recipe:replicate), cake)
57 | drop1(fm) # Using Satterthwaite degrees of freedom
58 | if(requireNamespace("pbkrtest", quietly = TRUE))
59 | drop1(fm, ddf="Kenward-Roger") # Alternative DenDF and F-test method
60 | drop1(fm, ddf="lme4", test="Chi") # Asymptotic Likelihood ratio tests
61 |
62 | # Consider a rank-deficient design matrix:
63 | fm <- lmer(angle ~ recipe + temp + temperature + (1|recipe:replicate), cake)
64 | # Here temp accounts for the linear effect of temperature, and
65 | # temperature is an (ordered) factor that accounts for the remaining
66 | # variation between temperatures (4 df).
67 | drop1(fm)
68 | # While temperature is in the model, we cannot test the effect of dropping
69 | # temp. After removing temperature we can test the effect of dropping temp:
70 | drop1(lmer(angle ~ recipe + temp + (1|recipe:replicate), cake))
71 |
72 | # Polynomials:
73 | # Note that linear terms should usually not be dropped before squared terms.
74 | # Therefore 'Days' should not be dropped before 'I(Days^2)' despite it being
75 | # tested here:
76 | fm <- lmer(Reaction ~ Days + I(Days^2) + (Days|Subject), sleepstudy)
77 | drop1(fm)
78 | # Using poly() provides a test of the whole polynomial structure - not a
79 | # separate test for the highest order (squared) term:
80 | fm <- lmer(Reaction ~ poly(Days, 2) + (Days|Subject), sleepstudy)
81 | drop1(fm)
82 |
83 | }
84 | \seealso{
85 | \code{\link{ranova}} for tests of marginal random terms.
86 | }
87 | \author{
88 | Rune Haubo B. Christensen
89 | }
90 |
--------------------------------------------------------------------------------
/man/ensure_full_rank.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/contrast_utils.R
3 | \name{ensure_full_rank}
4 | \alias{ensure_full_rank}
5 | \title{Ensure a Design Matrix has Full (Column) Rank}
6 | \usage{
7 | ensure_full_rank(X, tol = 1e-07, silent = FALSE, test.ans = FALSE)
8 | }
9 | \arguments{
10 | \item{X}{a design matrix as produced by \code{model.matrix}.}
11 |
12 | \item{tol}{\code{qr} tolerance.}
13 |
14 | \item{silent}{throw message if columns are dropped from \code{X}? Default
15 | is \code{FALSE}.}
16 |
17 | \item{test.ans}{Test if the resulting/returned matrix has full rank? Default
18 | is \code{FALSE}.}
19 | }
20 | \value{
21 | A design matrix in which redundant columns are dropped
22 | }
23 | \description{
24 | Determine and drop redundant columns using the \code{\link{qr}}
25 | decomposition.
26 | }
27 | \keyword{internal}
28 |
--------------------------------------------------------------------------------
/man/get_Fstat_ddf.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/contest.R
3 | \name{get_Fstat_ddf}
4 | \alias{get_Fstat_ddf}
5 | \title{Compute denominator df for F-test}
6 | \usage{
7 | get_Fstat_ddf(nu, tol = 1e-08)
8 | }
9 | \arguments{
10 | \item{nu}{vector of denominator df for the t-statistics}
11 |
12 | \item{tol}{tolerance on the consequtive differences between elements of nu to}
13 | }
14 | \value{
15 | the denominator df; a numerical scalar
16 | }
17 | \description{
18 | From a vector of denominator df from independent t-statistics (\code{nu}),
19 | the denominator df for the corresponding F-test is computed.
20 | }
21 | \details{
22 | Note that if any \code{nu <= 2} then \code{2} is returned. Also, if all nu
23 | are within tol of each other the simple average of the nu-vector is returned.
24 | This is to avoid downward bias.
25 | }
26 | \author{
27 | Rune Haubo B. Christensen
28 | }
29 | \keyword{internal}
30 |
--------------------------------------------------------------------------------
/man/get_contrasts_type1.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/anova_contrasts.R
3 | \name{get_contrasts_type1}
4 | \alias{get_contrasts_type1}
5 | \title{Type I ANOVA table contrasts}
6 | \usage{
7 | get_contrasts_type1(model)
8 | }
9 | \arguments{
10 | \item{model}{a model object with \code{terms} and \code{model.matrix} methods.}
11 | }
12 | \value{
13 | List of contrast matrices - one contrast matrix for each model term.
14 | }
15 | \description{
16 | Type I ANOVA table contrasts
17 | }
18 | \author{
19 | Rune Haubo B. Christensen
20 | }
21 | \keyword{internal}
22 |
--------------------------------------------------------------------------------
/man/get_contrasts_type3.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/anova_contrasts.R
3 | \name{get_contrasts_type3}
4 | \alias{get_contrasts_type3}
5 | \title{Contrasts for Type III Tests}
6 | \usage{
7 | get_contrasts_type3(model, which = NULL)
8 | }
9 | \arguments{
10 | \item{model}{model object.}
11 |
12 | \item{which}{optional character vector naming terms for which to compute the
13 | the contrasts.}
14 | }
15 | \value{
16 | list of contrast matrices.
17 | }
18 | \description{
19 | Contrasts for Type III Tests
20 | }
21 | \keyword{internal}
22 |
--------------------------------------------------------------------------------
/man/get_covbeta.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lmer.R
3 | \name{get_covbeta}
4 | \alias{get_covbeta}
5 | \title{Compute cov(beta) as a Function of varpar of an LMM}
6 | \usage{
7 | get_covbeta(varpar, devfun)
8 | }
9 | \arguments{
10 | \item{varpar}{variance parameters; \code{varpar = c(theta, sigma)}.}
11 |
12 | \item{devfun}{deviance function as a function of theta only.}
13 | }
14 | \value{
15 | cov(beta) at supplied varpar values.
16 | }
17 | \description{
18 | At the optimum cov(beta) is available as vcov(lmer-model). This function
19 | computes cov(beta) at non (RE)ML estimates of \code{varpar}.
20 | }
21 | \author{
22 | Rune Haubo B. Christensen
23 | }
24 | \keyword{internal}
25 |
--------------------------------------------------------------------------------
/man/get_model.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/step.R
3 | \name{get_model}
4 | \alias{get_model}
5 | \title{Extract Model from an Object}
6 | \usage{
7 | get_model(x, ...)
8 | }
9 | \arguments{
10 | \item{x}{an object.}
11 |
12 | \item{...}{currently not used.}
13 | }
14 | \description{
15 | Extract Model from an Object
16 | }
17 | \seealso{
18 | \code{\link{get_model.step_list}}
19 | }
20 | \keyword{internal}
21 |
--------------------------------------------------------------------------------
/man/get_model_matrix.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/terms_utils.R
3 | \name{get_model_matrix}
4 | \alias{get_model_matrix}
5 | \title{Extract or remake model matrix from model}
6 | \usage{
7 | get_model_matrix(model, type = c("extract", "remake"), contrasts = "restore")
8 | }
9 | \arguments{
10 | \item{model}{an \code{lm} or \code{lmerMod} model object.}
11 |
12 | \item{type}{extract or remake model matrix?}
13 |
14 | \item{contrasts}{contrasts settings. These may be restored to those in the
15 | model or they may be changed. If a length one character vector (e.g.
16 | \code{"contr.SAS"}) this is applied to all factors in the model, but it can
17 | also be a list naming factors for which the contrasts should be set as specified.}
18 | }
19 | \value{
20 | the model (or 'design') matrix.
21 | }
22 | \description{
23 | Extract or remake model matrix from model and potentially change the
24 | contrast coding
25 | }
26 | \author{
27 | Rune Haubo B Christensen
28 | }
29 | \keyword{internal}
30 |
--------------------------------------------------------------------------------
/man/get_rdX.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/contrast_utils.R
3 | \name{get_rdX}
4 | \alias{get_rdX}
5 | \title{Compute the 'Full' Rank-Deficient Design Matrix}
6 | \usage{
7 | get_rdX(model, do.warn = TRUE)
8 | }
9 | \arguments{
10 | \item{model}{a model object; lmerMod or lmerModLmerTest.}
11 |
12 | \item{do.warn}{throw a message if there is no data for some factor
13 | combinations.}
14 | }
15 | \value{
16 | the rank-deficien design matrix
17 | }
18 | \description{
19 | Compute the 'Full' Rank-Deficient Design Matrix
20 | }
21 | \author{
22 | Rune Haubo B. Christensen
23 | }
24 | \keyword{internal}
25 |
--------------------------------------------------------------------------------
/man/ham.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/data_documentation.R
3 | \docType{data}
4 | \name{ham}
5 | \alias{ham}
6 | \title{Conjoint Study of Dry Cured Ham}
7 | \format{
8 | \describe{
9 | \item{Consumer}{factor with 81 levels: numbering identifying consumers.}
10 | \item{Product}{factor with four levels.}
11 | \item{Informed.liking}{numeric: hedonic liking for the products.}
12 | \item{Information}{factor with two levels.}
13 | \item{Gender}{factor with two levels.}
14 | \item{Age}{numeric: age of Consumer.}
15 | }
16 | }
17 | \usage{
18 | data(ham)
19 | }
20 | \description{
21 | One of the purposes of the study was to investigate the effect of
22 | information given to the consumers measured in hedonic liking for the
23 | hams. Two of the hams were Spanish and two were Norwegian, each origin
24 | representing different salt levels and different aging time. The
25 | information about origin was given in such way that both true and
26 | false information was given. Essentially a 4x2 design with 4 samples
27 | and 2 information levels. A total of 81 Consumers participated in the
28 | study.
29 | }
30 | \examples{
31 |
32 | # Simple model for the ham data:
33 | fm <- lmer(Informed.liking ~ Product*Information + (1|Consumer) , data=ham)
34 |
35 | # Anova table for the fixed effects:
36 | anova(fm)
37 |
38 | \dontrun{
39 | # Fit 'big' model:
40 | fm <- lmer(Informed.liking ~ Product*Information*Gender*Age +
41 | + (1|Consumer) + (1|Consumer:Product) +
42 | (1|Consumer:Information),
43 | data=ham)
44 | step_fm <- step(fm)
45 | step_fm # Display elimination results
46 | final_fm <- get_model(step_fm)
47 | }
48 |
49 | }
50 | \references{
51 | T. Næs, V. Lengard, S. Bølling Johansen, M. Hersleth (2010)
52 | Alternative methods for combining design variables and consumer preference
53 | with information about attitudes and demographics in conjoint analysis,
54 | \emph{Food Quality and Preference}, 10-4, 368-378, ISSN 0950-3293,
55 | \url{https://doi.org/10.1016/j.foodqual.2009.09.004}.
56 | }
57 | \keyword{datasets}
58 |
--------------------------------------------------------------------------------
/man/is_estimable.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/estimability.R
3 | \name{is_estimable}
4 | \alias{is_estimable}
5 | \title{Estimability of Contrasts}
6 | \usage{
7 | is_estimable(
8 | contrast,
9 | nullspace = NULL,
10 | X = NULL,
11 | tol = sqrt(.Machine$double.eps)
12 | )
13 | }
14 | \arguments{
15 | \item{contrast}{a numeric matrix where each row is a contrast vector for
16 | which estimability is computed. The matrix should have as many columns as
17 | there are columns in the design matrix (which equals the number of
18 | coefficients). If \code{contrast} is a vector it is coerced to a matrix.}
19 |
20 | \item{nullspace}{the nullspace of the design matrix.}
21 |
22 | \item{X}{design matrix.}
23 |
24 | \item{tol}{tolerance for determining if a contrast is orthogonal to the}
25 | }
26 | \value{
27 | a logical vector of length \code{nrow(contrast)} determining if each
28 | contrast is estimable
29 | }
30 | \description{
31 | Computes the estimability of a vector or matrix of contrasts (i.e. linear
32 | functions of the coefficients) from the nullspace of a design matrix or
33 | potentially directly from the design matrix.
34 | }
35 | \examples{
36 |
37 | # FIXME: We need some examples here
38 |
39 | }
40 | \seealso{
41 | \code{\link{nullspace}}
42 | }
43 | \author{
44 | Rune Haubo B. Christensen
45 | }
46 | \keyword{internal}
47 |
--------------------------------------------------------------------------------
/man/legacy.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/legacy.R
3 | \name{anova.merModLmerTest}
4 | \alias{anova.merModLmerTest}
5 | \alias{legacy}
6 | \alias{summary.merModLmerTest}
7 | \alias{ls_means.merModLmerTest}
8 | \alias{lsmeansLT.merModLmerTest}
9 | \alias{difflsmeans.merModLmerTest}
10 | \alias{drop1.merModLmerTest}
11 | \alias{step.merModLmerTest}
12 | \title{Methods for Legacy lmerTest Objects}
13 | \usage{
14 | \method{anova}{merModLmerTest}(
15 | object,
16 | ...,
17 | type = c("III", "II", "I", "3", "2", "1"),
18 | ddf = c("Satterthwaite", "Kenward-Roger", "lme4")
19 | )
20 |
21 | \method{summary}{merModLmerTest}(object, ..., ddf = c("Satterthwaite", "Kenward-Roger", "lme4"))
22 |
23 | \method{ls_means}{merModLmerTest}(
24 | model,
25 | which = NULL,
26 | level = 0.95,
27 | ddf = c("Satterthwaite", "Kenward-Roger"),
28 | pairwise = FALSE,
29 | ...
30 | )
31 |
32 | \method{lsmeansLT}{merModLmerTest}(
33 | model,
34 | which = NULL,
35 | level = 0.95,
36 | ddf = c("Satterthwaite", "Kenward-Roger"),
37 | pairwise = FALSE,
38 | ...
39 | )
40 |
41 | \method{difflsmeans}{merModLmerTest}(
42 | model,
43 | which = NULL,
44 | level = 0.95,
45 | ddf = c("Satterthwaite", "Kenward-Roger"),
46 | ...
47 | )
48 |
49 | \method{drop1}{merModLmerTest}(
50 | object,
51 | scope,
52 | ddf = c("Satterthwaite", "Kenward-Roger", "lme4"),
53 | force_get_contrasts = FALSE,
54 | ...
55 | )
56 |
57 | \method{step}{merModLmerTest}(
58 | object,
59 | ddf = c("Satterthwaite", "Kenward-Roger"),
60 | alpha.random = 0.1,
61 | alpha.fixed = 0.05,
62 | reduce.fixed = TRUE,
63 | reduce.random = TRUE,
64 | keep,
65 | ...
66 | )
67 | }
68 | \arguments{
69 | \item{object}{an \code{lmerModLmerTest} object; the result of \code{lmer()}
70 | after loading the \pkg{lmerTest}-package.}
71 |
72 | \item{...}{for the anova method optionally additional models; for other
73 | methods see the corresponding \code{lmerModLmerTest} methods for details.}
74 |
75 | \item{type}{the type of ANOVA table requested (using SAS terminology)
76 | with Type I being the familiar sequential ANOVA table.}
77 |
78 | \item{ddf}{the method for computing the denominator degrees of freedom and
79 | F-statistics. \code{ddf="Satterthwaite"} (default) uses Satterthwaite's method;
80 | \code{ddf="Kenward-Roger"} uses Kenward-Roger's method,
81 | \code{ddf = "lme4"} returns the lme4-anova table, i.e., using the anova
82 | method for \code{lmerMod} objects as defined in the \pkg{lme4}-package and
83 | ignores the \code{type} argument. Partial matching is allowed.}
84 |
85 | \item{model}{a model object fitted with \code{\link{lmer}} (of class
86 | \code{"lmerModLmerTest"}).}
87 |
88 | \item{which}{optional character vector naming factors for which LS-means should
89 | be computed. If \code{NULL} (default) LS-means for all factors are computed.}
90 |
91 | \item{level}{confidence level.}
92 |
93 | \item{pairwise}{compute pairwise differences of LS-means instead?}
94 |
95 | \item{scope}{optional character vector naming terms to be dropped from the
96 | model. Note that only marginal terms can be dropped. To see which terms are
97 | marginal, use \code{drop.scope(terms(object))}.}
98 |
99 | \item{force_get_contrasts}{enforce computation of contrast matrices by a
100 | method in which the design matrices for full and restricted models are
101 | compared.}
102 |
103 | \item{alpha.random}{alpha for random effects elimination}
104 |
105 | \item{alpha.fixed}{alpha for fixed effects elimination}
106 |
107 | \item{reduce.fixed}{reduce fixed effect structure? \code{TRUE} by default.}
108 |
109 | \item{reduce.random}{reduce random effect structure? \code{TRUE} by default.}
110 |
111 | \item{keep}{an optional character vector of fixed effect terms which should
112 | not be considered for eliminated. Valid terms are given by
113 | \code{attr(terms(object), "term.labels")}. Terms that are marginal to terms
114 | in keep will also not be considered for eliminations.}
115 | }
116 | \description{
117 | Methods are defined for legacy lmerTest objects of class
118 | \code{merModLmerTest} generated with \pkg{lmerTest} version \code{< 3.0-0}.
119 | These methods are defined by interfacing code for \code{lmerModLmerTest}
120 | methods and therefore behaves like these methods do (which may differ from
121 | the behavior of \pkg{lmerTest} version \code{< 3.0-0}.)
122 | }
123 | \examples{
124 | # Load model fits fm1 and fm2 generated with lmerTest version 2.3-37:
125 | load(system.file("testdata","legacy_fits.RData", package="lmerTest"))
126 |
127 | # Apply some methods defined by lmerTest:
128 | anova(fm1)
129 | summary(fm1)
130 | contest(fm1, c(0, 1))
131 | contest(fm1, c(0, 1), joint=FALSE)
132 | drop1(fm1)
133 | ranova(fm1)
134 |
135 | # lme4-methods also work:
136 | fixef(fm1)
137 |
138 | # Ditto for second model fit:
139 | anova(fm2)
140 | summary(fm2)
141 | ls_means(fm2)
142 | difflsmeans(fm2)
143 | }
144 | \author{
145 | Rune Haubo B. Christensen
146 | }
147 | \keyword{internal}
148 |
--------------------------------------------------------------------------------
/man/lmer.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lmer.R
3 | \name{lmer}
4 | \alias{lmer}
5 | \title{Fit Linear Mixed-Effects Models}
6 | \usage{
7 | lmer(
8 | formula,
9 | data = NULL,
10 | REML = TRUE,
11 | control = lmerControl(),
12 | start = NULL,
13 | verbose = 0L,
14 | subset,
15 | weights,
16 | na.action,
17 | offset,
18 | contrasts = NULL,
19 | devFunOnly = FALSE
20 | )
21 | }
22 | \arguments{
23 | \item{formula}{a two-sided linear formula object describing both the
24 | fixed-effects and random-effects part of the model, with the
25 | response on the left of a \code{~} operator and the terms, separated
26 | by \code{+} operators, on the right. Random-effects terms are
27 | distinguished by vertical bars (\code{|}) separating expressions
28 | for design matrices from grouping factors. Two vertical bars
29 | (\code{||}) can be used to specify multiple uncorrelated random
30 | effects for the same grouping variable. %----------
31 | (Because of the way it is implemented, the \code{||}-syntax \emph{works
32 | only for design matrices containing numeric (continuous) predictors};
33 | to fit models with independent categorical effects, see \code{\link[lme4]{dummy}}
34 | or the \code{lmer_alt} function from the \href{https://CRAN.R-project.org/package=afex}{\pkg{afex}} package.)
35 | }
36 |
37 | \item{data}{an optional data frame containing the variables named in
38 | \code{formula}. By default the variables are taken from the
39 | environment from which \code{lmer} is called. While \code{data} is
40 | optional, the package authors \emph{strongly} recommend its use,
41 | especially when later applying methods such as \code{update} and
42 | \code{drop1} to the fitted model (\emph{such methods are not
43 | guaranteed to work properly if \code{data} is omitted}). If
44 | \code{data} is omitted, variables will be taken from the environment
45 | of \code{formula} (if specified as a formula) or from the parent
46 | frame (if specified as a character vector).}
47 |
48 | \item{REML}{logical scalar - Should the estimates be chosen to
49 | optimize the REML criterion (as opposed to the log-likelihood)?}
50 |
51 | \item{control}{a list (of correct class, resulting from
52 | \code{\link[lme4]{lmerControl}()} or \code{\link[lme4]{glmerControl}()}
53 | respectively) containing control parameters, including the nonlinear
54 | optimizer to be used and parameters to be passed through to the
55 | nonlinear optimizer, see the \code{*lmerControl} documentation for
56 | details.}
57 |
58 | \item{start}{a named \code{\link{list}} of starting values for the
59 | parameters in the model. For \code{lmer} this can be a numeric
60 | vector or a list with one component named \code{"theta"}.}
61 |
62 | \item{verbose}{integer scalar. If \code{> 0} verbose output is
63 | generated during the optimization of the parameter estimates. If
64 | \code{> 1} verbose output is generated during the individual
65 | penalized iteratively reweighted least squares (PIRLS) steps.}
66 |
67 | \item{subset}{an optional expression indicating the subset of the rows
68 | of \code{data} that should be used in the fit. This can be a logical
69 | vector, or a numeric vector indicating which observation numbers are
70 | to be included, or a character vector of the row names to be
71 | included. All observations are included by default.}
72 |
73 | \item{weights}{an optional vector of \sQuote{prior weights} to be used
74 | in the fitting process. Should be \code{NULL} or a numeric vector.
75 | Prior \code{weights} are \emph{not} normalized or standardized in
76 | any way. In particular, the diagonal of the residual covariance
77 | matrix is the squared residual standard deviation parameter
78 | \code{\link[lme4]{sigma}} times the vector of inverse \code{weights}.
79 | Therefore, if the \code{weights} have relatively large magnitudes,
80 | then in order to compensate, the \code{\link[lme4]{sigma}} parameter will
81 | also need to have a relatively large magnitude.}
82 |
83 | \item{na.action}{a function that indicates what should happen when the
84 | data contain \code{NA}s. The default action (\code{na.omit},
85 | inherited from the 'factory fresh' value of
86 | \code{getOption("na.action")}) strips any observations with any
87 | missing values in any variables.}
88 |
89 | \item{offset}{this can be used to specify an \emph{a priori} known
90 | component to be included in the linear predictor during
91 | fitting. This should be \code{NULL} or a numeric vector of length
92 | equal to the number of cases. One or more \code{\link{offset}}
93 | terms can be included in the formula instead or as well, and if more
94 | than one is specified their sum is used. See
95 | \code{\link{model.offset}}.}
96 |
97 | \item{contrasts}{an optional list. See the \code{contrasts.arg} of
98 | \code{model.matrix.default}.}
99 |
100 | \item{devFunOnly}{logical - return only the deviance evaluation
101 | function. Note that because the deviance function operates on
102 | variables stored in its environment, it may not return
103 | \emph{exactly} the same values on subsequent calls (but the results
104 | should always be within machine tolerance).}
105 | }
106 | \value{
107 | an S4 object of class \code{"lmerModLmerTest"}
108 | }
109 | \description{
110 | This function overloads \code{\link[lme4]{lmer}} from the \pkg{lme4}-package
111 | (\code{lme4::lmer}) and adds a couple of slots needed for the computation of
112 | Satterthwaite denominator degrees of freedom. All arguments are the same as
113 | for \code{lme4::lmer} and all the usual \code{lmer}-methods work.
114 | }
115 | \details{
116 | For details about \code{lmer} see \code{\link[lme4]{lmer}}
117 | (\code{help(lme4::lmer)}). The description of all arguments is taken
118 | unedited from the \pkg{lme4}-package.
119 |
120 | In cases when a valid \code{lmer}-object
121 | (\code{lmerMod}) is produced, but when the computations needed for
122 | Satterthwaite df fails, the \code{lmerMod} object is returned - not an
123 | \code{lmerModLmerTest} object.
124 | }
125 | \examples{
126 |
127 | data("sleepstudy", package="lme4")
128 | m <- lmer(Reaction ~ Days + (Days | Subject), sleepstudy)
129 | class(m) # lmerModLmerTest
130 |
131 | }
132 | \seealso{
133 | \code{\link[lme4]{lmer}} and \code{\link{lmerModLmerTest}}
134 | }
135 | \author{
136 | Rune Haubo B. Christensen and Alexandra Kuznetsova for the overload
137 | in \pkg{lmerTest} -- \pkg{lme4}-authors for the underlying implementation
138 | in \pkg{lme4}.
139 | }
140 |
--------------------------------------------------------------------------------
/man/lmerModLmerTest-class.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lmer.R
3 | \docType{class}
4 | \name{lmerModLmerTest-class}
5 | \alias{lmerModLmerTest-class}
6 | \alias{lmerModLmerTest}
7 | \title{Represent Linear Mixed-Effects Models}
8 | \value{
9 | An object of class \code{lmerModLmerTest} with slots as in
10 | \code{lmerMod} objects (see \code{\link[lme4]{merMod}}) and a few
11 | additional slots as described in the slots section.
12 | }
13 | \description{
14 | The \code{lmerModLmerTest} class extends \code{lmerMod} (which extends
15 | \code{merMod}) from the \pkg{lme4}-package.
16 | }
17 | \section{Slots}{
18 |
19 | \describe{
20 | \item{\code{vcov_varpar}}{a numeric matrix holding the asymptotic variance-covariance
21 | matrix of the variance parameters (including sigma).}
22 |
23 | \item{\code{Jac_list}}{a list of gradient matrices (Jacobians) for the gradient of
24 | the variance-covariance of beta with respect to the variance parameters,
25 | where beta are the mean-value parameters available in \code{fixef(object)}.}
26 |
27 | \item{\code{vcov_beta}}{a numeric matrix holding the asymptotic variance-covariance
28 | matrix of the fixed-effect regression parameters (beta).}
29 |
30 | \item{\code{sigma}}{the residual standard deviation.}
31 | }}
32 |
33 | \seealso{
34 | \code{\link[lme4]{lmer}} and \code{\link[lme4]{merMod}}
35 | }
36 | \author{
37 | Rune Haubo B. Christensen
38 | }
39 |
--------------------------------------------------------------------------------
/man/lmerTest-package.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lmerTest.R
3 | \docType{package}
4 | \name{lmerTest-package}
5 | \alias{lmerTest-package}
6 | \alias{lmerTest}
7 | \title{lmerTest: Tests in Linear Mixed Effects Models}
8 | \description{
9 | The \pkg{lmerTest} package provides p-values in type I, II or III
10 | \code{anova} and \code{summary}
11 | tables for linear mixed models (\code{\link{lmer}} model fits cf. \pkg{lme4})
12 | via Satterthwaite's degrees of freedom method; a Kenward-Roger method is also
13 | available via the \pkg{pbkrtest} package.
14 | Model selection and assessment methods include \code{\link{step}},
15 | \code{\link{drop1}}, anova-like tables for random effects (\code{\link{ranova}}),
16 | least-square means (LS-means; \code{\link{ls_means}})
17 | and tests of linear contrasts of fixed effects (\code{\link{contest}}).
18 | }
19 | \section{Key Functions and Methods}{
20 |
21 |
22 | \describe{
23 | \item{lmer}{overloads \code{lme4::lmer} and produced an object of class
24 | \code{lmerModLmerTest} which inherits from \code{lmerMod}. In addition to
25 | computing the model (using \code{lme4::lmer}), \code{lmerTest::lmer}
26 | computes a couple of components needed for the evaluation of Satterthwaite's
27 | denominator degrees of freedom.}
28 | \item{anova}{anova method for \code{\link{lmer}} model fits produces
29 | type I, II, and III anova tables for fixed-effect terms with
30 | Satterthwaite and Kenward-Roger methods for denominator degrees of freedom
31 | for F-tests.}
32 | \item{summary}{summary method for \code{\link{lmer}} model fits adds
33 | denominator degrees of freedom and p-values to the coefficient table.}
34 | \item{ranova}{anova-like table of random effects via likelihood ratio tests
35 | with methods for both \code{lmerMod} and \code{lmerModLmerTest} objects.
36 | \code{ranova} can either test reduction of random-effect terms to simpler
37 | structures or it can test removal of entire random-effect terms.}
38 | \item{drop1}{F-tests of fixed-effect terms using Satterthwaite or
39 | Kenward-Roger methods for denominator degrees of freedom. These 'single term
40 | deletion' tables are useful for model selection and tests of marginal terms.
41 | Compared to the likelihood ratio tests of \code{lme4::drop1} the F-tests and
42 | p-values of \code{lmerTest::drop1} are more accurate and considerably faster
43 | since no additional model fitting is required.}
44 | \item{contest}{tests of contrasts, i.e. tests of linear functions of the
45 | fixed-effect coefficients. A user-friendly interface for tests of contrasts
46 | with outputs either as a summary-like table of t-tests or an anova-like table
47 | of F-tests (or a list of either). Contrasts can optionally be tested for
48 | estimability. Contrasts are allowed to be rank-deficient as the rank is
49 | automatically detected and appropriate adjustments made. Methods for
50 | \code{lmerModLmerTest} as well as \code{lmerMod} objects -- the latter avoids
51 | the Satterthwaite specific computations when the Kenward-Roger method is used.}
52 | \item{show_test}{a function which operates on anova tables and LS-means tables
53 | makes it possible to see exactly which
54 | functions of the coefficients are being tested. This is helpful when
55 | differences between type I, II and III anova tables are being considered and
56 | discussed.}
57 | \item{ls_means}{computes the so-called least-squares means (classical Yates
58 | contrasts) as well as pairwise differences of these.}
59 | \item{step}{performs automatic backward model selection of fixed and random
60 | parts of the linear mixed model.}
61 | \item{as_lmerModLmerTest}{an explicit coerce function from class
62 | \code{lmerMod} to \code{lmerModLmerTest}.}
63 | }
64 | }
65 |
66 | \section{Details}{
67 |
68 | The computational approach is to let \code{lmerTest::lmer} compute the
69 | Hessian and derivatives needed for evaluation of degrees of freedom and
70 | t- and F-tests and to store these in the model object. The
71 | Hessian and derivatives are therefore computed only once per model fit
72 | and reused with each call to \code{anova}, \code{summary}, etc. Evaluation of
73 | t and F-tests does not involve model re-fitting.
74 |
75 | \code{lmerTest::lmer} roughly amounts to calling \code{lme4::lmer} followed by
76 | \code{lmerTest::as_lmerModLmerTest}, so for computationally intensive model
77 | fits it can make sense to use \code{lme4::lmer} rather than \code{lmerTest::lmer}
78 | if computational time is an issue and summary tables and anova tables will
79 | not be needed.
80 | }
81 |
82 | \examples{
83 |
84 | ## load lmerTest package
85 | library(lmerTest)
86 |
87 | ## Fit linear mixed model to the ham data:
88 | fm <- lmer(Informed.liking ~ Gender + Information * Product + (1 | Consumer) +
89 | (1 | Consumer:Product), data=ham)
90 |
91 | ## Summary including coefficient table with p-values for t-statistics using
92 | ## Satterthwaite's method for denominator degrees of freedom:
93 | summary(fm)
94 |
95 | ## Type III anova table with p-values for F-tests based on Satterthwaite's
96 | ## method:
97 | (aov <- anova(fm))
98 |
99 | ## Inspect the contrast matrix for the Type III test of Product:
100 | show_tests(aov, fractions = TRUE)$Product
101 |
102 | ## Choose type II anova table with Kenward-Roger method for the F-test:
103 | \dontrun{
104 | if(requireNamespace("pbkrtest", quietly = TRUE))
105 | anova(fm, type=2, ddf="Kenward-Roger")
106 | }
107 |
108 | ## Anova-like table of random-effect terms using likelihood ratio tests:
109 | ranova(fm)
110 |
111 | ## F-tests of 'single term deletions' for all marginal terms:
112 | drop1(fm)
113 |
114 | ## Least-Square means and pairwise differences:
115 | (lsm <- ls_means(fm))
116 | ls_means(fm, which = "Product", pairwise = TRUE)
117 |
118 | ## ls_means also have plot and as.data.frame methods:
119 | \dontrun{
120 | plot(lsm, which=c("Product", "Information"))
121 | as.data.frame(lsm)
122 | ## Inspect the LS-means contrasts:
123 | show_tests(lsm, fractions=TRUE)$Product
124 | }
125 |
126 | ## Contrast test (contest) using a custom contrast:
127 | ## Here we make the 2-df joint test of the main effects of Gender and Information
128 | (L <- diag(length(fixef(fm)))[2:3, ])
129 | contest(fm, L = L)
130 |
131 | ## backward elimination of non-significant effects:
132 | step_result <- step(fm)
133 |
134 | ## Elimination tables for random- and fixed-effect terms:
135 | step_result
136 |
137 | # Extract the model that step found:
138 | final_model <- get_model(step_result)
139 |
140 | }
141 | \references{
142 | Alexandra Kuznetsova, Per B. Brockhoff and Rune H. B. Christensen (2017)
143 | lmerTest Package: Tests in Linear Mixed Effects Models.
144 | \emph{Journal of Statistical Software}, 82(13), 1--26. doi:10.18637/jss.v082.i13
145 | }
146 | \author{
147 | Alexandra Kuznetsova, Per Bruun Brockhoff, Rune Haubo Bojesen Christensen
148 | }
149 |
--------------------------------------------------------------------------------
/man/ls_means.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/ls_means.R
3 | \name{ls_means}
4 | \alias{ls_means}
5 | \alias{difflsmeans}
6 | \alias{lsmeansLT}
7 | \title{LS-means Generic Function}
8 | \usage{
9 | ls_means(model, ...)
10 |
11 | difflsmeans(model, ...)
12 |
13 | lsmeansLT(model, ...)
14 | }
15 | \arguments{
16 | \item{model}{a model object.}
17 |
18 | \item{...}{parsed on to methods.}
19 | }
20 | \description{
21 | LS-means Generic Function
22 | }
23 | \seealso{
24 | \code{\link{ls_means.lmerModLmerTest}}
25 |
26 | \code{\link{difflsmeans.lmerModLmerTest}}
27 |
28 | \code{\link{lsmeansLT.lmerModLmerTest}}
29 | }
30 | \author{
31 | Rune Haubo B. Christensen
32 | }
33 | \keyword{internal}
34 |
--------------------------------------------------------------------------------
/man/ls_means.lmerModLmerTest.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/ls_means.R
3 | \name{ls_means.lmerModLmerTest}
4 | \alias{ls_means.lmerModLmerTest}
5 | \alias{lsmeansLT.lmerModLmerTest}
6 | \alias{difflsmeans.lmerModLmerTest}
7 | \title{LS-means for lmerTest Model Fits}
8 | \usage{
9 | \method{ls_means}{lmerModLmerTest}(
10 | model,
11 | which = NULL,
12 | level = 0.95,
13 | ddf = c("Satterthwaite", "Kenward-Roger"),
14 | pairwise = FALSE,
15 | ...
16 | )
17 |
18 | \method{lsmeansLT}{lmerModLmerTest}(
19 | model,
20 | which = NULL,
21 | level = 0.95,
22 | ddf = c("Satterthwaite", "Kenward-Roger"),
23 | pairwise = FALSE,
24 | ...
25 | )
26 |
27 | \method{difflsmeans}{lmerModLmerTest}(
28 | model,
29 | which = NULL,
30 | level = 0.95,
31 | ddf = c("Satterthwaite", "Kenward-Roger"),
32 | ...
33 | )
34 | }
35 | \arguments{
36 | \item{model}{a model object fitted with \code{\link{lmer}} (of class
37 | \code{"lmerModLmerTest"}).}
38 |
39 | \item{which}{optional character vector naming factors for which LS-means should
40 | be computed. If \code{NULL} (default) LS-means for all factors are computed.}
41 |
42 | \item{level}{confidence level.}
43 |
44 | \item{ddf}{method for computation of denominator degrees of freedom.}
45 |
46 | \item{pairwise}{compute pairwise differences of LS-means instead?}
47 |
48 | \item{...}{currently not used.}
49 | }
50 | \value{
51 | An LS-means table in the form of a \code{data.frame}. Formally an object
52 | of class \code{c("ls_means", "data.frame")} with a number of attributes set.
53 | }
54 | \description{
55 | Computes LS-means or pairwise differences of LS-mean for all factors in a
56 | linear mixed model. \code{lsmeansLT} is provided as an alias for
57 | \code{ls_means} for backward compatibility.
58 | }
59 | \details{
60 | Confidence intervals and p-values are based on the t-distribution using
61 | degrees of freedom based on Satterthwaites or Kenward-Roger methods.
62 |
63 | LS-means is SAS terminology for predicted/estimated marginal means, i.e. means
64 | for levels of factors which are averaged over the levels of other factors in
65 | the model. A flat (i.e. unweighted) average is taken which gives equal weight
66 | to all levels of each of the other factors. Numeric/continuous variables are
67 | set at their mean values. See \pkg{emmeans} package
68 | for more options and greater flexibility.
69 |
70 | LS-means contrasts are checked for estimability and unestimable contrasts appear
71 | as \code{NA}s in the resulting table.
72 |
73 | LS-means objects (of class \code{"ls_means"} have a print method).
74 | }
75 | \examples{
76 |
77 | # Get data and fit model:
78 | data("cake", package="lme4")
79 | model <- lmer(angle ~ recipe * temp + (1|recipe:replicate), cake)
80 |
81 | # Compute LS-means:
82 | ls_means(model)
83 |
84 | # Get LS-means contrasts:
85 | show_tests(ls_means(model))
86 |
87 | # Compute pairwise differences of LS-means for each factor:
88 | ls_means(model, pairwise=TRUE)
89 | difflsmeans(model) # Equivalent.
90 |
91 | }
92 | \seealso{
93 | \code{\link[=show_tests.ls_means]{show_tests}} for display of the
94 | underlying LS-means contrasts.
95 | }
96 | \author{
97 | Rune Haubo B. Christensen and Alexandra Kuznetsova
98 | }
99 |
--------------------------------------------------------------------------------
/man/merModLmerTest-class.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/legacy.R
3 | \docType{class}
4 | \name{merModLmerTest-class}
5 | \alias{merModLmerTest-class}
6 | \alias{merModLmerTest}
7 | \title{Legacy lmerTest representation of Linear Mixed-Effects Models}
8 | \description{
9 | The \code{merModLmerTest} class extends \code{lmerMod} (which extends
10 | \code{merMod}) from the \pkg{lme4}-package.
11 | }
12 | \author{
13 | Rune Haubo B. Christensen
14 | }
15 | \keyword{internal}
16 |
--------------------------------------------------------------------------------
/man/nullspace.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/estimability.R
3 | \name{nullspace}
4 | \alias{nullspace}
5 | \title{Nullspace}
6 | \usage{
7 | nullspace(A, type = c("right", "left"), tol = sqrt(.Machine$double.eps))
8 | }
9 | \arguments{
10 | \item{A}{a numeric matrix.}
11 |
12 | \item{type}{\code{"right"} (default) gives is the standard nullspace,
13 | \code{"left"} gives left nullspace of \code{A}.}
14 |
15 | \item{tol}{tolerance multiple of the first singular value to determine if
16 | subsequent singular values are (sufficiently) positive to be determined
17 | greater than zero.}
18 | }
19 | \value{
20 | a matrix with as many rows as there are columns in \code{A}. The
21 | number of columns (which may be zero) determine the dimensionality of the
22 | nullspace of \code{A}.
23 | }
24 | \description{
25 | Compute the (right or left) nullspace of matrix using a (semi-complete)
26 | Singular Value Decomposition.
27 | }
28 | \details{
29 | This implementation is fastest on matrices with more rows
30 | than columns such as a typical design matrix for a linear model.
31 | }
32 | \examples{
33 |
34 | # FIXME: We need some examples here
35 |
36 | }
37 | \author{
38 | Rune Haubo B. Christensen
39 | }
40 | \keyword{internal}
41 |
--------------------------------------------------------------------------------
/man/plot.ls_means.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/ls_means.R
3 | \name{plot.ls_means}
4 | \alias{plot.ls_means}
5 | \title{Bar Plots of LS-Means}
6 | \usage{
7 | \method{plot}{ls_means}(x, y = NULL, which = NULL, mult = TRUE, ...)
8 | }
9 | \arguments{
10 | \item{x}{an \code{\link{ls_means}} object.}
11 |
12 | \item{y}{not used and ignored with a warning.}
13 |
14 | \item{which}{optional character vector naming factors for which LS-means should
15 | be plotted. If \code{NULL} (default) plots for all LS-means are generated.}
16 |
17 | \item{mult}{if \code{TRUE} and there is more than one term for which to plot
18 | LS-means the plots are organized in panels with \code{facet_wrap}.}
19 |
20 | \item{...}{currently not used.}
21 | }
22 | \value{
23 | generates the desired plots and invisibly returns the plot objects.
24 | }
25 | \description{
26 | Bar plots of LS-means using the \pkg{ggplot2} package.
27 | }
28 | \examples{
29 |
30 | # Fit example model with 2 factors:
31 | data("cake", package="lme4")
32 | cake$Temp <- factor(cake$temperature, ordered = FALSE)
33 | model <- lmer(angle ~ recipe * Temp + (1|recipe:replicate), cake)
34 |
35 | # Extract LS-means:
36 | (lsm <- ls_means(model))
37 |
38 | # Multi-frame plot of the LS-means
39 | plot(lsm)
40 |
41 | # Compute list of 'single frame' plots:
42 | res <- plot(lsm, mult=FALSE)
43 |
44 | # Display each plot separately:
45 | plot(res[[1]])
46 | plot(res[[2]])
47 |
48 | # Example with pairwise differences of LS-means:
49 | (lsm <- ls_means(model, pairwise = TRUE))
50 | plot(lsm, which="Temp")
51 |
52 | }
53 | \seealso{
54 | \code{\link{ls_means.lmerModLmerTest}}
55 | }
56 | \author{
57 | Rune Haubo B. Christensen
58 | }
59 | \keyword{internal}
60 |
--------------------------------------------------------------------------------
/man/plot.step_list.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/step.R
3 | \name{plot.step_list}
4 | \alias{plot.step_list}
5 | \title{Plot LS-means for Backward Reduced Model}
6 | \usage{
7 | \method{plot}{step_list}(
8 | x,
9 | y = NULL,
10 | which = NULL,
11 | pairwise = FALSE,
12 | mult = TRUE,
13 | level = 0.95,
14 | ddf = c("Satterthwaite", "Kenward-Roger"),
15 | ...
16 | )
17 | }
18 | \arguments{
19 | \item{x}{a \code{step_list} object; the result of running
20 | \code{\link[=step.lmerModLmerTest]{step}}.}
21 |
22 | \item{y}{not used and ignored with a warning.}
23 |
24 | \item{which}{optional character vector naming factors for which LS-means should
25 | be plotted. If \code{NULL} (default) plots for all LS-means are generated.}
26 |
27 | \item{pairwise}{pairwise differences of LS-means?}
28 |
29 | \item{mult}{if \code{TRUE} and there is more than one term for which to plot
30 | LS-means the plots are organized in panels with \code{facet_wrap}.}
31 |
32 | \item{level}{confidence level.}
33 |
34 | \item{ddf}{denominator degree of freedom method.}
35 |
36 | \item{...}{currently not used.}
37 | }
38 | \description{
39 | Computes the LS-means for the final backward reduced model and passes these
40 | to \code{\link{plot.ls_means}}.
41 | }
42 | \details{
43 | Error bars are confidence intervals - the default is 95% CI but the confidence
44 | level can be changed.
45 | }
46 | \examples{
47 |
48 | \dontrun{
49 | # Fit example model:
50 | tv <- lmer(Sharpnessofmovement ~ TVset * Picture +
51 | (1 | Assessor:TVset) + (1 | Assessor:Picture) +
52 | (1 | Assessor:Picture:TVset) + (1 | Repeat) + (1 | Repeat:Picture) +
53 | (1 | Repeat:TVset) + (1 | Repeat:TVset:Picture) + (1 | Assessor),
54 | data = TVbo)
55 |
56 | # Backward reduce the model:
57 | (st <- step(tv)) # takes ~10 sec to run
58 |
59 | # Pairwise comparisons of LS-means for Picture and TVset:
60 | plot(st, which=c("Picture", "TVset"), pairwise = TRUE)
61 | }
62 |
63 | }
64 | \seealso{
65 | \code{\link[=ls_means.lmerModLmerTest]{ls_means}} and
66 | \code{\link{plot.ls_means}}
67 | }
68 | \author{
69 | Rune Haubo B. Christensen and Alexandra Kuznetsova
70 | }
71 | \keyword{internal}
72 |
--------------------------------------------------------------------------------
/man/qform.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/utils.R
3 | \name{qform}
4 | \alias{qform}
5 | \title{Compute Quadratic Form}
6 | \usage{
7 | qform(x, A)
8 | }
9 | \arguments{
10 | \item{x}{a numeric vector}
11 |
12 | \item{A}{a symmetric numeric matrix}
13 | }
14 | \value{
15 | a numerical scalar
16 | }
17 | \description{
18 | Efficiently computes \eqn{x' A x} - or in R-notation:
19 | }
20 | \details{
21 | Length of \code{x} should equal the number of rows and columns of \code{A}.
22 | }
23 | \keyword{internal}
24 |
--------------------------------------------------------------------------------
/man/ranova.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/ranova.R
3 | \name{ranova}
4 | \alias{ranova}
5 | \alias{rand}
6 | \title{ANOVA-Like Table for Random-Effects}
7 | \usage{
8 | ranova(model, reduce.terms = TRUE, ...)
9 |
10 | rand(model, reduce.terms = TRUE, ...)
11 | }
12 | \arguments{
13 | \item{model}{a linear mixed effect model fitted with \code{lmer()}
14 | (inheriting from class \code{lmerMod}).}
15 |
16 | \item{reduce.terms}{if \code{TRUE} (default) random-effect terms are
17 | reduced (if possible). If \code{FALSE} random-effect terms are simply
18 | removed.}
19 |
20 | \item{...}{currently ignored}
21 | }
22 | \value{
23 | an ANOVA-like table with single term deletions of random-effects
24 | inheriting from class \code{anova} and \code{data.frame} with the columns:
25 | \item{npar}{number of model parameters.}
26 | \item{logLik}{the log-likelihood for the model. Note that this is the
27 | REML-logLik if the model is fitted with REML.}
28 | \item{AIC}{the AIC for the model evaluated as \code{-2*(logLik - npar)}.
29 | Smaller is better.}
30 | \item{LRT}{the likelihood ratio test statistic; twice the difference in
31 | log-likelihood, which is asymptotically chi-square distributed.}
32 | \item{Df}{degrees of freedom for the likelihood ratio test: the difference in
33 | number of model parameters.}
34 | \item{Pr(>Chisq)}{the p-value.}
35 | }
36 | \description{
37 | Compute an ANOVA-like table with tests of random-effect terms in the model.
38 | Each random-effect term is reduced or removed and likelihood ratio tests of
39 | model reductions are presented in a form similar to that of
40 | \code{\link[=drop1.lmerModLmerTest]{drop1}}.
41 | \code{rand} is an alias for \code{ranova}.
42 | }
43 | \details{
44 | If the model is fitted with REML the tests are REML-likelihood ratio tests.
45 |
46 | A random-effect term of the form \code{(f1 + f2 | gr)} is reduced to
47 | terms of the form \code{(f2 | gr)} and \code{(f1 | gr)} and these reduced
48 | models are compared to the original model.
49 | If \code{reduce.terms} is \code{FALSE} \code{(f1 + f2 | gr)} is removed
50 | instead.
51 |
52 | A random-effect term of the form \code{(f1 | gr)} is reduced to \code{(1 | gr)}
53 | (unless \code{reduce.terms} is \code{FALSE}).
54 |
55 | A random-effect term of the form \code{(1 | gr)} is not reduced but
56 | simply removed.
57 |
58 | A random-effect term of the form \code{(0 + f1 | gr)} or \code{(-1 + f1 | gr)}
59 | is reduced (if \code{reduce.terms = TRUE}) to \code{(1 | gr)}.
60 |
61 | A random-effect term of the form \code{(1 | gr1/gr2)} is automatically
62 | expanded to two terms: \code{(1 | gr2:gr1)} and \code{(1 | gr1)} using
63 | \code{\link[lme4]{findbars}}.
64 |
65 | In this exposition it is immaterial whether \code{f1} and \code{f2} are
66 | factors or continuous variables.
67 | }
68 | \note{
69 | Note that \code{anova} can be used to compare two models and will often
70 | be able to produce the same tests as \code{ranova}. This is, however, not always the
71 | case as illustrated in the examples.
72 | }
73 | \section{Warning}{
74 |
75 | In certain cases tests of non-nested models may be generated. An example
76 | is when \code{(0 + poly(x, 2) | gr)} is reduced (the default) to \code{(1 | gr)}.
77 | To our best knowledge non-nested model comparisons are only generated in
78 | cases which are statistical nonsense anyway (such as in this example where
79 | the random intercept is suppressed).
80 | }
81 |
82 | \examples{
83 |
84 | # Test reduction of (Days | Subject) to (1 | Subject):
85 | fm1 <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
86 | ranova(fm1) # 2 df test
87 |
88 | # This test can also be achieved with anova():
89 | fm2 <- lmer(Reaction ~ Days + (1|Subject), sleepstudy)
90 | anova(fm1, fm2, refit=FALSE)
91 |
92 | # Illustrate reduce.test argument:
93 | # Test removal of (Days | Subject):
94 | ranova(fm1, reduce.terms = FALSE) # 3 df test
95 |
96 | # The likelihood ratio test statistic is in this case:
97 | fm3 <- lm(Reaction ~ Days, sleepstudy)
98 | 2*c(logLik(fm1, REML=TRUE) - logLik(fm3, REML=TRUE)) # LRT
99 |
100 | # anova() is not always able to perform the same tests as ranova(),
101 | # for example:
102 | anova(fm1, fm3, refit=FALSE) # compares REML with ML and should not be used
103 | anova(fm1, fm3, refit=TRUE) # is a test of ML fits and not what we seek
104 |
105 | # Also note that the lmer-fit needs to come first - not an lm-fit:
106 | # anova(fm3, fm1) # does not work and gives an error
107 |
108 | # ranova() may not generate all relevant test:
109 | # For the following model ranova() indicates that we should not reduce
110 | # (TVset | Assessor):
111 | fm <- lmer(Coloursaturation ~ TVset * Picture + (TVset | Assessor), data=TVbo)
112 | ranova(fm)
113 | # However, a more appropriate model is:
114 | fm2 <- lmer(Coloursaturation ~ TVset * Picture + (1 | TVset:Assessor), data=TVbo)
115 | anova(fm, fm2, refit=FALSE)
116 | # fm and fm2 has essentially the same fit to data but fm uses 5 parameters
117 | # more than fm.
118 |
119 | }
120 | \seealso{
121 | \code{\link[=drop1.lmerModLmerTest]{drop1}} for tests of marginal
122 | fixed-effect terms and
123 | \code{\link{anova}} for usual anova tables for fixed-effect terms.
124 | }
125 | \author{
126 | Rune Haubo B. Christensen and Alexandra Kuznetsova
127 | }
128 |
--------------------------------------------------------------------------------
/man/rbindall.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/utils.R
3 | \name{rbindall}
4 | \alias{rbindall}
5 | \title{\code{rbind} Multiple Objects}
6 | \usage{
7 | rbindall(...)
8 | }
9 | \arguments{
10 | \item{...}{objects to be \code{rbind}'ed - typically matrices or vectors}
11 | }
12 | \description{
13 | \code{rbind} Multiple Objects
14 | }
15 | \keyword{internal}
16 |
--------------------------------------------------------------------------------
/man/rm_complete_terms.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/ranova.R
3 | \name{rm_complete_terms}
4 | \alias{rm_complete_terms}
5 | \title{Remove Terms from Formula}
6 | \usage{
7 | rm_complete_terms(terms, full_formula, random = TRUE)
8 | }
9 | \arguments{
10 | \item{terms}{character vector (or list) of terms to remove from
11 | \code{full_formula}}
12 |
13 | \item{full_formula}{formula}
14 |
15 | \item{random}{if \code{TRUE} names of the return list have parentheses around
16 | them.}
17 | }
18 | \description{
19 | Remove fixef or ranef terms from formula, return a list of modified formulae
20 | with environment restored to that of the original formula.
21 | }
22 | \keyword{internal}
23 |
--------------------------------------------------------------------------------
/man/show_tests.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lmer_anova.R
3 | \name{show_tests}
4 | \alias{show_tests}
5 | \alias{show_tests.default}
6 | \title{Show Tests Generic Function and Default Method}
7 | \usage{
8 | show_tests(object, ...)
9 |
10 | \method{show_tests}{default}(object, fractions = FALSE, names = TRUE, ...)
11 | }
12 | \arguments{
13 | \item{object}{a suitable object with an \code{"hypotheses"} attribute, e.g. an
14 | anova table or an \code{ls_means} table as defined in \pkg{lmerTest}.}
15 |
16 | \item{...}{parsed on to methods; currently not used in the default method.}
17 |
18 | \item{fractions}{display entries in the hypothesis matrices as fractions?}
19 |
20 | \item{names}{if \code{FALSE} column and row names of the hypothesis matrices
21 | are suppressed.}
22 | }
23 | \description{
24 | Show Tests Generic Function and Default Method
25 | }
26 | \seealso{
27 | \code{\link{show_tests.anova}} and \code{\link{show_tests.ls_means}}
28 | }
29 | \author{
30 | Rune Haubo B. Christensen
31 |
32 | Rune Haubo B. Christensen
33 | }
34 | \keyword{internal}
35 |
--------------------------------------------------------------------------------
/man/show_tests.anova.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lmer_anova.R
3 | \name{show_tests.anova}
4 | \alias{show_tests.anova}
5 | \title{Show Hypothesis Tests in ANOVA Tables}
6 | \usage{
7 | \method{show_tests}{anova}(object, fractions = FALSE, names = TRUE, ...)
8 | }
9 | \arguments{
10 | \item{object}{an anova table with a \code{"hypotheses"} attribute.}
11 |
12 | \item{fractions}{display entries in the hypothesis matrices as fractions?}
13 |
14 | \item{names}{if \code{FALSE} column and row names of the hypothesis matrices
15 | are suppressed.}
16 |
17 | \item{...}{currently not used.}
18 | }
19 | \value{
20 | a list of hypothesis matrices.
21 | }
22 | \description{
23 | Extracts hypothesis matrices for terms in ANOVA tables detailing exactly which
24 | functions of the parameters are being tested in anova tables.
25 | }
26 | \examples{
27 |
28 | # Fit basic model to the 'cake' data:
29 | data("cake", package="lme4")
30 | fm1 <- lmer(angle ~ recipe * temp + (1|recipe:replicate), cake)
31 |
32 | # Type 3 anova table:
33 | (an <- anova(fm1, type="3"))
34 |
35 | # Display tests/hypotheses for type 1, 2, and 3 ANOVA tables:
36 | # (and illustrate effects of 'fractions' and 'names' arguments)
37 | show_tests(anova(fm1, type="1"))
38 | show_tests(anova(fm1, type="2"), fractions=TRUE, names=FALSE)
39 | show_tests(an, fractions=TRUE)
40 |
41 | }
42 | \seealso{
43 | \code{\link[=show_tests.ls_means]{show_tests}} for \code{ls_means}
44 | objects.
45 | }
46 | \author{
47 | Rune Haubo B. Christensen
48 | }
49 |
--------------------------------------------------------------------------------
/man/show_tests.ls_means.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/ls_means.R
3 | \name{show_tests.ls_means}
4 | \alias{show_tests.ls_means}
5 | \title{Show LS-means Hypothesis Tests and Contrasts}
6 | \usage{
7 | \method{show_tests}{ls_means}(object, fractions = FALSE, names = TRUE, ...)
8 | }
9 | \arguments{
10 | \item{object}{an \code{ls_means} object.}
11 |
12 | \item{fractions}{display contrasts as fractions rather than decimal numbers?}
13 |
14 | \item{names}{include row and column names of the contrasts matrices?}
15 |
16 | \item{...}{currently not used.}
17 | }
18 | \value{
19 | a list of contrast matrices; one matrix for each model term.
20 | }
21 | \description{
22 | Extracts the contrasts which defines the LS-mean hypothesis tests.
23 | }
24 | \examples{
25 |
26 | data("cake", package="lme4")
27 | model <- lmer(angle ~ recipe * temp + (1|recipe:replicate), cake)
28 |
29 | # LS-means:
30 | (lsm <- ls_means(model))
31 |
32 | # Contrasts for LS-means estimates and hypothesis tests:
33 | show_tests(lsm)
34 |
35 | }
36 | \seealso{
37 | \code{\link[=ls_means.lmerModLmerTest]{ls_means}} for computation of
38 | LS-means and \code{\link[=show_tests.anova]{show_tests}} for \code{anova}
39 | objects.
40 | }
41 | \author{
42 | Rune Haubo B. Christensen
43 | }
44 |
--------------------------------------------------------------------------------
/man/single_anova.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lmer_anova.R
3 | \name{single_anova}
4 | \alias{single_anova}
5 | \title{ANOVA Tables for Linear Mixed Models}
6 | \usage{
7 | single_anova(
8 | object,
9 | type = c("III", "II", "I", "3", "2", "1", "yates", "marginal", "2b"),
10 | ddf = c("Satterthwaite", "Kenward-Roger")
11 | )
12 | }
13 | \arguments{
14 | \item{object}{an \code{lmerModLmerTest} object; the result of \code{lmer()}
15 | after loading the \pkg{lmerTest}-package.}
16 |
17 | \item{type}{the type of ANOVA table requested (using the SAS terminology for
18 | these) with Type I being the familiar sequential ANOVA table.}
19 |
20 | \item{ddf}{method for computing denominator degrees of freedom.}
21 | }
22 | \value{
23 | an ANOVA table
24 | }
25 | \description{
26 | ANOVA Tables for Linear Mixed Models
27 | }
28 | \author{
29 | Rune Haubo B. Christensen
30 | }
31 | \keyword{internal}
32 |
--------------------------------------------------------------------------------
/man/step.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/step.R
3 | \name{step}
4 | \alias{step}
5 | \alias{step.default}
6 | \title{Generic Step Function}
7 | \usage{
8 | step(object, ...)
9 |
10 | \method{step}{default}(object, ...)
11 | }
12 | \arguments{
13 | \item{object}{a model object.}
14 |
15 | \item{...}{currently not used.}
16 | }
17 | \description{
18 | Generic step function with default method \code{stats::step}. This
19 | construction ensures that \code{stats::step} still works on \code{lm}
20 | objects etc. after loading the \pkg{lmerTest} package.
21 | }
22 | \seealso{
23 | \code{\link[=step.lmerModLmerTest]{step}}
24 | }
25 | \author{
26 | Rune Haubo B. Christensen
27 | }
28 | \keyword{internal}
29 |
--------------------------------------------------------------------------------
/man/step.lmerModLmerTest.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/step.R
3 | \name{step.lmerModLmerTest}
4 | \alias{step.lmerModLmerTest}
5 | \alias{get_model.step_list}
6 | \title{Backward Elimination for Linear Mixed Models}
7 | \usage{
8 | \method{step}{lmerModLmerTest}(
9 | object,
10 | ddf = c("Satterthwaite", "Kenward-Roger"),
11 | alpha.random = 0.1,
12 | alpha.fixed = 0.05,
13 | reduce.fixed = TRUE,
14 | reduce.random = TRUE,
15 | keep,
16 | ...
17 | )
18 |
19 | \method{get_model}{step_list}(x, ...)
20 | }
21 | \arguments{
22 | \item{object}{a fitted model object. For the \code{lmerModLmerTest} method
23 | an \code{\link{lmer}} model fit (of class \code{"lmerModLmerTest"}.)}
24 |
25 | \item{ddf}{the method for computing the denominator degrees of freedom and
26 | F-statistics. \code{ddf="Satterthwaite"} (default) uses Satterthwaite's method;
27 | \code{ddf="Kenward-Roger"} uses Kenward-Roger's method.}
28 |
29 | \item{alpha.random}{alpha for random effects elimination}
30 |
31 | \item{alpha.fixed}{alpha for fixed effects elimination}
32 |
33 | \item{reduce.fixed}{reduce fixed effect structure? \code{TRUE} by default.}
34 |
35 | \item{reduce.random}{reduce random effect structure? \code{TRUE} by default.}
36 |
37 | \item{keep}{an optional character vector of fixed effect terms which should
38 | not be considered for eliminated. Valid terms are given by
39 | \code{attr(terms(object), "term.labels")}. Terms that are marginal to terms
40 | in keep will also not be considered for eliminations.}
41 |
42 | \item{...}{currently not used.}
43 |
44 | \item{x}{a step object.}
45 | }
46 | \value{
47 | \code{step} returns a list with elements \code{"random"} and
48 | \code{"fixed"} each
49 | containing anova-like elimination tables. The \code{"fixed"} table is
50 | based on \code{drop1} and the \code{"random"} table is
51 | based on \code{ranova} (a \code{drop1}-like table for random effects). Both
52 | tables have a column \code{"Eliminated"} indicating the order in which terms
53 | are eliminated from the model with zero (\code{0}) indicating that the term
54 | is not eliminated from the model.
55 |
56 | The \code{step} object also contains the final model as an attribute which
57 | is extractable with \code{get_model()}.
58 | }
59 | \description{
60 | Backward elimination of random-effect terms followed by backward elimination
61 | of fixed-effect terms in linear mixed models.
62 | }
63 | \details{
64 | Tests of random-effects are performed using \code{\link{ranova}} (using
65 | \code{reduce.terms = TRUE}) and tests of fixed-effects are performed using
66 | \code{\link[=drop1.lmerModLmerTest]{drop1}}.
67 |
68 | The step method for \code{\link{lmer}} fits has a print method.
69 | }
70 | \examples{
71 |
72 | # Fit a model to the ham dataset:
73 | fm <- lmer(Informed.liking ~ Product*Information+
74 | (1|Consumer) + (1|Product:Consumer)
75 | + (1|Information:Consumer), data=ham)
76 |
77 | # Backward elimination using terms with default alpha-levels:
78 | (step_res <- step(fm))
79 | final <- get_model(step_res)
80 | anova(final)
81 |
82 | \dontrun{
83 | # Fit 'big' model:
84 | fm <- lmer(Informed.liking ~ Product*Information*Gender*Age +
85 | + (1|Consumer) + (1|Consumer:Product) +
86 | (1|Consumer:Information), data=ham)
87 | step_fm <- step(fm)
88 | step_fm # Display elimination results
89 | final_fm <- get_model(step_fm)
90 | }
91 |
92 | }
93 | \seealso{
94 | \code{\link[=drop1.lmerModLmerTest]{drop1}} for tests of marginal
95 | fixed-effect terms and \code{\link{ranova}} for a
96 | \code{\link[=drop1.lmerModLmerTest]{drop1}}-like table of reduction of
97 | random-effect terms.
98 | }
99 | \author{
100 | Rune Haubo B. Christensen and Alexandra Kuznetsova
101 | }
102 |
--------------------------------------------------------------------------------
/man/summary.lmerModLmerTest.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/lmer_summary.R
3 | \name{summary.lmerModLmerTest}
4 | \alias{summary.lmerModLmerTest}
5 | \title{Summary Method for Linear Mixed Models}
6 | \usage{
7 | \method{summary}{lmerModLmerTest}(object, ..., ddf = c("Satterthwaite", "Kenward-Roger", "lme4"))
8 | }
9 | \arguments{
10 | \item{object}{an lmerModLmerTest object.}
11 |
12 | \item{...}{additional arguments passed on to \code{lme4::summary.merMod}}
13 |
14 | \item{ddf}{the method for computing the degrees of freedom and
15 | t-statistics. \code{ddf="Satterthwaite"} (default) uses Satterthwaite's method;
16 | \code{ddf="Kenward-Roger"} uses Kenward-Roger's method,
17 | \code{ddf = "lme4"} returns the lme4-summary i.e., using the summary
18 | method for \code{lmerMod} objects as defined in the \pkg{lme4}-package and
19 | ignores the \code{type} argument. Partial matching is allowed.}
20 | }
21 | \value{
22 | A summary object with a coefficient table (a \code{matrix}) including
23 | t-values and p-values. The coefficient table can be extracted with
24 | \code{coef(summary())}.
25 | }
26 | \description{
27 | Summaries of Linear Mixed Models with coefficient tables including t-tests
28 | and p-values using Satterthwaites's or Kenward-Roger's methods for
29 | degrees-of-freedom and t-statistics.
30 | }
31 | \details{
32 | The returned object is of class
33 | \code{c("summary.lmerModLmerTest", "summary.merMod")} utilizing \code{print},
34 | \code{coef} and other methods defined for \code{summary.merMod} objects.
35 | The \code{"Kenward-Roger"} method use methods from the \pkg{pbkrtest} package internally
36 | to compute t-statistics and associated degrees-of-freedom.
37 | }
38 | \examples{
39 |
40 | # Fit example model:
41 | data("sleepstudy", package="lme4")
42 | fm <- lmer(Reaction ~ Days + (1|Subject) + (0+Days|Subject), sleepstudy)
43 |
44 | # Get model summary:
45 | summary(fm) # Satterthwaite df and t-tests
46 |
47 | # Extract coefficient table:
48 | coef(summary(fm))
49 |
50 | # Use the Kenward-Roger method
51 | if(requireNamespace("pbkrtest", quietly = TRUE))
52 | summary(fm, ddf="Kenward-Roger")
53 |
54 | # The lme4-summary table:
55 | summary(fm, ddf="lme4") # same as summary(as(fm, "lmerMod"))
56 |
57 | \dontshow{
58 | # Check that summaries are as expected:
59 | summ_fm <- coef(summary(fm))
60 | summ_fm_lme4 <- coef(summary(fm, ddf="lme4"))
61 | stopifnot(
62 | all(colnames(summ_fm) == c("Estimate", "Std. Error", "df", "t value", "Pr(>|t|)")),
63 | all(colnames(summ_fm_lme4) == c("Estimate", "Std. Error", "t value")),
64 | all(!(is.na(summ_fm))),
65 | all(!(is.na(summ_fm_lme4)))
66 | )
67 | if(requireNamespace("pbkrtest", quietly = TRUE) && getRversion() >= "3.3.3") {
68 | summ_fm_kr <- coef(summary(fm, ddf="Kenward-Roger"))
69 | stopifnot(
70 | all(colnames(summ_fm_kr) == c("Estimate", "Std. Error", "df", "t value", "Pr(>|t|)")),
71 | all(!(is.na(summ_fm_kr)))
72 | )
73 | }
74 | }
75 | }
76 | \seealso{
77 | \code{\link{contest1D}} for one degree-of-freedom contrast tests
78 | and \code{\link[pbkrtest]{KRmodcomp}} for Kenward-Roger F-tests.
79 | }
80 | \author{
81 | Rune Haubo B. Christensen and Alexandra Kuznetsova
82 | }
83 |
--------------------------------------------------------------------------------
/man/term_contain.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/contrast_utils.R
3 | \name{term_contain}
4 | \alias{term_contain}
5 | \title{Determine which Terms Contain a Term}
6 | \usage{
7 | term_contain(term, factors, dataClasses, term_names)
8 | }
9 | \arguments{
10 | \item{term}{character; name of a model term and one of \code{term_names}.}
11 |
12 | \item{factors}{the result of \code{attr(terms_object, "factors")}.}
13 |
14 | \item{dataClasses}{the result of
15 | \code{attr(terms(model, fixed.only=FALSE), "dataClasses")}. Note that
16 | \code{fixed.only=FALSE} is only needed for \code{merMod} objects, but does
17 | no harm for \code{lm} objects.}
18 |
19 | \item{term_names}{the result of \code{attr(terms_object, "term.labels")}.}
20 | }
21 | \value{
22 | a logical vector indicating for each term in \code{term_names} if
23 | it contains \code{term}.
24 | }
25 | \description{
26 | The definition of \emph{containment} follows from the SAS documentation on
27 | "The Four Types of Estimable Functions".
28 | }
29 | \details{
30 | Containment is defined for two model terms, say, F1 and F2 as:
31 | F1 is contained in F2 (F2 contains F1) if
32 | \enumerate{
33 | \item F1 and F2 involve the same continuous variables (if any)
34 | \item F2 involve more factors than F1
35 | \item All factors in F1 (if any) are part of F2
36 | }
37 | The intercept, though not really a model term, is defined by SAS to be
38 | contained in all factor terms, but it is not contained in any
39 | effect involving a continuous variable.
40 | }
41 | \keyword{internal}
42 |
--------------------------------------------------------------------------------
/misc/copyright_header.txt:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # Copyright (c) 2013-2020 Alexandra Kuznetsova, Per Bruun Brockhoff, and
3 | # Rune Haubo Bojesen Christensen
4 | #
5 | # This file is part of the lmerTest package for R (*lmerTest*)
6 | #
7 | # *lmerTest* is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 2 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # *lmerTest* is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # A copy of the GNU General Public License is available at
18 | # and/or
19 | # .
20 | #############################################################################
21 |
--------------------------------------------------------------------------------
/misc/modify_copyright_header.R:
--------------------------------------------------------------------------------
1 |
2 | ########################################################
3 | ## Change or modify copyright header in R-files:
4 |
5 | cp_header <- readLines("~/GitHub/lmerTestR/package/misc/copyright_header.txt")
6 |
7 | folder <- "~/GitHub/lmerTestR/package/R"
8 | filenames <- list.files(folder)
9 |
10 | # fn <- filenames[1] # for tests
11 | for(fn in filenames) {
12 | filepath <- paste(folder, fn, sep="/")
13 | txt <- readLines(filepath)
14 | # Get index of copyright header first and last line:
15 | ind <- grep("^########################################", txt)
16 | # Check if copyright header exists in file:
17 | if(grepl("Copyright (c)", txt[ind[1]+1], fixed=TRUE)) {
18 | txt <- txt[-seq_len(ind[2])] # remove copyright header
19 | txt <- c(cp_header, txt) # add new copyright header
20 | writeLines(txt, con=filepath) # write to file
21 | } else {
22 | warning(sprintf("No copyright header found in file: %s.", fn))
23 | }
24 | }
25 |
26 | ########################################################
27 | # Write copyright header to new file:
28 | #
29 | # for(fn in filenames) {
30 | # filepath <- paste(folder, fn, sep="/")
31 | # txt <- readLines(filepath)
32 | # writeLines(c(cp_header, txt), con=filepath)
33 | # }
34 |
35 | ########################################################
36 |
--------------------------------------------------------------------------------
/pkg_notes/Satterthwaite_for_LMMs.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runehaubo/lmerTestR/35dc5885205d709cdc395b369b08ca2b7273cb78/pkg_notes/Satterthwaite_for_LMMs.pdf
--------------------------------------------------------------------------------
/pkg_notes/implementation.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Implementation in package lmerTestR"
3 | author: "Rune Haubo B Christensen"
4 | date: "`r Sys.Date()`"
5 | output:
6 | html_document:
7 | toc: TRUE
8 | ---
9 |
10 | ```{r setup, include=FALSE}
11 | knitr::opts_chunk$set(echo = TRUE)
12 | ```
13 |
14 | ## `lmer` fitting linear mixed models
15 |
16 | **lmerTestR** overloads `lmer` from **lme4** in order to facilitate the computation of summary tables, anova tabels and tests of costum contrasts with $t$ and $F$ tests using the Satterthwaite method for computation of denominator degrees of freedom.
17 |
18 | 1. `lmerTestR::lmer` produces an object of class `lmerModLmerTest` extending class `lmerMod` (as produced by `lme4::lmer`)
19 | 1. `lmerTestR::lmer` adds slots containing the covariance matrix of the variance-covariance parameters in the model and the gradient of the covariance matrix of the fixed effect parameters, $\beta$ (and a few other things) which are required for the computation of Satterthwaite degrees of freedom.
20 | 1. The covariance matrix of the variance-covariance parameters in the model and the gradient of the covariance matrix of the fixed effect parameters are computed numerically using `hessian` and `jacobian` functions from the **numDeriv** package utilizing the accurate Richardson extrapolation method.
21 |
22 | ## Satterthwaite's method for denominator degrees of freedom
23 |
24 | Satterthwaite's method is implemented for one-df contrasts as well as for multi-df contrasts in two functions respectively:
25 |
26 | 1. `contest1D` takes a contrast-vector (or 1D row-matrix) and produces a `data.frame` with $t$-tests in the form similar to a summary coefficient table. This function is used by the `summary` method for `lmer` fits to compute the $p$-values for $t$-tests of the model coefficients.
27 | 1. `contestMD` takes a contrast-matrix (or a vector) and produces a `data.frame` with sums of squares, mean squares, $F$-values, numerator and denominator degrees of freedom and $p$-values in a form similar to that of an ANOVA table. This function is used by the `anova` method for `lmer` fits.
28 |
29 | The computations involved in the Satterthwaite's method are described in a separate document/vignette.
30 |
31 | ## Kenward-Roger's (KR) method
32 |
33 | 1. The KR method is facilitated via the implementation in the **pbkrtest** package (**lmerTestR** _suggests_ this package)
34 | 1. The KR method not only involves an estimate of the denominator df (as does the Satterthwaite method) but also an adjusted covariance matrix of $\beta$ as well as a scaling of the $F$-statistic.
35 | 1. In simple cases the adjusted covariance matrix of $\beta$ equals the standard one and scaling of the $F$-statistics may be neutral.
36 | 1. As a consequence of the adjusted covariance matrix of fixed effect parameters, the standard errors and $t$-values of model coefficients (as in `summary` tables) may be respectively larger and smaller.
37 | 1. The potential scaling applied to $F$-statistics is not applied to $t$-statistics. (I am not sure if $F$-tests on one numerator df will never be scaled -- that may be the case.)
38 | 1. The KR $t$-tests are implemented by computing the adjusted covariance matrix of the fixed effect parameters with `pbkrtest::vcovAdj` and the KR df with `pbkrtest::Lb_ddf`. Computing the KR $t$-tests for a whole set of one-df contrasts (as in a summary table) therefore only involves calculating the adjusted covariance matrix once.
39 | 1. The KR $F$-tests are implemented by passing a contrast matrix to `pbkrtest::KRmodcomp`. When computing $F$-tests for a series of terms (as is done in ANOVA tables) `pbkrtest::KRmodcomp` is called multiple times in each case evaluating the same adjusted covariance matrix of $\beta$ (the computationally time consuming part). We have not found a way to decompose the computations in `pbkrtest::KRmodcomp` so that `pbkrtest::vcovAdj` could be called just once instead. The culprit is the calculation of the scaling of the $F$-value for which **pbkrtest** does not appear to export a low-level (direct) method.
40 | 1. The KR-method is not available for ML-fits and attempts to use ML-fits causes functions in **lmerTestR** to throw an error.
41 |
42 | ## ANOVA tables using the `anova` method
43 |
44 | 1. Produces an ANOVA table if called with a single model as argument - the internal function `single_anova` handles this.
45 | 1. Produces a comparison of models if more than one model is passed to `anova`. This is not implemented in **lmerTestR**; `callNextMethod` is applied.
46 | 1. `single_anova` computes the appropriate contrast matrices (corresponding to type I, II, or III ANOVA tables) and then uses `contestMD` to compute the relevant SSQ, MS, $F$-values etc.
47 |
48 | ### Type I ANOVA tables
49 |
50 | 1. The type I (sequential) ANOVA contrasts are produced by `get_contrasts_type1` which forms the contrasts using the Doolittle decomposition of $X^\top X$ where $X$ is the standard full-rank (column rank) design matrix.
51 |
52 |
53 | ### Type II ANOVA tables
54 |
55 | 1. Not yet implemented
56 |
57 |
58 | ### Type III ANOVA tables
59 |
60 | 1. Type III ANOVA contrasts are produces by `get_contrasts_type3` which uses a SAS-type algorithm based on the 'full' rank-deficient design matrix (produced by `get_rdX`) and a 'general' contrast matrix 'L' (produced by `general_L`).
61 | 1. The algorithm only works when the standard `contr.treatment` or `contr.SAS` is used for coding of factors in the design matrix. Using other "contrasts", for example `contr.sum` or `contr.poly`, which is used by default for ordered factors produces an error.
62 |
63 |
64 | ## The `summary` method for `lmer` model fits
65 |
66 | The summary method does two things to a `lme4::lmer` summary table before it is returned. The `lme4::print.summary.merMod` print method takes care of printing.
67 |
68 | 1. The summary method appends a title to model fit describing which method was used for $t$-tests: Satterthwaite or Kenward-Roger
69 | 1. The summary method computes the coefficient table with (denominator) degrees of freedom and $p$-values for the $t$-statistics by passing the rows of a unit-diagonal matrix with as many rows as there are coefficients to `contest1D`.
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/pkg_notes/implementation_notes.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Notes on the implementation in lmerTest and lmerTestR"
3 | author: "Rune Haubo B Christensen"
4 | date: "`r Sys.Date()`"
5 | output:
6 | html_document:
7 | toc: TRUE
8 | ---
9 |
10 | ```{r setup, include=FALSE}
11 | knitr::opts_chunk$set(echo = TRUE)
12 | ```
13 |
14 | # On the the use of `contr.SAS` in **lmerTest**
15 |
16 | When computing type III ANOVA tables, **lmerTest** refits the model using `contr.SAS`, i.e., SAS-type contrasts for all factors. This has the following consequences:
17 |
18 | Draw backs:
19 |
20 | 1. The same model has to be refit once more thus wasting time and computational recourses.
21 | 1. The coding of ordered factors is changed from `contr.poly` to `contr.SAS`. What is the meaning of type III tests for ordered factors? How does SAS handle these?
22 | 1. There could be cases where the numerical behaviour of the models differ when SAS contrasts are used. For example the model might not converge proporly after changing to SAS contrasts.
23 |
24 | Advantages:
25 |
26 | 1. Irrespective of the contrasts used, type III tests for all terms are produced. This obviously includes the usual `contr.treatment` but also `contr.sum`, `contr.helmert` and `contr.poly` which generates orthogonal polynomials for ordered factors.
27 | 1. Whether `contr.treatment` or `contr.SAS` are used usually does not matter - only the interpretation of coefficients (which are never seen anyway) changes.
28 | 1. The `L`-matrix (containing the general contrast structure) has a particular and known structure.
29 |
30 | Notes:
31 |
32 | 1. It seems that even though models are refitted with `contr.SAS`, that the code also works when `contr.treatment` is used. This means that when the default `contr.treatment` have been used, there should be no reason to refit the models with `contr.SAS`.
33 |
34 | **lmerTestR** takes a different approach since it doesn't refit the models and so throws an error if `contr.treatment` or `contr.SAS` has not been used. Essentially this requires the user to refit the models with one of these contrasts. This will probably rarely be the case, but can come into play if `contr.sum` has been set for some odd reason, or if ordered factors are used in which case `contr.poly` will be used by default.
35 |
36 |
--------------------------------------------------------------------------------
/pkg_notes/new_lmerTest.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/runehaubo/lmerTestR/35dc5885205d709cdc395b369b08ca2b7273cb78/pkg_notes/new_lmerTest.pdf
--------------------------------------------------------------------------------
/pkg_notes/view_html.md:
--------------------------------------------------------------------------------
1 | To view htlm-files in browser, use:
2 |
3 |
4 |
5 | or directly prepend as in the following links:
6 |
7 | 1.
8 | 1.
9 | 1.
10 |
--------------------------------------------------------------------------------
/tests/test_a_utils.R:
--------------------------------------------------------------------------------
1 | # test_a_utils.R
2 |
3 | library(lmerTest)
4 |
5 | # test safeDeparse() - equivalence and differences to deparse():
6 | deparse_args <- formals(deparse)
7 | safeDeparse_args <- formals(lmerTest:::safeDeparse)
8 | stopifnot(
9 | all.equal(names(deparse_args), names(safeDeparse_args)),
10 | all.equal(deparse_args[!names(deparse_args) %in% c("control", "width.cutoff")],
11 | safeDeparse_args[!names(safeDeparse_args) %in% c("control", "width.cutoff")]),
12 | all.equal(deparse_args[["width.cutoff"]], 60L),
13 | all(eval(safeDeparse_args[["control"]]) %in% eval(deparse_args[["control"]])),
14 | all.equal(safeDeparse_args[["width.cutoff"]], 500L)
15 | )
16 |
17 |
--------------------------------------------------------------------------------
/tests/test_compare_sas.R:
--------------------------------------------------------------------------------
1 | # test_compare_sas.R
2 | library(lmerTest)
3 |
4 | # WRE says "using if(requireNamespace("pkgname")) is preferred, if possible."
5 | # even in tests:
6 | assertError <- function(expr, ...)
7 | if(requireNamespace("tools")) tools::assertError(expr, ...) else invisible()
8 | assertWarning <- function(expr, ...)
9 | if(requireNamespace("tools")) tools::assertWarning(expr, ...) else invisible()
10 |
11 | #####################################################################
12 |
13 |
14 | # Use contrasts to get particular estimates for the summary table:
15 | l <- list(Frequency="contr.SAS", Income="contr.SAS")
16 | m.carrots <- lmer(Preference ~ sens2*Frequency*Income
17 | +(1+sens2|Consumer), data=carrots, contrasts=l)
18 | an.m <- anova(m.carrots)
19 |
20 | TOL <- 1e-4
21 | TOL2 <- 1e-5
22 | # with 4 decimals should agree with SAS output
23 | # numbers before decimals should agree with SAS output
24 | stopifnot(
25 | all.equal(an.m[,"Pr(>F)"],
26 | c(2e-5, 0.15512, 0.06939, 0.08223, 0.52459, 0.03119, 0.48344),
27 | tolerance = TOL),
28 | all.equal(round(an.m$DenDF), c(83, 83, 83, 83, 83, 83, 83))
29 | )
30 |
31 | sm <- summary(m.carrots)
32 | stopifnot(
33 | isTRUE(all.equal(sm$coefficients[,"Pr(>|t|)"],
34 | c(1e-10, 0.005061, 0.6865554, 0.342613, 0.129157,
35 | 0.088231, 0.846000, 0.354472, 0.526318, 0.020646, 0.010188,
36 | 0.031242, 0.055356, 0.694689, 0.099382, 0.28547,
37 | 0.977774, 0.855653, 0.427737, 0.321086, 0.417465 , 0.204385, 0.784437,
38 | 0.681434, 0.106180, 0.149122, 0.390870, 0.273686), tolerance=TOL,
39 | check.attributes = FALSE))
40 | )
41 |
42 | # Takes too long to run:
43 | # if(requireNamespace("pbkrtest", quietly = TRUE)) {
44 | # sm.kr <- summary(m.carrots, ddf = "Kenward-Roger")
45 | #
46 | # ## coefficients for Sat and KR agree in this example
47 | # # cbind(sm$coefficients[,"Pr(>|t|)"], sm.kr$coefficients[,"Pr(>|t|)"])
48 | # all.equal(sm$coefficients[,"Pr(>|t|)"], sm.kr$coefficients[,"Pr(>|t|)"],
49 | # tol=TOL)
50 | # }
51 |
52 | ################################################################################
53 | ## checking lsmeans and difflsmeans
54 | ## compare with SAS output
55 | m <- lmer(Informed.liking ~ Product*Information*Gender
56 | + (1|Product:Consumer) + (1|Consumer) , data=ham)
57 |
58 |
59 | lsm <- lsmeansLT(m, which = "Product")
60 | # head(lsm)
61 |
62 | stopifnot(
63 | isTRUE(all.equal(lsm[, "Estimate"], c(5.8084, 5.1012, 6.0909, 5.9256),
64 | tol=TOL, check.attributes = FALSE)),
65 | isTRUE(all.equal(round(lsm[, "t value"], 2), c(24.93, 21.89, 26.14, 25.43), tolerance=TOL,
66 | check.attributes = FALSE)),
67 | isTRUE(all.equal(lsm[, "lower"], c(5.3499, 4.6428, 5.6324, 5.4672), tolerance=TOL,
68 | check.attributes = FALSE)),
69 | isTRUE(all.equal(lsm[, "upper"], c(6.2668, 5.5597, 6.5493, 6.3840), tolerance=TOL,
70 | check.attributes = FALSE))
71 | )
72 |
73 | ################################################################################
74 | # Not actually 'hard-coded' tests versus SAS results...
75 |
76 | m.carrots <- lmer(Preference ~ 0 + sens2 + Homesize +
77 | (1+sens2 | Consumer), data=carrots,
78 | control=lmerControl(optimizer="bobyqa"))
79 | summary(m.carrots)
80 |
81 | (an.1 <- anova(m.carrots, type=1))
82 | (an.3 <- anova(m.carrots))
83 | (an.lme4 <- anova(m.carrots, ddf = "lme4")) # difference in SSQ MS and F-values
84 | # Is this a problem with lme4?
85 | # fm <- lm(Preference ~ 0 + sens2 + Homesize, data=carrots)
86 | # anova(fm)
87 | # coef(summary(fm))
88 | # Here the F value is a little greater than the squared t-value (as expected)
89 |
90 | stopifnot(all.equal(an.1[, "F value"], c(56.5394, 4169.87), tolerance = TOL2),
91 | all.equal(an.3[, "F value"], c(54.8206, 4169.87), tolerance = TOL2))
92 |
93 |
94 | ################################################################################
95 | # Check exmaple from GLM SAS report
96 |
97 | ### example from the paper GLM SAS 101 report
98 | a <- factor(c(1,1,1,2,2,2,2,2,1,2))
99 | b <- factor(c(1,1,2,1,2,2,2,2,2,1))
100 | f=factor(c(1,2,1,2,1,2,1,2,1,2))
101 | y <- c(12,14,11,20,17,23,35,46,15,16)
102 | dd <- data.frame(a=a, b=b, y=y, f=f)
103 |
104 | ## check type 2 is order independent
105 | model <- lmer(y ~ a*b + (1|f), data=dd)
106 | model2 <- lmer(y ~ b*a + (1|f), data=dd)
107 | (an <- anova(model, type=2))
108 | (an2 <- anova(model2, type=2))
109 | stopifnot(
110 | isTRUE(all.equal(an,an2[c(2,1,3),], check.attributes = FALSE, tolerance=TOL2))
111 | )
112 |
113 | ## check the results are the same as from SAS proc mixed
114 | stopifnot(
115 | isTRUE(all.equal(an[,"F value"], c(3.90131, 1.32753, 0.99565), tolerance=TOL2))
116 | )
117 | ################################################################################
118 | ## Check type II and III anova tables versus SAS
119 |
120 | m.carrots <- lmer(Preference ~ sens2*Homesize
121 | +(1+sens2|Consumer), data=carrots)
122 | (ancar <- anova(m.carrots, type=2))
123 |
124 | stopifnot(
125 | isTRUE(all.equal(ancar[,"F value"], c(54.8361, 5.16138, 1.03035), tolerance = TOL))
126 | )
127 |
128 | m <- lmer(Informed.liking ~ Product*Age
129 | + (1|Consumer) , data=ham)
130 | (an <- anova(m, type=2))
131 |
132 | stopifnot(
133 | isTRUE(all.equal(an[,"F value"], c(2.48135, .005387, 1.48451), tolerance = TOL2))
134 | )
135 |
136 |
137 | fm <- lmer(Preference ~ sens2*Homesize*sens1 + (1|Product),
138 | data=carrots)
139 | (ant2 <- anova(fm, type=2))
140 | (ant3 <- anova(fm, type=3))
141 |
142 | stopifnot(
143 | isTRUE(all.equal(ant2[,"F value"],
144 | c(16.4842, 14.0010, .526076, 1.18144,
145 | .107570, .335177, 1.05946), tolerance = TOL)),
146 | isTRUE(all.equal(ant3[,"F value"],
147 | c(16.9140, 14.0010,.481148, 1.18144,
148 | .074201, .335177, 1.05946), tolerance = TOL))
149 | )
150 |
151 | ################################################################################
152 |
153 |
154 |
--------------------------------------------------------------------------------
/tests/test_contest1D.R:
--------------------------------------------------------------------------------
1 | # test_contest1D.R
2 | library(lmerTest)
3 |
4 | # WRE says "using if(requireNamespace("pkgname")) is preferred, if possible."
5 | # even in tests:
6 | assertError <- function(expr, ...)
7 | if(requireNamespace("tools")) tools::assertError(expr, ...) else invisible()
8 | assertWarning <- function(expr, ...)
9 | if(requireNamespace("tools")) tools::assertWarning(expr, ...) else invisible()
10 |
11 | TOL <- 1e-4
12 | # Kenward-Roger only available with pbkrtest and only then validated in R >= 3.3.3
13 | # (faulty results for R < 3.3.3 may be due to unstated dependencies in pbkrtest)
14 | has_pbkrtest <- requireNamespace("pbkrtest", quietly = TRUE) && getRversion() >= "3.3.3"
15 |
16 | data("sleepstudy", package="lme4")
17 |
18 | ####################################
19 | ## Tests of contest1D
20 | ####################################
21 |
22 | fm <- lmer(Reaction ~ Days + I(Days^2) + (1|Subject) + (0+Days|Subject),
23 | sleepstudy)
24 | # Basic tests:
25 | L <- c(0, 1, 0)
26 | contest1D(fm, L)
27 | contest1D(fm, L, confint = TRUE)
28 | contest1D(fm, L, confint = TRUE, level=0.99)
29 | if(has_pbkrtest)
30 | contest1D(fm, L, ddf="Kenward-Roger")
31 |
32 | # Test too long L
33 | assertError(contest1D(fm, c(0, 1, 1, 1)))
34 |
35 | # Test too short L
36 | assertError(contest1D(fm, c(0, 1)))
37 |
38 | # Test matrix L
39 | contest1D(fm, matrix(L, nrow=1))
40 | contest1D(fm, matrix(L, ncol=1))
41 | assertError(contest1D(fm, matrix(c(0, 1), ncol=1)))
42 | assertError(contest1D(fm, matrix(c(0, 1, 0, 0), nrow=1)))
43 | L <- matrix(numeric(0L), ncol=3)
44 | assertError(contest1D(fm, L)) # "empty" matrix
45 | assertError(contest1D(fm, matrix(1, ncol=3, nrow=2)))
46 |
47 | # Test list L
48 | assertError(contest1D(fm, list(c(0, 1, 0))))
49 |
50 | # Test equivalence to coef(summary(fm)):
51 | Lmat <- diag(length(fixef(fm)))
52 | (coef_mat <- lmerTest:::rbindall(lapply(1:ncol(Lmat), function(i)
53 | contest1D(fm, Lmat[i, ]))))
54 | (coef_mat_lme4 <- coef(summary(fm, ddf="lme4")))
55 | rownames(coef_mat) <- rownames(coef_mat_lme4)
56 | stopifnot(isTRUE(
57 | all.equal(as.data.frame(coef_mat_lme4),
58 | coef_mat[, c("Estimate", "Std. Error", "t value")], tolerance=TOL)
59 | ))
60 |
61 | if(has_pbkrtest) {
62 | (coef_mat_KR <- lmerTest:::rbindall(lapply(1:ncol(Lmat), function(i)
63 | contest1D(fm, Lmat[i, ], ddf="Kenward-Roger"))))
64 | rownames(coef_mat_KR) <- rownames(coef_mat_lme4)
65 | stopifnot(isTRUE(
66 | all.equal(as.data.frame(coef_mat_lme4),
67 | coef_mat_KR[, c("Estimate", "Std. Error", "t value")], tolerance=TOL)
68 | ))
69 | }
70 | # Test of 0-length beta
71 | fm1 <- lmer(Reaction ~ 0 + (1|Subject) + (0+Days|Subject),
72 | sleepstudy)
73 | stopifnot(length(fixef(fm1)) == 0L)
74 | if(has_pbkrtest) {
75 | (ans <- contest1D(fm1, numeric(0L), ddf="Kenward-Roger"))
76 | stopifnot(nrow(ans) == 0L)
77 | }
78 |
79 | ## Test rhs argument:
80 | fm <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
81 | contest1D(fm, L=cbind(0, 1))
82 | contest1D(fm, L=cbind(0, 1), rhs=10)
83 | if(has_pbkrtest) {
84 | contest1D(fm, L=cbind(0, 1), ddf="Kenward-Roger")
85 | contest1D(fm, L=cbind(0, 1), ddf="Kenward-Roger", rhs=10)
86 | }
87 |
88 | contest1D(fm, L=c(0, 1), rhs = 10.467)
89 |
90 | (ct1 <- contest1D(fm, L=cbind(c(0, 1)), rhs = 10))
91 | (ct2 <- contestMD(fm, L=rbind(c(0, 1)), rhs = 10))
92 | stopifnot(
93 | isTRUE(all.equal(ct1[, "t value"]^2, ct2[, "F value"], tolerance=1e-6))
94 | )
95 |
96 | ## Test 'lmerMod' method:
97 | fm <- lme4::lmer(Reaction ~ Days + I(Days^2) + (1|Subject) + (0+Days|Subject),
98 | sleepstudy)
99 | # Basic tests:
100 | L <- c(0, 1, 0)
101 | contest1D(fm, L)
102 | contest1D(fm, L, confint = TRUE)
103 | contest1D(fm, L, confint = TRUE, level=0.99)
104 | if(has_pbkrtest)
105 | contest1D(fm, L, ddf="Kenward-Roger")
106 |
107 |
--------------------------------------------------------------------------------
/tests/test_contestMD.R:
--------------------------------------------------------------------------------
1 | # test_contestMD.R
2 | library(lmerTest)
3 |
4 | # WRE says "using if(requireNamespace("pkgname")) is preferred, if possible."
5 | # even in tests:
6 | assertError <- function(expr, ...)
7 | if(requireNamespace("tools")) tools::assertError(expr, ...) else invisible()
8 | assertWarning <- function(expr, ...)
9 | if(requireNamespace("tools")) tools::assertWarning(expr, ...) else invisible()
10 |
11 | # Kenward-Roger only available with pbkrtest and only then validated in R >= 3.3.3
12 | # (faulty results for R < 3.3.3 may be due to unstated dependencies in pbkrtest)
13 | has_pbkrtest <- requireNamespace("pbkrtest", quietly = TRUE) && getRversion() >= "3.3.3"
14 |
15 | data("sleepstudy", package="lme4")
16 |
17 | ####################################
18 | ## Tests of contestMD
19 | ####################################
20 |
21 | fm <- lmer(Reaction ~ Days + I(Days^2) + (1|Subject) + (0+Days|Subject),
22 | sleepstudy)
23 | # Basic tests:
24 | L <- diag(3L)
25 | contestMD(fm, L)
26 |
27 | # Tests of ddf arg:
28 | contestMD(fm, L, ddf="Sat")
29 | if(has_pbkrtest)
30 | contestMD(fm, L, ddf="Kenward-Roger")
31 | assertError(contestMD(fm, L, ddf="sat")) # Invalid ddf arg.
32 |
33 | # Tests of simple 2-df test:
34 | (ans <- contestMD(fm, L[2:3, ], ddf="Sat"))
35 | stopifnot(nrow(ans) == 1L,
36 | ans$NumDF == 2L)
37 | if(has_pbkrtest) {
38 | (ans <- contestMD(fm, L[2:3, ], ddf="Kenward-Roger"))
39 | stopifnot(nrow(ans) == 1L,
40 | ans$NumDF == 2L)
41 | }
42 |
43 | # Tests of simple 1-df test:
44 | (ans <- contestMD(fm, L[3, , drop=FALSE], ddf="Sat"))
45 | stopifnot(nrow(ans) == 1L,
46 | ans$NumDF == 1L)
47 | if(has_pbkrtest) {
48 | (ans <- contestMD(fm, L[3, , drop=FALSE], ddf="Kenward-Roger"))
49 | stopifnot(nrow(ans) == 1L,
50 | ans$NumDF == 1L)
51 | }
52 |
53 | # Test of vector input:
54 | (ans <- contestMD(fm, L[3, ], ddf="Sat")) # OK since length(L[3, ]) == length(fixef(fm))
55 | stopifnot(nrow(ans) == 1L,
56 | ans$NumDF == 1L)
57 | assertError(contestMD(fm, c(1, 0))) # L is too short
58 | assertError(contestMD(fm, c(1, 0, 1, 1))) # L is too long
59 |
60 | # Test of list input:
61 | assertError(contestMD(fm, list(L[3, , drop=FALSE]), ddf="Sat")) # Need L to be a matrix
62 |
63 | # zero-row L's are allowed (if ncol(L) is correct):
64 | ans1 <- contestMD(fm, L[0, , drop=FALSE], ddf="Sat")
65 | stopifnot(nrow(ans1) == 0L)
66 | if(has_pbkrtest) {
67 | ans2 <- contestMD(fm, L[0, , drop=FALSE], ddf="Kenward-Roger")
68 | stopifnot(nrow(ans2) == 0L)
69 | }
70 |
71 | # Test wrong ncol(L):
72 | assertError(contestMD(fm, L[2:3, 2:3])) # need ncol(L) == length(fixef(fm))
73 |
74 | # row-rank deficient L are allowed:
75 | L <- rbind(c(1, 0, 1),
76 | c(0, 1, 0),
77 | c(1, -1, 1))
78 | ans <- contestMD(fm, L)
79 | stopifnot(nrow(L) == 3L,
80 | qr(L)$rank == 2,
81 | ans$NumDF == 2)
82 | if(has_pbkrtest) {
83 | ans_KR <- contestMD(fm, L, ddf="Kenward-Roger")
84 | stopifnot(ans_KR$NumDF == 2)
85 | }
86 |
87 | # Test of 0-length beta
88 | fm1 <- lmer(Reaction ~ 0 + (1|Subject) + (0+Days|Subject),
89 | sleepstudy)
90 | stopifnot(length(fixef(fm1)) == 0L)
91 | L <- numeric(0L)
92 | (ans <- contestMD(fm1, L))
93 | stopifnot(nrow(ans) == 0L)
94 | L <- matrix(numeric(0L), ncol=0L)
95 | (ans <- contestMD(fm1, L))
96 | stopifnot(nrow(ans) == 0L)
97 |
98 |
99 | ## rhs argument:
100 | data("cake", package="lme4")
101 | model <- lmer(angle ~ recipe * temp + (1|recipe:replicate), cake)
102 | (L <- diag(length(fixef(model)))[2:3, ])
103 | (an <- anova(model, type="marginal"))
104 |
105 | ct <- contestMD(model, L, rhs = 0)
106 | ct2 <- contestMD(model, L, rhs = c(2, 2))
107 | stopifnot(
108 | isTRUE(all.equal(ct[1, ], an[1, ], check.attributes=FALSE, tolerance=1e-6)),
109 | ct[, "F value"] < ct2[, "F value"]
110 | )
111 |
112 | L2 <- rbind(L, L[1, ] + L[2, ]) # rank deficient!
113 | contestMD(model, L2, rhs = c(0, 0, 0)) # no warning
114 | assertWarning(contestMD(model, L2, rhs = c(2, 2, 2))) # warning since L2 is rank def.
115 | if(has_pbkrtest)
116 | assertWarning(contestMD(model, L2, rhs = c(2, 2, 2), ddf="Kenward-Roger"))
117 |
118 | fm <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
119 | contestMD(fm, L=cbind(0, 1))
120 | contestMD(fm, L=cbind(0, 1), rhs=10)
121 | if(has_pbkrtest) {
122 | contestMD(fm, L=cbind(0, 1), ddf="Kenward-Roger")
123 | contestMD(fm, L=cbind(0, 1), ddf="Kenward-Roger", rhs=10)
124 | }
125 |
126 |
127 | ## Test 'lmerMod' method:
128 | fm <- lme4::lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
129 | contestMD(fm, L=cbind(0, 1))
130 | contestMD(fm, L=cbind(0, 1), rhs=10)
131 | if(has_pbkrtest) {
132 | contestMD(fm, L=cbind(0, 1), ddf="Kenward-Roger")
133 | contestMD(fm, L=cbind(0, 1), ddf="Kenward-Roger", rhs=10)
134 | }
135 |
--------------------------------------------------------------------------------
/tests/test_contrast_utils.R:
--------------------------------------------------------------------------------
1 | # test_contrast_utils.R
2 |
3 | library(lmerTest)
4 |
5 | ##########
6 | # Test that a message is printed if some cells have zero data:
7 | # Missing a single cell:
8 | data("cake", package="lme4")
9 | cake4 <- cake
10 | cake4$temperature <- factor(cake4$temperature, ordered=FALSE)
11 | cake4 <- droplevels(subset(cake4, !(recipe == "A" & temperature == "175") ))
12 | with(cake4, table(recipe, temperature))
13 |
14 | fm1 <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake4)
15 | an <- anova(fm1)
16 | txt <- capture.output(an <- anova(fm1), type = "message")
17 | stopifnot(length(grep("Missing cells for:", txt)) > 0,
18 | length(grep("Interpret type III hypotheses with care.", txt)) > 0)
19 |
20 | ##########
21 | # Test that a message is printed if some cells have zero data:
22 | # Missing diagonal:
23 | cake4 <- cake
24 | cake4$temperature <- factor(cake4$temperature, ordered=FALSE)
25 | cake4 <- droplevels(subset(cake4, temperature %in% levels(cake4$temperature)[1:3]))
26 | cake4 <- droplevels(subset(cake4, !((recipe == "A" & temperature == "175") |
27 | (recipe == "B" & temperature == "185") |
28 | (recipe == "C" & temperature == "195") )))
29 | cake4$temp0 <- cake4$temp - mean(cake4$temp)
30 | with(cake4, table(recipe, temperature))
31 |
32 | fm1 <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake4)
33 | an <- anova(fm1)
34 | txt <- capture.output(an <- anova(fm1), type = "message")
35 | stopifnot(length(grep("Missing cells for:", txt)) > 0,
36 | length(grep("Interpret type III hypotheses with care.", txt)) > 0)
37 |
38 | ##########
39 | # Test that a message is NOT printed with centered covariates:
40 | fm1 <- lmer(angle ~ recipe * temp0 + (1|recipe:replicate), cake4)
41 | an <- anova(fm1)
42 | txt <- capture.output(an <- anova(fm1), type = "message")
43 | stopifnot(length(grep("Missing cells for:", txt)) == 0,
44 | length(grep("Interpret type III hypotheses with care.", txt)) == 0)
45 | # Note: in many cases a message would not be printed anyway because the
46 | # columns sums in the rdX design matrix would not be exactly zero but just a
47 | # small number very close to zero.
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/tests/test_drop1.R:
--------------------------------------------------------------------------------
1 | # test_drop1.R
2 |
3 | library(lmerTest)
4 |
5 | # WRE says "using if(requireNamespace("pkgname")) is preferred, if possible."
6 | # even in tests:
7 | assertError <- function(expr, ...)
8 | if(requireNamespace("tools")) tools::assertError(expr, ...) else invisible()
9 | assertWarning <- function(expr, ...)
10 | if(requireNamespace("tools")) tools::assertWarning(expr, ...) else invisible()
11 |
12 | TOL <- 1e-4
13 | # Kenward-Roger only available with pbkrtest and only then validated in R >= 3.3.3
14 | # (faulty results for R < 3.3.3 may be due to unstated dependencies in pbkrtest)
15 | has_pbkrtest <- requireNamespace("pbkrtest", quietly = TRUE) && getRversion() >= "3.3.3"
16 |
17 | data("sleepstudy", package="lme4")
18 |
19 | ######### Basic usage
20 |
21 | data("cake", package="lme4")
22 | cake2 <- cake
23 | cake2$temperature <- factor(cake2$temperature, ordered = FALSE)
24 | fm <- lmer(angle ~ recipe + temperature + (1|recipe:replicate), cake2)
25 | (an1 <- drop1(fm))
26 | (an2 <- drop1(fm, force_get_contrasts = TRUE))
27 | drop1(fm, ddf="lme4", test="Chi")
28 | if(has_pbkrtest)
29 | drop1(fm, ddf="Kenward-Roger")
30 |
31 | tests1 <- show_tests(an1)
32 | tests2 <- show_tests(an2)
33 |
34 | stopifnot(
35 | # Tests are the same:
36 | isTRUE(all.equal(an1, an2, check.attributes = FALSE, tolerance=TOL)),
37 | # But contrast matrices are not:
38 | all(!mapply(function(x, y) isTRUE(all.equal(x, y)), tests1, tests2))
39 | )
40 |
41 | fm <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake2)
42 | drop1(fm)
43 | drop1(fm, ddf="lme4")
44 | if(has_pbkrtest)
45 | drop1(fm, ddf="Kenward-Roger")
46 |
47 | # Incorrect arguments:
48 | assertError(drop1(fm, scope="recipe")) # Correct Error
49 | assertError(drop1(fm, scope=3)) # Correct Error
50 | assertError(drop1(fm, scope=list("recipe"))) # Correct Error
51 |
52 | # Polynomial terms:
53 |
54 | fm <- lmer(Reaction ~ 0 + (Days|Subject), sleepstudy)
55 | (an0 <- drop1(fm)) # No fixef!
56 | fm <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
57 | (an1 <- drop1(fm))
58 | fm <- lmer(Reaction ~ Days + I(Days^2) + (Days|Subject), sleepstudy)
59 | (an2 <- (drop1(fm)))
60 | fm <- lmer(Reaction ~ poly(Days, 2) + (Days|Subject), sleepstudy)
61 | (an3 <- drop1(fm))
62 | stopifnot(
63 | nrow(an0) == 0L,
64 | nrow(an1) == 1L,
65 | nrow(an2) == 2L,
66 | nrow(an3) == 1L
67 | )
68 |
69 | # Consider a rank-deficient design matrix:
70 | fm <- lmer(angle ~ recipe + temp + temperature + (1|recipe:replicate), cake)
71 | # Here temp accounts for the linear effect of temperature, and
72 | # temperature is an (ordered) factor that accounts for the remaining
73 | # variation between temperatures (4 df).
74 | (an4 <- drop1(fm))
75 | # While temperature is in the model, we cannot test the effect of dropping
76 | # temp. After removing temperature we can test the effect of dropping temp:
77 | (an5 <- drop1(update(fm, ~.-temperature)))
78 |
79 | stopifnot(
80 | nrow(an4) == 3,
81 | rownames(an4)[2] == "temp",
82 | all(is.na(an4[2, ])),
83 | all(!is.na(an4[-2, ])),
84 | all(rownames(an5) == c("recipe", "temp"))
85 | )
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/tests/test_legacy.R:
--------------------------------------------------------------------------------
1 | # test_legacy.R
2 | library(lmerTest)
3 | TOL <- 1e-4
4 | #####################################################################
5 |
6 | # Read in data set
7 | load(system.file("testdata", "legacy_fits.RData", package="lmerTest"))
8 | # Generated with the following code using lmerTest version 2.0-37.9002
9 | #
10 | # library("lmerTest")
11 | # packageVersion("lmerTest")
12 | # fm1 <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
13 | # (an1 <- anova(fm1))
14 | # (sfm1 <- summary(fm1))
15 | #
16 | # fm2 <- lmer(Informed.liking ~ Product + Information + Gender +
17 | # (1|Product:Consumer) , data=ham)
18 | # (an2 <- anova(fm2))
19 | # (sfm2 <- summary(fm2))
20 | #
21 | # save(fm1, an1, sfm1, fm2, an2, sfm2,
22 | # file="~/GitHub/lmerTestR/package/inst/testdata/legacy_fits.RData")
23 |
24 |
25 | #######################################
26 | ### Check that arguments for merModLmerTest and lmerModLmerTest methods match up:
27 |
28 | stopifnot(
29 | isTRUE(all.equal(formals(lmerTest:::anova.merModLmerTest),
30 | formals(lmerTest:::anova.lmerModLmerTest))),
31 | isTRUE(all.equal(formals(lmerTest:::summary.merModLmerTest),
32 | formals(lmerTest:::summary.lmerModLmerTest))),
33 | isTRUE(all.equal(formals(lmerTest:::drop1.merModLmerTest),
34 | formals(lmerTest:::drop1.lmerModLmerTest))),
35 | isTRUE(all.equal(formals(lmerTest:::step.merModLmerTest),
36 | formals(lmerTest:::step.lmerModLmerTest))),
37 | isTRUE(all.equal(formals(lmerTest:::ls_means.merModLmerTest),
38 | formals(lmerTest:::ls_means.lmerModLmerTest))),
39 | isTRUE(all.equal(formals(lmerTest:::difflsmeans.merModLmerTest),
40 | formals(lmerTest:::difflsmeans.lmerModLmerTest))))
41 |
42 |
43 | #######################################
44 | ## Tests for fm1:
45 |
46 | an1new <- anova(fm1)
47 | sfm1new <- summary(fm1)
48 |
49 | stopifnot(
50 | isTRUE(all.equal(an1new, an1, check.attributes=FALSE, tol=TOL)),
51 | isTRUE(all.equal(coef(sfm1new), coef(sfm1), tol=TOL))
52 | )
53 |
54 | contest(fm1, c(0, 1))
55 | contest(fm1, c(0, 1), joint=FALSE)
56 | drop1(fm1)
57 | ranova(fm1)
58 | step(fm1)
59 |
60 | fm1new <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy,
61 | control=lmerControl(optimizer="bobyqa"))
62 | stopifnot(
63 | isTRUE(all.equal(drop1(fm1), drop1(fm1new), tol=TOL)),
64 | isTRUE(all.equal(ranova(fm1), ranova(fm1new), tol=TOL)),
65 | isTRUE(all.equal(contest(fm1, c(0, 1)), contest(fm1new, c(0, 1)), tol=TOL)),
66 | isTRUE(all.equal(contest(fm1, c(0, 1), joint=FALSE),
67 | contest(fm1new, c(0, 1), joint=FALSE), tol=TOL))
68 | )
69 |
70 | # Test that lme4 methods work:
71 | coef(fm1)
72 | fixef(fm1)
73 | resid(fm1)
74 |
75 | #######################################
76 | ## Tests for fm2:
77 | an2new <- anova(fm2)
78 | sfm2new <- summary(fm2)
79 |
80 | stopifnot(
81 | isTRUE(all.equal(an2new, an2, check.attributes=FALSE, tol=TOL)),
82 | isTRUE(all.equal(coef(sfm2new), coef(sfm2), tol=TOL))
83 | )
84 |
85 | drop1(fm2)
86 | ranova(fm2)
87 | ls_means(fm2)
88 | difflsmeans(fm2)
89 | nbeta <- length(fixef(fm2))
90 | L <- diag(nbeta)
91 | L[1:4, ] <- 0
92 | contest(fm2, L)
93 | contest(fm2, diag(nbeta), joint=FALSE)
94 | step(fm2)
95 |
96 | fm2new <- lmer(Informed.liking ~ Product + Information + Gender +
97 | (1|Product:Consumer), data=ham)
98 | stopifnot(
99 | isTRUE(all.equal(drop1(fm2), drop1(fm2new), tol=TOL)),
100 | isTRUE(all.equal(ranova(fm2), ranova(fm2new), tol=TOL)),
101 | isTRUE(all.equal(ls_means(fm2), ls_means(fm2new), tol=TOL)),
102 | isTRUE(all.equal(difflsmeans(fm2), difflsmeans(fm2new), tol=TOL))
103 | )
104 |
105 | # Test that lme4 methods work:
106 | coef(fm2)
107 | fixef(fm2)
108 | resid(fm2)
109 |
110 |
--------------------------------------------------------------------------------
/tests/test_lmer.R:
--------------------------------------------------------------------------------
1 | # test_lmer.R
2 |
3 | stopifnot(!"lmerTest" %in% .packages()) # ensure that lmerTest is NOT attached
4 | data("sleepstudy", package="lme4")
5 | f <- function(form, data) lmerTest::lmer(form, data=data)
6 | form <- "Reaction ~ Days + (Days|Subject)"
7 | fm <- f(form, data=sleepstudy)
8 | anova(fm)
9 | summary(fm)
10 |
11 | # cf. GitHub issue #2:
12 | test <- function() {
13 | tmp <- sleepstudy
14 | m <- lmerTest::lmer(Reaction ~ Days + (Days | Subject), data = tmp)
15 | summary(m)
16 | }
17 | test()
18 | test <- function() {
19 | tmp <- sleepstudy
20 | m <- lme4::lmer(Reaction ~ Days + (Days | Subject), data = tmp)
21 | if(requireNamespace("lmerTest", quietly = TRUE)) {
22 | summary(lmerTest::as_lmerModLmerTest(m))
23 | }
24 | }
25 | test()
26 |
27 | library(lmerTest)
28 |
29 | # WRE says "using if(requireNamespace("pkgname")) is preferred, if possible."
30 | # even in tests:
31 | assertError <- function(expr, ...)
32 | if(requireNamespace("tools")) tools::assertError(expr, ...) else invisible()
33 | assertWarning <- function(expr, ...)
34 | if(requireNamespace("tools")) tools::assertWarning(expr, ...) else invisible()
35 |
36 | TOL <- 1e-4
37 |
38 | #####################################################################
39 | # Check that lme4::lmer and lmerTest::lmer have the same arguments
40 |
41 | lmer_args <- formals(lme4::lmer)
42 | names(lmer_args)
43 | lmerTest_args <- formals(lmerTest::lmer)
44 | seq_args <- seq_along(lmerTest_args)
45 | if(packageVersion("lme4") > '1.1.21') {
46 | stopifnot(
47 | all.equal(names(lmer_args), names(lmerTest_args)),
48 | all.equal(lmer_args, lmerTest_args)
49 | )
50 | } else { # Older versions of 'lme4' has a "..." argument:
51 | stopifnot(
52 | all.equal(names(lmer_args)[seq_args], names(lmerTest_args[seq_args])),
53 | all.equal(lmer_args[seq_args], lmerTest_args[seq_args])
54 | )
55 | }
56 |
57 | #####################################################################
58 | # Test evaluation of update inside a function:
59 | myupdate <- function(m, ...) {
60 | update(m, ...)
61 | }
62 |
63 | data("sleepstudy", package="lme4")
64 | fm1 <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
65 | tmp <- sleepstudy
66 | rm(sleepstudy)
67 | fmA <- update(fm1, data = tmp) # works
68 | fmB <- myupdate(fm1, data = tmp) # also works
69 | # Same except for 'call':
70 | fmB@call <- fmA@call
71 | stopifnot(isTRUE(all.equal(fmA, fmB, tolerance=TOL)))
72 | # Based on bug-report by Henrik Singmann, github issue #3
73 |
74 | #####################################################################
75 | # Test update when formula is a character vector:
76 |
77 | form <- "Informed.liking ~ Product+Information+
78 | (1|Consumer) + (1|Product:Consumer) + (1|Information:Consumer)"
79 | m <- lmer(form, data=ham)
80 | class(m)
81 | class(update(m, ~.- Product))
82 | stopifnot(inherits(update(m, ~.- Product), "lmerModLmerTest"))
83 |
84 | # In version < 3.0-1.9002 class(update(m, ~.- Product)) was "lmerMod"
85 | #####################################################################
86 | # Test error message from as_lmerModLmerTest:
87 | data("sleepstudy", package="lme4")
88 | myfit <- function(formula, data) {
89 | lme4::lmer(formula = formula, data = data)
90 | }
91 | fm2 <- myfit(Reaction ~ Days + (Days|Subject), sleepstudy)
92 | m <- assertError(as_lmerModLmerTest(fm2))
93 | stopifnot(
94 | grepl("Unable to extract deviance function from model fit", m[[1]], fixed=TRUE)
95 | )
96 |
97 | #####################################################################
98 | # Check that devFunOnly argument works:
99 | data("sleepstudy", package="lme4")
100 | fun <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy, devFunOnly = TRUE)
101 | stopifnot(is.function(fun) && names(formals(fun)[1]) == "theta")
102 | fm1 <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
103 | fun <- update(fm1, devFunOnly=TRUE)
104 | stopifnot(is.function(fun) && names(formals(fun)[1]) == "theta")
105 | # devFunOnly = FALSE:
106 | notfun <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy, devFunOnly = FALSE)
107 | stopifnot(inherits(notfun, "lmerModLmerTest"))
108 | # Partial matching:
109 | notfun <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy, devFun = FALSE)
110 | stopifnot(inherits(notfun, "lmerModLmerTest"))
111 |
112 | #####################################################################
113 | # Use of as_lmerModLmerTest
114 | data("sleepstudy", package="lme4")
115 | m <- lme4::lmer(Reaction ~ Days + (Days | Subject), sleepstudy)
116 | bm <- lmerTest:::as_lmerModLmerTest(m)
117 | stopifnot(
118 | inherits(bm, "lmerModLmerTest"),
119 | !inherits(m, "lmerModLmerTest"),
120 | inherits(bm, "lmerMod"),
121 | all(c("vcov_varpar", "Jac_list", "vcov_beta", "sigma") %in% slotNames(bm))
122 | )
123 |
124 | #####################################################################
125 | # Update method
126 |
127 | m <- lmer(Reaction ~ Days + (Days | Subject), sleepstudy)
128 | m1 <- update(m, ~.-Days)
129 | m2 <- lmer(Reaction ~ (Days | Subject), sleepstudy)
130 |
131 | stopifnot(
132 | inherits(m, "lmerModLmerTest"),
133 | inherits(m1, "lmerModLmerTest"),
134 | inherits(m2, "lmerModLmerTest"),
135 | all.equal(m1, m2, tolerance=1e-6)
136 | )
137 |
138 |
--------------------------------------------------------------------------------
/tests/test_lmerTest_paper.R:
--------------------------------------------------------------------------------
1 | # test_lmerTest_paper.R
2 |
3 | library(lmerTest)
4 |
5 | # Kenward-Roger only available with pbkrtest and only then validated in R >= 3.3.3
6 | # (faulty results for R < 3.3.3 may be due to unstated dependencies in pbkrtest)
7 | has_pbkrtest <- requireNamespace("pbkrtest", quietly = TRUE) && getRversion() >= "3.3.3"
8 |
9 | # Read in data set
10 | load(system.file("testdata","test_paper_objects.RData", package="lmerTest"))
11 |
12 | # Evaluate code from paper:
13 | ## Section 8.2:
14 | tv <- lmer(Sharpnessofmovement ~ TVset * Picture + (1 | Assessor) +
15 | (1 | Assessor:TVset) + (1 | Assessor:Picture), data = TVbo,
16 | control=lmerControl(optimizer="bobyqa"))
17 |
18 | (an8.2 <- anova(tv))
19 |
20 | if(has_pbkrtest)
21 | (ankr8.2 <- anova(tv, type=2, ddf="Kenward-Roger"))
22 |
23 | ## Section 8.3:
24 | m.carrots <- lmer(Preference ~ sens1 + sens2 + (1 + sens1 + sens2 | Consumer) +
25 | (1 | Product), data=carrots,
26 | control=lmerControl(optimizer="bobyqa"))
27 | (sum8.3 <- coef(summary(m.carrots)))
28 |
29 | ## Section 8.4:
30 | tv <- lmer(Sharpnessofmovement ~ TVset * Picture +
31 | (1 | Assessor:TVset) + (1 | Assessor:Picture) +
32 | (1 | Assessor:Picture:TVset) + (1 | Repeat) + (1 | Repeat:Picture) +
33 | (1 | Repeat:TVset) + (1 | Repeat:TVset:Picture) + (1 | Assessor),
34 | data = TVbo,
35 | control=lmerControl(optimizer="bobyqa"))
36 | st <- step(tv)
37 | (elim_tab_random8.4 <- st$random)
38 | (elim_tab_fixed8.4 <- st$fixed)
39 | (an8.4 <- anova(get_model(st)))
40 |
41 | ## Section 8.5:
42 | # L <- matrix(0, ncol = 12, nrow = 6)
43 | # L[1, 7] <- L[2, 8] <- L[3, 9] <- L[4, 10] <- L[5, 11] <- L[6, 12] <- 1
44 | L <- cbind(array(0, dim=c(6, 6)), diag(6))
45 | (con1_8.5 <- calcSatterth(tv, L))
46 | (con2_8.5 <- contest(tv, L))
47 |
48 | ## Section C:
49 | # m.carrots <- lmer(Preference ~ sens1 + sens2 + (1 + sens1 + sens2 | Consumer) +
50 | # (1 | product), data = carrots)
51 | # step(m.carrots, reduce.fixed = FALSE)
52 | (ran_C <- ranova(m.carrots))
53 |
54 | # Compare to validated outputs:
55 | TOL <- 1e-4
56 | stopifnot(
57 | isTRUE(all.equal(an8.2_save, an8.2, check.attributes = FALSE, tolerance=TOL)),
58 | isTRUE(all.equal(sum8.3_save, sum8.3, check.attributes = FALSE, tolerance=TOL)),
59 | isTRUE(all.equal(elim_tab_random8.4_save, elim_tab_random8.4,
60 | check.attributes = FALSE, tolerance=TOL)),
61 | isTRUE(all.equal(elim_tab_fixed8.4_save, elim_tab_fixed8.4,
62 | check.attributes = FALSE, tolerance=TOL)),
63 | isTRUE(all.equal(an8.4_save, an8.4, check.attributes = FALSE, tolerance=TOL)),
64 | isTRUE(all.equal(con1_8.5_save, con1_8.5, check.attributes = FALSE, tolerance=TOL)),
65 | isTRUE(all.equal(con2_8.5_save, con2_8.5, check.attributes = FALSE, tolerance=TOL))
66 | )
67 | if(has_pbkrtest) {
68 | stopifnot(
69 | isTRUE(all.equal(ankr8.2_save, ankr8.2, check.attributes = FALSE, tolerance=TOL))
70 | )
71 | }
72 |
73 |
--------------------------------------------------------------------------------
/tests/test_ls_means.R:
--------------------------------------------------------------------------------
1 | # test_lsmeans.R
2 |
3 | library(lmerTest)
4 |
5 | TOL <- 1e-4
6 | # Kenward-Roger only available with pbkrtest and only then validated in R >= 3.3.3
7 | # (faulty results for R < 3.3.3 may be due to unstated dependencies in pbkrtest)
8 | has_pbkrtest <- requireNamespace("pbkrtest", quietly = TRUE) && getRversion() >= "3.3.3"
9 |
10 | ########### Basic model structures:
11 |
12 | # Factor * covariate:
13 | data("cake", package="lme4")
14 | model <- lmer(angle ~ recipe * temp + (1|recipe:replicate), cake)
15 | (lsm <- ls_means(model))
16 | stopifnot(
17 | nrow(lsm) == 3L,
18 | ncol(lsm) == 7L,
19 | # Balanced, so LS-means equal raw means:
20 | isTRUE(all.equal(c(with(cake, tapply(angle, recipe, mean))), lsm[, "Estimate"],
21 | check.attributes=FALSE, tolerance=TOL))
22 | )
23 |
24 | # Pairwise differences of LS-means:
25 | plsm <- ls_means(model, pairwise = TRUE)
26 | plsm2 <- difflsmeans(model)
27 | C <- as.matrix(lmerTest:::get_pairs(rownames(lsm)))
28 | stopifnot(
29 | isTRUE(all.equal(plsm, plsm2, tolerance=TOL)),
30 | isTRUE(all.equal(plsm[, "Estimate"], c(lsm[, "Estimate"] %*% C),
31 | check.attributes=FALSE, tolerance=TOL))
32 | )
33 |
34 | # Contrasts vectors:
35 | show_tests(lsm)
36 | show_tests(plsm)
37 |
38 | # Factor * Ordered:
39 | model <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake)
40 | (lsm2 <- ls_means(model))
41 | stopifnot(
42 | nrow(lsm2) == 3 + 6 + 3*6,
43 | ncol(lsm) == 7L,
44 | # Balanced, so LS-means equal raw means:
45 | isTRUE(all.equal(lsm[1:3, ], lsm2[1:3, ],
46 | check.attributes=FALSE, tolerance=TOL))
47 | )
48 |
49 |
50 | # Factor * Factor:
51 | cake2 <- cake
52 | cake2$temperature <- factor(cake2$temperature, ordered = FALSE)
53 | model <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake2)
54 | (lsm3 <- ls_means(model))
55 | stopifnot(
56 | isTRUE(all.equal(lsm2, lsm3, check.attributes=FALSE, tolerance=TOL))
57 | )
58 |
59 | # Covariate (only):
60 | data("sleepstudy", package="lme4")
61 | m <- lmer(Reaction ~ Days + (Days | Subject), sleepstudy)
62 | (lsm <- ls_means(m))
63 | stopifnot(
64 | nrow(lsm) == 0L,
65 | ncol(lsm) == 7L
66 | )
67 |
68 | # No fixef:
69 | m <- lmer(Reaction ~ 0 + (Days | Subject), sleepstudy)
70 | (lsm <- ls_means(m))
71 | stopifnot(
72 | nrow(lsm) == 0L,
73 | ncol(lsm) == 7L
74 | )
75 |
76 | ########### Arguments and options:
77 |
78 | # which
79 | model <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake2)
80 | (lsm4 <- ls_means(model, which = "recipe"))
81 | stopifnot(
82 | nrow(lsm4) == 3L,
83 | ncol(lsm4) == 7L,
84 | isTRUE(all.equal(lsm3[1:3, ], lsm4, check.attributes=FALSE, tolerance=TOL))
85 | )
86 |
87 | # KR:
88 | if(has_pbkrtest)
89 | (lsm5 <- ls_means(model, which = "recipe", ddf = "Kenward-Roger"))
90 |
91 | # level:
92 | (lsm6 <- ls_means(model, which = "recipe", level=0.99))
93 |
94 | stopifnot(
95 | all(lsm6[, "lower"] < lsm4[, "lower"]),
96 | all(lsm6[, "upper"] > lsm4[, "upper"])
97 | )
98 |
99 |
100 |
101 | ########### Missing cels -> unestimable contrasts:
102 |
103 | # Missing cell:
104 | cake3 <- cake
105 | cake3$temperature <- factor(cake3$temperature, ordered=FALSE)
106 | cake3 <- droplevels(subset(cake3, temperature %in% levels(cake3$temperature)[1:3]))
107 | cake3 <- droplevels(subset(cake3, !(recipe == "C" & temperature == "195") ))
108 | str(cake3)
109 | with(cake3, table(recipe, temperature))
110 | model <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake3)
111 | (lsm7 <- ls_means(model))
112 |
113 | # Using show_tests with options:
114 | show_tests(lsm7, fractions = TRUE)
115 | show_tests(lsm7, fractions = TRUE, names = FALSE)
116 |
117 | # Missing diagonal:
118 | cake4 <- cake
119 | cake4$temperature <- factor(cake4$temperature, ordered=FALSE)
120 | cake4 <- droplevels(subset(cake4, temperature %in% levels(cake4$temperature)[1:3]))
121 | cake4 <- droplevels(subset(cake4, !((recipe == "A" & temperature == "175") |
122 | (recipe == "B" & temperature == "185") |
123 | (recipe == "C" & temperature == "195") )))
124 | # str(cake4)
125 | with(cake4, table(recipe, temperature))
126 | model <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake4)
127 | ls_means(model)
128 |
129 |
130 | ########### Various contrasts codings:
131 |
132 | model <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake3,
133 | contrasts = list(recipe="contr.sum", temperature="contr.helmert"))
134 | (lsm8 <- ls_means(model))
135 | # show_tests(lsm7)
136 | # show_tests(lsm8)
137 | stopifnot(
138 | isTRUE(all.equal(lsm7, lsm8, check.attributes=FALSE, tolerance=TOL))
139 | )
140 |
141 | # ambient contrasts not contr.treatment:
142 | options("contrasts")
143 | options(contrasts = c("contr.sum", "contr.poly"))
144 | model <- lmer(angle ~ recipe * temperature + (1|recipe:replicate), cake3)
145 | (lsm9 <- ls_means(model))
146 | options(contrasts = c("contr.treatment", "contr.poly"))
147 | options("contrasts")
148 | stopifnot(
149 | isTRUE(all.equal(lsm7, lsm9, check.attributes=FALSE, tolerance=TOL))
150 | )
151 |
152 |
153 |
--------------------------------------------------------------------------------
/tests/test_summary.R:
--------------------------------------------------------------------------------
1 | # test_summary.R
2 |
3 | # WRE says "using if(requireNamespace("pkgname")) is preferred, if possible."
4 | # even in tests:
5 | assertError <- function(expr, ...)
6 | if(requireNamespace("tools")) tools::assertError(expr, ...) else invisible()
7 | assertWarning <- function(expr, ...)
8 | if(requireNamespace("tools")) tools::assertWarning(expr, ...) else invisible()
9 |
10 | # Kenward-Roger only available with pbkrtest and only then validated in R >= 3.3.3
11 | # (faulty results for R < 3.3.3 may be due to unstated dependencies in pbkrtest)
12 | has_pbkrtest <- requireNamespace("pbkrtest", quietly = TRUE) && getRversion() >= "3.3.3"
13 |
14 | library(lmerTest)
15 |
16 | data("sleepstudy", package="lme4")
17 | data("cake", package="lme4")
18 |
19 | # Fit basic model and compute summary:
20 | fm <- lmer(Reaction ~ Days + (1|Subject) + (0+Days|Subject), sleepstudy)
21 | (sfm <- summary(fm))
22 |
23 | ## Test class:
24 | stopifnot(all(
25 | class(sfm) == c("summary.lmerModLmerTest", "summary.merMod"),
26 | all(c("df", "Pr(>|t|)") %in% colnames(coef(sfm)))
27 | ))
28 | stopifnot(class(summary(fm, ddf="lme4")) == "summary.merMod")
29 |
30 | ## Test coefficient table names:
31 | mat <- coef(summary(fm))
32 | stopifnot(all( # colnames
33 | colnames(mat) == c("Estimate", "Std. Error", "df", "t value", "Pr(>|t|)")
34 | ))
35 | stopifnot(all( # rownames
36 | names(fixef(fm)) == rownames(mat)
37 | ))
38 |
39 | ## Test pass of 'correlation' argument to lme4:::summary.merMod:
40 | x <- capture.output(summary(fm))
41 | x_nocor <- capture.output(summary(fm, correlation=FALSE))
42 | txt <- "Correlation of Fixed Effects:"
43 | stopifnot(
44 | any(grep(txt, x)),
45 | !any(grepl(txt, x_nocor))
46 | )
47 |
48 | # Test warning with unrecognized arguments (caught by lme4:::summary.merMod):
49 | assertWarning(summary(fm, false_arg=FALSE))
50 |
51 | ## Test pass of extra arguments to lme4:::print.summary.merMod:
52 | x <- capture.output(print(summary(fm), signif.stars=TRUE))
53 | x_nocor <- capture.output(print(summary(fm), signif.stars=FALSE))
54 | txt <- "Signif. codes:"
55 | stopifnot(
56 | any(grep(txt, x)),
57 | !any(grepl(txt, x_nocor))
58 | )
59 |
60 | ####### ddf argument:
61 | (an1 <- summary(fm)) # Also testing print method.
62 | (an2 <- summary(fm, ddf="Satterthwaite"))
63 | stopifnot(isTRUE(
64 | all.equal(an1, an2)
65 | ))
66 | (an3 <- summary(fm, ddf="Sat")) ## Abbreviated argument
67 | stopifnot(isTRUE(
68 | all.equal(an1, an3)
69 | ))
70 | (summary(fm, ddf="lme4"))
71 | if(has_pbkrtest) {
72 | (summary(fm, ddf="Kenward-Roger"))
73 | assertError(summary(fm, ddf="KR")) ## Error on incorrect arg.
74 | }
75 |
76 | ## lme4 method:
77 | an1 <- summary(fm, ddf="lme4")
78 | an2 <- summary(as(fm, "lmerMod"))
79 | stopifnot(isTRUE(
80 | all.equal(an1, an2)
81 | ))
82 |
83 |
84 | # Test printed output
85 | # - Satterthwaite
86 | x <- capture.output(sfm) # equal to output of 'print(sfm)'
87 | txt <- c("lmerModLmerTest", "t-tests use Satterthwaite's method",
88 | "df", "t value", "Pr(>|t|)")
89 | stopifnot(all(
90 | sapply(txt, function(text) any(grepl(text, x)))
91 | ))
92 |
93 | # Test printed output
94 | # - KR
95 | if(has_pbkrtest) {
96 | (sfm <- summary(fm, ddf="Kenward-Roger"))
97 | x <- capture.output(sfm)
98 | txt <- c("lmerModLmerTest", "t-tests use Kenward-Roger's method",
99 | "df", "t value", "Pr(>|t|)")
100 | stopifnot(all(
101 | sapply(txt, function(text) any(grepl(text, x)))
102 | ))
103 | }
104 |
105 | ####################################
106 | ## Test 'boundary' fixef structures:
107 | ####################################
108 |
109 | # Example with no fixef:
110 | m <- lmer(Reaction ~ -1 + (Days | Subject), sleepstudy)
111 | # m <- lmer(Reaction ~ 0 + (Days | Subject), sleepstudy) # alternative
112 | stopifnot(length(fixef(m)) == 0L)
113 | stopifnot(
114 | nrow(coef(summary(m))) == 0L,
115 | nrow(coef(summary(m, ddf="lme4"))) == 0L
116 | )
117 | if(has_pbkrtest){
118 | stopifnot(nrow(coef(summary(m, ddf="Kenward-Roger"))) == 0L)
119 | }
120 |
121 | # Example with intercept only:
122 | m <- lmer(Reaction ~ (Days | Subject), sleepstudy)
123 | # m <- lmer(Reaction ~ 1 + (Days | Subject), sleepstudy) # alternative
124 | stopifnot(length(fixef(m)) == 1L,
125 | names(fixef(m)) == "(Intercept)")
126 | stopifnot(
127 | nrow(coef(summary(m))) == 1L,
128 | nrow(coef(summary(m, ddf="lme4"))) == 1L
129 | )
130 | if(has_pbkrtest){
131 | stopifnot(nrow(coef(summary(m, ddf="Kenward-Roger"))) == 1L)
132 | }
133 |
134 | # Example with >1 fixef without intercept:
135 | m <- lmer(Reaction ~ Days - 1 + I(Days^2) + (Days | Subject), sleepstudy)
136 | stopifnot(length(fixef(m)) == 2L,
137 | names(fixef(m)) == c("Days", "I(Days^2)"))
138 | stopifnot(
139 | nrow(coef(summary(m))) == 2L,
140 | nrow(coef(summary(m, ddf="lme4"))) == 2L
141 | )
142 | if(has_pbkrtest){
143 | stopifnot(nrow(coef(summary(m, ddf="Kenward-Roger"))) == 2L)
144 | }
145 |
146 |
--------------------------------------------------------------------------------
/tests/test_zerovar.R:
--------------------------------------------------------------------------------
1 | # test_zerovar.R
2 |
3 | library(lmerTest)
4 | data("sleepstudy", package="lme4")
5 |
6 | # Baseline fit:
7 | m0 <- lmer(Reaction ~ Days + (Days | Subject), sleepstudy,
8 | control=lmerControl(optimizer="bobyqa"))
9 | ## default optimizer does not converge proporly
10 | m0
11 | (an0 <- anova(m0))
12 |
13 | # Make a fit with a zero variance estimate:
14 | n <- nrow(sleepstudy)
15 | g <- factor(rep(1:2, c(n - 10, 10)))
16 | m <- lmer(Reaction ~ Days + (Days | Subject) + (1|g), sleepstudy,
17 | control=lmerControl(optimizer="bobyqa"))
18 | m
19 | (an <- anova(m))
20 |
21 | # check that fit has a zero variance
22 | vc <- as.data.frame(VarCorr(m))
23 | stopifnot(isTRUE(
24 | all.equal(0, vc[vc$grp == "g", "sdcor"], tolerance=1e-4)
25 | ))
26 | # The hessian/vcov is actually positive definite:
27 | stopifnot(isTRUE(
28 | all(eigen(m@vcov_varpar, only.values = TRUE)$values > 0)
29 | ))
30 |
31 | # Check that ANOVA tables are the same:
32 | stopifnot(isTRUE(
33 | all.equal(an0[, 1:5], an[, 1:5], tolerance=1e-4)
34 | ))
35 |
36 | stopifnot(isTRUE( # Equality of summary tables
37 | all.equal(coef(summary(m0)), coef(summary(m)), tolerance=1e-4)
38 | ))
39 | stopifnot(isTRUE( # Equality of lme4-anova tables
40 | all.equal(anova(m0, ddf="lme4"), anova(m, ddf="lme4"), tolerance=1e-4)
41 | ))
42 |
43 |
--------------------------------------------------------------------------------
/tests/zlmerTest_zeroDenom.R:
--------------------------------------------------------------------------------
1 | library(lmerTest)
2 |
3 | # Read in data set
4 | load(system.file("testdata","potdata.RData", package="lmerTest"))
5 |
6 | # Mixed model
7 | lmerout <- lmer(biomass ~ CO2*nutrients + (1|chamber),data=potdata)
8 | summary(lmerout)
9 |
10 | an.sat <- anova(lmerout)
11 | anova(lmerout, ddf="lme4")
12 | TOL <- 1e-5
13 | stopifnot(isTRUE(all.equal(
14 | an.sat[,"DenDF"], c(2, 10, 10), tolerance=TOL
15 | )))
16 |
17 | stopifnot(isTRUE(
18 | all.equal(an.sat[,"Pr(>F)"], c(0.0224955602, 1e-11, 0.020905569), tolerance=TOL)
19 | ))
20 |
21 | # if(require(pbkrtest))
22 | # an.kr <- anova(lmerout, ddf="Kenward-Roger")
23 | #
24 | # TOL <- 1e-7
25 | # stopifnot(all.equal(an.kr[,"Pr(>F)"], c(0.0224955602, 1e-11, 0.020905569) ,
26 | # tol=TOL),
27 | # all.equal(an.kr[,"DenDF"],
28 | # c(2, 10, 10) , tol=TOL),
29 | # TRUE)
30 |
--------------------------------------------------------------------------------