Switch to unified view

a b/tests/testthat/test-projection.R
1
test_that("projsel for a model with no penalized predictors",
2
{
3
    SW({
4
        sel.base.00 <- projsel(hs.base, max.iters=0)
5
        sel.base.02 <- projsel(hs.base, max.iters=0, start.from="X2")
6
        sel.base.1 <- projsel(hs.base)
7
        sel.base.2 <- projsel(hs.base, start.from="X2")
8
    })
9
10
    expect_equal(nrow(sel.base.00),
11
                 1)
12
    expect_true(is.na(sel.base.00$rel.kl))
13
    expect_equal(sel.base.00$rel.kl.null,
14
                 0)
15
16
    expect_equal(nrow(sel.base.02),
17
                 2)
18
    expect_equal(sel.base.02$rel.kl[2],
19
                 0)
20
    expect_equal(sel.base.02$rel.kl.null[1],
21
                 0)
22
    expect_equal(sel.base.02$rel.kl.null[2],
23
                 0.38193515, tolerance=tol)
24
25
    expect_equal(nrow(sel.base.1),
26
                 length(hs.base$betas$unpenalized))
27
    expect_equal(attr(sel.base.1, "start.from"),
28
                 character(0))
29
30
    expect_equal(nrow(sel.base.2),
31
                 length(hs.base$betas$unpenalized))
32
    expect_equal(sel.base.2$var[2],
33
                 "Initial submodel")
34
    expect_equal(attr(sel.base.2, "start.from"),
35
                 "X2")
36
})
37
38
test_that("projsel for gaussian family",
39
{
40
    SW({
41
        sel.gauss <- projsel(hs.gauss, out.csv="out.csv")
42
    })
43
44
    expect_s3_class(sel.gauss,
45
                    "projsel")
46
    expect_equal(colnames(sel.gauss),
47
                 c("var", "kl", "rel.kl.null", "rel.kl", "elpd", "delta.elpd"))
48
    expect_equal(nrow(sel.gauss),
49
                 length(pen) + 2)
50
    expect_equal(attr(sel.gauss, "start.from"),
51
                 hs.gauss$model.terms$unpenalized)
52
    expect_equal(sel.gauss$var[1:2],
53
                 c("Intercept only", "Initial submodel"))
54
    expect_equal(sel.gauss$var[-c(1:2)],
55
                 paste0("X", c(9, 4, 8, 7, 5, 6, 10)))
56
    expect_equal(sel.gauss$kl[2],
57
                 0.02948656, tolerance=tol)
58
    expect_equal(tail(sel.gauss$kl, n=1),
59
                 0)
60
    expect_equal(sel.gauss$rel.kl.null[1],
61
                 0)
62
    expect_equal(tail(sel.gauss$rel.kl.null, n=1),
63
                 1)
64
    expect_true(is.na(sel.gauss$rel.kl[1]))
65
    expect_equal(sel.gauss$rel.kl[2],
66
                 0)
67
    expect_equal(tail(sel.gauss$rel.kl, n=1),
68
                 1)
69
    expect_equal(sel.gauss$elpd[2],
70
                 -111.370949, tolerance=tol)
71
    expect_equal(tail(sel.gauss$elpd, n=1),
72
                 -109.695740, tolerance=tol)
73
    expect_equal(sel.gauss$delta.elpd[2],
74
                 -1.67520810, tolerance=tol)
75
    expect_true(all(diff(sel.gauss$kl) < 0))
76
    expect_true(file.exists("out.csv"))
77
    unlink("out.csv")
78
79
    expect_s3_class(plot(sel.gauss, from.covariates=FALSE, max.points=3),
80
                    "ggplot")
81
    expect_silent(print(plot(sel.gauss, title="Test", max.labels=3)))
82
    unlink("Rplots.pdf")
83
})
84
85
test_that("projsel for binomial family",
86
{
87
    num.sel <- 4
88
    SW({
89
        sel.binom <- projsel(hs.binom, max.iters=num.sel)
90
    })
91
92
    expect_equal(nrow(sel.binom),
93
                 num.sel + 2)
94
    expect_equal(sel.binom$var[-c(1:2)],
95
                 paste0("X", c(6, 9, 5, 8)))
96
    expect_equal(sel.binom$kl[2],
97
                 0.03245156, tolerance=tol)
98
    expect_equal(tail(sel.binom$kl, n=1),
99
                 0.00478297, tolerance=tol)
100
    expect_equal(sel.binom$rel.kl.null[1],
101
                 0)
102
    expect_true(is.na(sel.binom$rel.kl[1]))
103
    expect_lt(tail(sel.binom$rel.kl, n=1),
104
              1)
105
    expect_lt(tail(sel.binom$rel.kl.null, n=1),
106
              1)
107
    expect_equal(sel.binom$elpd[2],
108
                 -35.3793754, tolerance=tol)
109
    expect_equal(tail(sel.binom$elpd, n=1),
110
                 -34.0411588, tolerance=tol)
111
    expect_equal(sel.binom$delta.elpd[2],
112
                 -1.39197661, tolerance=tol)
113
    expect_true(all(diff(sel.binom$kl) < 0))
114
})
115
116
test_that("projsel for a model with interaction terms",
117
{
118
    SW({
119
        sel.inter <- projsel(hs.inter, start.from="X1:X3")
120
    })
121
    expect_equal(attr(sel.inter, "start.from"),
122
                 c("X1", "X3", "X1:X3"))
123
})
124
125
test_that("projsel from the intercept-only model",
126
{
127
    SW({
128
        sel.gauss.1 <- projsel(hs.gauss, start.from=character(0))
129
        sel.gauss.2 <- projsel(hs.gauss, start.from="X2")
130
    })
131
132
    expect_equal(sel.gauss.1$var[1:2],
133
                 c("Intercept only", "X2"))
134
    expect_equal(sel.gauss.2$var[1:2],
135
                 c("Intercept only", "Initial submodel"))
136
    expect_equivalent(sel.gauss.1[-2, ],
137
                      sel.gauss.2[-2, ])
138
    expect_equal(nrow(sel.gauss.1),
139
                 length(c(hs.gauss$betas$unpenalized, hs.gauss$betas$penalized)))
140
    expect_equal(attr(sel.gauss.1, "start.from"),
141
                 character(0))
142
    expect_equal(attr(sel.gauss.2, "start.from"),
143
                 "X2")
144
})
145
146
test_that("projsel from a non-default starting submodel",
147
{
148
    SW({
149
        sel.gauss <- projsel(hs.gauss, start.from="X1")
150
    })
151
152
    expect_equal(nrow(sel.gauss),
153
                 length(c(grep("X1", names(hs.gauss$beta$unpenalized), inv=TRUE),
154
                          hs.gauss$betas$penalized)) + 1)
155
})
156
157
test_that("projsel from a submodel that includes all variables",
158
{
159
    SW({
160
        sel.gauss <- projsel(hs.gauss, start.from=paste0("X", 1:P))
161
    })
162
163
    expect_equal(sel.gauss$var,
164
                 c("Intercept only", "Initial submodel"))
165
    expect_equal(sel.gauss$rel.kl.null,
166
                 c(0, 1))
167
    expect_equal(sel.gauss$rel.kl,
168
                 c(NA, 1))
169
    expect_equal(sel.gauss$delta.elpd[2],
170
                 0)
171
    expect_equal(attr(sel.gauss, "row.names"),
172
                 1:2)
173
    expect_equal(attr(sel.gauss, "start.from"),
174
                 paste0("X", 1:P))
175
})
176
177
test_that("projsel for a model with few observations",
178
{
179
    SW({
180
        hs.small <- hsstan(df[1:5, ], y.gauss ~ X2 + X3, pen,
181
                           iter=iters,  chains=chains, refresh=0)
182
        expect_message(sel <- projsel(hs.small),
183
                      "Fully saturated model reached")
184
    })
185
    expect_equal(tail(sel$kl, 1),
186
                 0)
187
})
188
189
test_that("projsel for a cross-validated object",
190
{
191
    SW({
192
        sel.gauss <- projsel(cv.gauss$fits[[1]])
193
    })
194
195
    expect_equal(tail(sel.gauss$elpd, n=1),
196
                 sum(colMeans(log_lik(cv.gauss$fits[[1]],
197
                                      newdata=df[folds == 2, ]))))
198
})
199
200
test_that("projsel with invalid inputs",
201
{
202
    expect_error(projsel(hs.gauss, max.iters=-1),
203
                 "must be a non-negative integer")
204
    expect_error(projsel(hs.gauss, max.iters=2.3),
205
                 "must be a non-negative integer")
206
    expect_error(projsel(hs.gauss, max.iters=iris),
207
                 "must be a non-negative integer")
208
})