You can use purrr::map_depth
to sort the nested lists, then check the lists with setdiff
. If the length when you call setdiff
is 0, the lists contain the same elements. The tricky thing is that setdiff
will yield different results based on the order of its arguments, so you end up calling it twice, once from each direction. This is similar to the double checking done in testthat::expect_setequal
.
For simplicity, I'm wrapping this in a function. You could instead do the same thing with a combination of all
and %in%
, but this seemed for compact.
a1 <- list("PL+", "PW-", "PL+", "PW-", c("PL+", "PW-"))
b1 <- list("PL+", c("PW-", "PL+"), "PL+", "PW-", "PW-")
nested_equal <- function(l1, l2) {
left_diff <- setdiff(
purrr::map_depth(l1, 1, sort),
purrr::map_depth(l2, 1, sort)
)
right_diff <- setdiff(
purrr::map_depth(l2, 1, sort),
purrr::map_depth(l1, 1, sort)
)
(length(left_diff) == 0) & (length(right_diff) == 0)
}
nested_equal(a1, b1)
#> [1] TRUE
A few test cases with different elements:
a2 <- list("PL+", "PW-", "PL+", "PW-", c("PL+", "PW-"), "A")
b2 <- list("PL+", c("PW-", "PL+"), "PL+", "PW-", "PW-")
nested_equal(a2, b2)
#> [1] FALSE
a3 <- list("PL+", "PW-", "PL+", "PW-", c("PL+", "PW-"))
b3 <- list("PL+", c("PW-", "PL+", "X"), "PL+", "PW-", "PW-", "B")
nested_equal(a3, b3)
#> [1] FALSE
To fit in with testthat
tests, you could test against a true or false value returned by nested_equal
in expect_equal
, expect_true
, expect_false
.