Skip to content

Commit 6fbe27c

Browse files
authored
Fix behaviour of combine_vars() with more than one facet variable (#3302, fixes #2810)
2 parents 0f929a1 + 963be06 commit 6fbe27c

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

R/facet-.r

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ combine_vars <- function(data, env = emptyenv(), vars = NULL, drop = TRUE) {
563563
if (drop) {
564564
new <- unique_combs(new)
565565
}
566-
base <- rbind(base, df.grid(old, new))
566+
base <- unique(rbind(base, df.grid(old, new)))
567567
}
568568

569569
if (empty(base)) {

tests/testthat/test-facet-.r

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,103 @@ test_that("facet gives clear error if ", {
204204
)
205205
})
206206

207+
# Variable combinations ---------------------------------------------------
208+
209+
test_that("zero-length vars in combine_vars() generates zero combinations", {
210+
df <- data_frame(letter = c("a", "b"))
211+
expect_equal(nrow(combine_vars(list(df), vars = vars())), 0)
212+
expect_equal(ncol(combine_vars(list(df), vars = vars())), 0)
213+
})
214+
215+
test_that("at least one layer must contain all facet variables in combine_vars()", {
216+
df <- data_frame(letter = c("a", "b"))
217+
expect_silent(combine_vars(list(df), vars = vars(letter = letter)))
218+
expect_error(
219+
combine_vars(list(df), vars = vars(letter = number)),
220+
"At least one layer"
221+
)
222+
})
223+
224+
test_that("at least one combination must exist in combine_vars()", {
225+
df <- data_frame(letter = character(0))
226+
expect_error(
227+
combine_vars(list(df), vars = vars(letter = letter)),
228+
"Faceting variables must have at least one value"
229+
)
230+
})
231+
232+
test_that("combine_vars() generates the correct combinations", {
233+
df_one <- data_frame(
234+
letter = c("a", "b"),
235+
number = c(1, 2),
236+
boolean = c(TRUE, FALSE),
237+
factor = factor(c("level1", "level2"))
238+
)
239+
240+
df_all <- expand.grid(
241+
letter = c("a", "b"),
242+
number = c(1, 2),
243+
boolean = c(TRUE, FALSE),
244+
factor = factor(c("level1", "level2")),
245+
stringsAsFactors = FALSE
246+
)
247+
248+
vars_all <- vars(letter = letter, number = number, boolean = boolean, factor = factor)
249+
250+
expect_equivalent(
251+
combine_vars(list(df_one), vars = vars_all),
252+
df_one
253+
)
254+
255+
expect_equivalent(
256+
combine_vars(list(df_all), vars = vars_all),
257+
df_all
258+
)
259+
260+
# with drop = FALSE the rows are ordered in the opposite order
261+
# NAs are dropped with drop = FALSE (except for NA factor values);
262+
# NAs are kept with with drop = TRUE
263+
# drop keeps all combinations of data, regardless of the combinations in which
264+
# they appear in the data (in addition to keeping unused factor levels)
265+
expect_equivalent(
266+
combine_vars(list(df_one), vars = vars_all, drop = FALSE),
267+
df_all[order(df_all$letter, df_all$number, df_all$boolean, df_all$factor), ]
268+
)
269+
})
270+
271+
test_that("drop = FALSE in combine_vars() keeps unused factor levels", {
272+
df <- data_frame(x = factor("a", levels = c("a", "b")))
273+
expect_equivalent(
274+
combine_vars(list(df), vars = vars(x = x), drop = TRUE),
275+
data_frame(x = factor("a"))
276+
)
277+
expect_equivalent(
278+
combine_vars(list(df), vars = vars(x = x), drop = FALSE),
279+
data_frame(x = factor(c("a", "b")))
280+
)
281+
})
282+
283+
test_that("combine_vars() generates the correct combinations with multiple data frames", {
284+
df <- expand.grid(letter = c("a", "b"), number = c(1, 2), boolean = c(TRUE, FALSE))
285+
286+
vars <- vars(letter = letter, number = number)
287+
expect_identical(
288+
combine_vars(list(df), vars = vars),
289+
combine_vars(list(df, df), vars = vars)
290+
)
291+
expect_identical(
292+
combine_vars(list(df), vars = vars),
293+
combine_vars(list(df, df[character(0)]), vars = vars)
294+
)
295+
expect_identical(
296+
combine_vars(list(df), vars = vars),
297+
combine_vars(list(df, df["letter"]), vars = vars)
298+
)
299+
expect_identical(
300+
combine_vars(list(df), vars = vars),
301+
combine_vars(list(df, df[c("letter", "number")]), vars = vars)
302+
)
303+
})
207304

208305
# Visual tests ------------------------------------------------------------
209306

0 commit comments

Comments
 (0)