Skip to content

Commit d66e077

Browse files
committed
Adding unit tests for missing values
1 parent ae6250b commit d66e077

File tree

3 files changed

+205
-2
lines changed

3 files changed

+205
-2
lines changed

R/utils_calculate.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ wrowmean <- function(x, ngroups = 1L, w = NULL) {
8282
}
8383
list(
8484
X = X[!X_dup, , drop = FALSE],
85-
w = c(rowsum(w, group = x_not_v, reorder = FALSE))
85+
w = c(rowsum(w, group = x_not_v, reorder = FALSE)) # warning if missing in x_not_v
8686
)
8787
}
8888

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
x <- c(NA, 1:98, NA)
2+
y <- c(rep(c("A", "B"), each = 48), c(NA, NA, NA, NA))
3+
xy <- data.frame(x = x, y = y)
4+
5+
test_that("univariate_grid() can deal with missings", {
6+
expect_true(
7+
!anyNA(univariate_grid(x, grid_size = 3, strategy = "uniform", na.rm = TRUE))
8+
)
9+
expect_true(
10+
!anyNA(univariate_grid(x, grid_size = 3, strategy = "quantile", na.rm = TRUE))
11+
)
12+
expect_true(
13+
anyNA(univariate_grid(x, grid_size = 3, strategy = "uniform", na.rm = FALSE))
14+
)
15+
expect_true(
16+
anyNA(univariate_grid(x, grid_size = 3, strategy = "quantile", na.rm = FALSE))
17+
)
18+
expect_false(
19+
anyNA(univariate_grid(na.omit(x), grid_size = 3, strategy = "uniform", na.rm = FALSE))
20+
)
21+
expect_false(
22+
anyNA(univariate_grid(na.omit(x), grid_size = 3, strategy = "quantile", na.rm = FALSE))
23+
)
24+
25+
expect_true(!anyNA(univariate_grid(y, na.rm = TRUE)))
26+
expect_true(anyNA(univariate_grid(y, na.rm = FALSE)))
27+
expect_false(anyNA(univariate_grid(na.omit(y), na.rm = FALSE)))
28+
})
29+
30+
test_that("multivariate_grid() can deal with missings", {
31+
expect_true(
32+
!anyNA(multivariate_grid(xy, grid_size = 6, strategy = "uniform", na.rm = TRUE))
33+
)
34+
expect_false(
35+
!anyNA(multivariate_grid(xy, grid_size = 6, strategy = "uniform", na.rm = FALSE))
36+
)
37+
expect_false(
38+
anyNA(multivariate_grid(na.omit(xy), grid_size = 6, strategy = "uniform", na.rm = FALSE))
39+
)
40+
})
41+
42+
# Univariate model
43+
X <- data.frame(x1 = 1:6, x2 = c(NA, 1, 2, 1, 1, 3), x3 = factor(c("A", NA, NA, "B", "A", "A")))
44+
y <- 1:6
45+
pf <- function(fit, x) x$x1
46+
fit <- "a model"
47+
48+
test_that("average_loss() works without BY", {
49+
expect_equal(drop(average_loss(fit, X = X, y = y, pred_fun = pf)$M), 0)
50+
})
51+
52+
test_that("average_loss() works with BY", {
53+
expect_warning(
54+
expect_warning(r <- average_loss(fit, X = X, y = y, pred_fun = pf, BY = "x3"))
55+
)
56+
expect_equal(unname(drop(r$M)), c(0, 0, 0))
57+
expect_s3_class(plot(r), "ggplot")
58+
})
59+
60+
test_that("perm_importance() works", {
61+
set.seed(1L)
62+
expect_no_error(r <- perm_importance(fit, X = X, y = y, pred_fun = pf))
63+
expect_true(r$M[1L] > 0 && all(r$M[2:3] == 0))
64+
})
65+
66+
test_that("ice() works when non-v variable contains missing", {
67+
set.seed(1L)
68+
expect_no_error(r <- ice(fit, v = "x1", X = X, pred_fun = pf))
69+
expect_equal(r$data$x1, r$data$y)
70+
})
71+
72+
test_that("ice() works when v contains missing", {
73+
expect_no_error(r1 <- ice(fit, v = "x2", X = X, pred_fun = pf))
74+
expect_true(!anyNA(r1$data$x2))
75+
76+
expect_no_error(r2 <- ice(fit, v = "x2", X = X, pred_fun = pf, na.rm = FALSE))
77+
expect_true(anyNA(r2$data$x2))
78+
79+
expect_equal(r1$data[1:3, ], r2$data[1:3, ])
80+
expect_s3_class(plot(r2, alpha = 1), "ggplot")
81+
})
82+
83+
test_that("ice() works when v contains missing (multivariate)", {
84+
v <- c("x2", "x3")
85+
86+
expect_no_error(r1 <- ice(fit, v = v, X = X, pred_fun = pf))
87+
expect_true(!anyNA(r1$data$x2))
88+
89+
expect_no_error(r2 <- ice(fit, v = v, X = X, pred_fun = pf, na.rm = FALSE))
90+
expect_true(anyNA(r2$data$x2))
91+
})
92+
93+
test_that("ice() works with missing value in BY", {
94+
expect_true(anyNA(ice(fit, v = "x1", X = X, pred_fun = pf, BY = "x3")$data$x3))
95+
r <- ice(fit, v = "x2", X = X, pred_fun = pf, BY = "x3")
96+
expect_true(anyNA(r$data$x3))
97+
expect_s3_class(plot(r), "ggplot")
98+
})
99+
100+
test_that("partial_dep() works when non-v variable contains missing", {
101+
expect_no_error(r <- partial_dep(fit, v = "x1", X = X, pred_fun = pf))
102+
expect_equal(r$data$x1, r$data$y)
103+
})
104+
105+
test_that("partial_dep() works when v contains missing", {
106+
expect_no_error(r1 <- partial_dep(fit, v = "x2", X = X, pred_fun = pf, grid_size = 2))
107+
expect_true(!anyNA(r1$data$x2))
108+
109+
expect_no_error(
110+
r2 <- partial_dep(fit, v = "x2", X = X, pred_fun = pf, na.rm = FALSE, grid_size = 2)
111+
)
112+
expect_true(anyNA(r2$data$x2))
113+
expect_equal(r1$data, r2$data[1:2, ])
114+
expect_s3_class(plot(r2), "ggplot")
115+
})
116+
117+
test_that("partial_dep() works when v contains missing (multi)", {
118+
v <- c("x2", "x3")
119+
expect_no_error(r1 <- partial_dep(fit, v = v, X = X, pred_fun = pf))
120+
expect_true(!anyNA(r1$data$x2))
121+
122+
expect_no_error(
123+
r2 <- partial_dep(fit, v = v, X = X, pred_fun = pf, na.rm = FALSE)
124+
)
125+
expect_true(anyNA(r2$data$x2))
126+
expect_s3_class(plot(r2), "ggplot")
127+
})
128+
129+
test_that("partial_dep() works when BY variable contains missing", {
130+
expect_no_error(
131+
r <- partial_dep(fit, v = "x2", X = X, pred_fun = pf, BY = "x3", na.rm = FALSE)
132+
)
133+
expect_true(anyNA(r$data$x3))
134+
expect_s3_class(plot(r), "ggplot")
135+
})
136+
137+
pfi <- function(fit, x) ifelse(is.na(x$x1 * x$x2), 1, x$x1 * x$x2)
138+
139+
test_that("hstats() does not give an error with missing", {
140+
expect_warning(
141+
expect_warning(
142+
expect_warning(
143+
expect_no_error(
144+
r <- hstats(fit, X = X, pred_fun = pfi, verbose = FALSE)
145+
)
146+
)
147+
)
148+
)
149+
expect_true(drop(r$h2$num) > 0)
150+
expect_equal(rownames(h2_pairwise(r, zero = FALSE)), "x1:x2")
151+
})
152+
153+
# Some checks on pd_raw()
154+
155+
test_that(".compress_grid() works with missing values in grid", {
156+
g <- c(2, 2, NA, 1, NA)
157+
gg <- .compress_grid(g)
158+
expect_equal(gg$grid[gg$reindex], g)
159+
160+
g <- cbind(c(2, 2, NA, 1, NA), c(NA, NA, 3, 4, 4))
161+
gg <- .compress_grid(g)
162+
expect_equal(gg$grid[gg$reindex, , drop = FALSE], g)
163+
164+
g <- data.frame(g)
165+
gg <- .compress_grid(g)
166+
res <- gg$grid[gg$reindex, , drop = FALSE]
167+
rownames(res) <- 1:5
168+
expect_equal(res, g)
169+
})
170+
171+
test_that(".compress_X() works with missing values", {
172+
# Note that b is not used after compression
173+
174+
# data.frame
175+
X <- data.frame(a = c(NA, NA, NA, 1, 1), b = 1:5)
176+
out_df <- data.frame(a = c(NA, 1), b = c(1, 4), row.names = c(1L, 4L))
177+
expect_warning(out <- .compress_X(X, v = "b"))
178+
expect_equal(out$X, out_df)
179+
expect_equal(out$w, c(3, 2))
180+
181+
# Matrix
182+
X <- cbind(a = c(NA, NA, NA, 1, 1), b = 1:5)
183+
out_m <- cbind(a = c(NA, 1), b = c(1, 4))
184+
expect_warning(out <- .compress_X(X, v = "b"))
185+
expect_equal(out$X, out_m)
186+
expect_equal(out$w, c(3, 2))
187+
})
188+
189+
test_that("pd_raw() works with missings (all compressions on)", {
190+
X <- cbind(a = c(NA, NA, NA, 1, 1), b = 1:5)
191+
out <- pd_raw(1, v = "a", X = X, pred_fun = function(m, x) x[, "b"], grid = c(NA, 1))
192+
expect_equal(drop(out), rep(mean(X[, "b"]), times = 2L))
193+
194+
expect_warning(
195+
out <- pd_raw(1, v = "b", X = X, pred_fun = function(m, x) x[, "b"], grid = 1:5)
196+
)
197+
expect_equal(drop(out), 1:5)
198+
})
199+
200+
# Other utils
201+
202+
test_that("qcut() works with missings", {
203+
expect_true(is.na(hstats:::qcut(c(NA, 1:9), m = 2)[1L]))
204+
})

tests/testthat/test_utils.R

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ test_that(".compress_X() works for matrices", {
8989
expect_equal(out_w2$w, c(9, 6))
9090
})
9191

92-
9392
test_that(".compress_X() leaves X unchanged if unique", {
9493
X <- data.frame(a = 1:5, b = rep(1, times = 5))
9594
out <- .compress_X(X, v = "b")

0 commit comments

Comments
 (0)