# ------------------------------------------------------------------------------
# Setup
ex_eq <- c(0L, 1L, 2L, 2L, 3L)
ex_no_eq <- c(1L, 1L, 2L, 2L, 3L)
real_labs <- c("low", "med", "high")
factor_no_eq <- factor(ex_no_eq, labels = real_labs)
manual_creation_eq <- new_class_pred(ex_eq, labels = real_labs)
manual_creation_no_eq <- new_class_pred(ex_no_eq, labels = real_labs)
masked_high <- class_pred(factor_no_eq, which = 5)
# ------------------------------------------------------------------------------
# Testing
test_that("can create from integers", {
expect_equal(new_class_pred(ex_eq, real_labs), manual_creation_eq)
expect_equal(new_class_pred(ex_no_eq, real_labs), manual_creation_no_eq)
expect_error(new_class_pred("not-an-integer", "lab"))
expect_error(new_class_pred(1L, 0))
})
test_that("can create from helper", {
expect_equal(class_pred(factor_no_eq, which = 1), manual_creation_eq)
expect_equal(class_pred(factor_no_eq), manual_creation_no_eq)
expect_error(class_pred(1L))
})
test_that("can detect class_pred", {
expect_equal(is_class_pred(manual_creation_eq), TRUE)
})
test_that("equivocal label is not allowed as level", {
expect_error(class_pred(factor("[EQ]")))
# changing the label means we can use "EQ"
expect_error(class_pred(factor("[EQ]"), equivocal = "hi"), NA)
})
test_that("format preserves equivocal values", {
expect_equal(
format(manual_creation_eq),
c("[EQ]", "low", "med", "med", "high")
)
})
test_that("levels() does not return the equivocal label", {
expect_equal(levels(manual_creation_eq), c("low", "med", "high"))
})
test_that("class_pred masking a level retains the level", {
expect_equal(
levels(masked_high),
c("low", "med", "high")
)
})
test_that("coercing class_pred to factor retains all levels", {
expect_equal(
levels(masked_high),
levels(as.factor(masked_high))
)
})
test_that("class_pred can be coerced to ordered factor", {
expect_s3_class(as.ordered(manual_creation_eq), "ordered")
})
test_that("casting class_pred to class_pred", {
cp1 <- class_pred(factor(c("a", "b", "b", "c")), which = 2)
cp2 <- class_pred(factor(c("a", "b", "b", "b")), which = 3)
cp3 <- class_pred(factor(c("a", "b", "b", "c")), which = 2, equivocal = "eq")
cp4 <- class_pred(factor(c("a", "b", "b", "c"), ordered = TRUE), which = 2)
# lossy cast, no c level in cp2
expect_error(vec_cast(cp1, cp2), class = "vctrs_error_cast_lossy")
# can suppress lossy cast
expect_equal(
allow_lossy_cast(vec_cast(cp1, cp2)),
class_pred(factor(c("a", "b", "b", NA)), which = 2L)
)
# casting to new class_pred preserves new eq label
expect_equal(get_equivocal_label(vec_cast(cp1, cp3)), "eq")
expect_true(is_ordered(vec_cast(cp1, cp4)))
})
test_that("casting class_pred to factor", {
cp1 <- class_pred(factor(c("a", "b", "b", "c")))
cp2 <- class_pred(factor(c("a", "b", "b", "c")), which = 2)
cp3 <- class_pred(factor(c(NA, "a", "b", "c")), which = 3)
fc1 <- factor(levels = c("a", "b"))
fc2 <- factor(levels = c("a", "b", "c"))
fc3 <- factor(levels = c("a", "b", "c"), ordered = TRUE)
# lossy cast, no c level in fc1
expect_error(vec_cast(cp1, fc1), class = "vctrs_error_cast_lossy")
# can allow lossy cast to succeed
expect_equal(
allow_lossy_cast(vec_cast(cp1, fc1)),
factor(c("a", "b", "b", NA))
)
# clean conversion to factor
expect_equal(vec_cast(cp1, fc2), factor(c("a", "b", "b", "c")))
# convert to factor, eq becomes NA
expect_equal(vec_cast(cp2, fc2), factor(c("a", NA, "b", "c")))
# converting to ordered factor maintains orderedness
expect_equal(vec_cast(cp1, fc3), ordered(c("a", "b", "b", "c")))
# convert to factor with NA already present is not lossy
expect_warning(vec_cast(cp3, factor()), NA)
# special test for when the factor you are casting to has different
# levels and they are in an odd order compared to what the class_pred had
# (poor is between good and great here)
cp_special <- class_pred(factor(c("good", "great")))
fc_special <- factor(c("good", "poor", "great"), c("good", "poor", "great"))
res_special <- factor(c("good", "great"), levels = c("good", "poor", "great"))
expect_equal(vec_cast(cp_special, fc_special), res_special)
})
test_that("casting factor to class_pred", {
fc1 <- factor(c("a", "b", "b", "b"))
fc2 <- factor(c("a", "b", "b", "c"))
fc3 <- factor(c(NA, "a", "b", "c"))
cp1 <- class_pred(factor(levels = c("a", "b")))
cp2 <- class_pred(factor(levels = c("a", "b", "c")))
cp3 <- class_pred(factor(levels = c("a", "b", "c")), equivocal = "eq")
cp4 <- class_pred(factor(levels = c("a", "b", "c"), ordered = TRUE))
# lossy cast, no c level in cp1
expect_error(vec_cast(fc2, cp1), class = "vctrs_error_cast_lossy")
# can allow lossy cast to succeed
expect_equal(
allow_lossy_cast(vec_cast(fc2, cp1)),
class_pred(factor(c("a", "b", "b", NA)))
)
# clean conversion to class_pred
expect_equal(vec_cast(fc1, cp1), class_pred(factor(c("a", "b", "b", "b"))))
# converting to ordered class_pred maintains orderedness
expect_equal(vec_cast(fc2, cp4), class_pred(factor(c("a", "b", "b", "c"), ordered = TRUE)))
# convert to class_pred with NA already present is not lossy
expect_warning(vec_cast(fc3, class_pred()), NA)
# convert ordered factor to class_pred
# order-ness depends on class_pred type, not order factor
or1 <- as.ordered(fc1)
expect_equal(vec_cast(or1, class_pred()), class_pred(factor(c("a", "b", "b", "b"))))
})
test_that("casting character to class_pred", {
chr1 <- c("a", "b", "b", "c")
cp1 <- class_pred(factor(c("a", "b", "b", "c")))
cp2 <- class_pred(factor(c("a", "b", "b", "b")))
cp3 <- class_pred(factor(c("a", "b", "b", "c"), ordered = TRUE))
cp4 <- class_pred(factor(c("a", "b", "b", "c")), equivocal = "eq")
# lossy cast, no c level in chr1
expect_error(vec_cast(chr1, cp2), class = "vctrs_error_cast_lossy")
# can allow lossy cast to succeed
expect_equal(
allow_lossy_cast(vec_cast(chr1, cp2)),
class_pred(factor(c("a", "b", "b", NA)))
)
# equivocal label is maintained
expect_equal(get_equivocal_label(vec_cast(chr1, cp4)), "eq")
# clean conversion to class_pred
expect_equal(vec_cast(chr1, cp1), class_pred(factor(c("a", "b", "b", "c"))))
# converting to ordered class_pred maintains orderedness
expect_true(is_ordered_class_pred(vec_cast(chr1, cp3)))
})
test_that("slicing", {
# levels are kept
expect_equal(levels(manual_creation_eq[1]), real_labs)
# reportable rate updates
expect_equal(reportable_rate(manual_creation_eq[1]), 0)
expect_equal(reportable_rate(manual_creation_eq[1:2]), 0.5)
# extending past is an error
expect_snapshot(error = TRUE, {
manual_creation_eq[1:6]
})
})
test_that("unknown casts are handled correctly", {
# numeric -> class_pred = error
expect_error(vec_cast(numeric(), class_pred()))
# logical vec -> class pred = depends on if only NA or has TRUE/FALSE
expect_equal(vec_cast(NA, class_pred()), class_pred(factor(NA)))
expect_error(vec_cast(TRUE, class_pred()))
# NULL second = x, NULL first = NULL
expect_equal(vec_cast(NULL, class_pred()), NULL)
expect_equal(vec_cast(class_pred(), NULL), class_pred())
})
test_that("ptype2 checks are handled correctly", {
expect_error(vec_ptype2(manual_creation_eq, numeric()), class = "vctrs_error_incompatible_type")
expect_equal(vec_ptype2(manual_creation_eq, vctrs::unspecified()), vec_ptype(manual_creation_eq))
expect_equal(vec_ptype2(character(), manual_creation_eq), character())
expect_equal(vec_ptype2(manual_creation_eq, character()), character())
})
test_that("combining class preds", {
cp1 <- new_class_pred(c(1L, 2L, 2L), c("low", "med"))
cp2 <- new_class_pred(c(1L, 2L, 2L), c("low", "med"), ordered = TRUE)
cp3 <- new_class_pred(c(1L, 2L, 2L), c("low", "med"), equivocal = "eq")
# joining with different levels is the union
expect_equal(levels(c(manual_creation_eq, cp1)), c("low", "med", "high"))
# joining with different levels is the union in the order given
# even if one is ordered
expect_equal(levels(c(manual_creation_eq, cp2)), c("low", "med", "high"))
expect_true(is_ordered_class_pred(c(manual_creation_eq, cp2)))
# joining with different equivocal labels uses the LHS label
expect_equal(get_equivocal_label(c(cp1, cp3)), "[EQ]")
expect_equal(get_equivocal_label(c(cp3, cp1)), "eq")
})
test_that("combining class pred with factor", {
cp1 <- class_pred(factor(c("good", "poor")), which = 2)
chr <- c("good", "great", NA)
fc1 <- factor(chr)
join1 <- class_pred(
factor(
c("good", "poor", "good", "great", NA),
levels = c("good", "poor", "great")
),
which = 2
)
join2 <- class_pred(
factor(
c("good", "great", NA, "good", "poor"),
levels = c("good", "great", "poor")
),
which = 5
)
join3 <- c(1, 2, NA, 1, 0)
# vec_c() joins are bidirectionally correct
expect_equal(vec_c(cp1, fc1), join1)
expect_equal(vec_c(fc1, cp1), join2)
# c() joins are correct if vctrs_vctr is first
expect_equal(c(cp1, fc1), join1)
# sadly this happens and cannot be overriden
expect_equal(c(fc1, cp1), join3)
})
test_that("common type: factor and class_pred", {
expect_s3_class(vec_ptype2(class_pred(), factor()), "class_pred")
expect_equal(
levels(
vec_ptype2(
class_pred(factor(levels = "a")),
factor(levels = "b")
)
),
c("a", "b")
)
expect_equal(
get_equivocal_label(
vec_ptype2(
class_pred(factor(levels = "a"), equivocal = "eq"),
factor(levels = "b")
)
),
"eq"
)
# reverse order
expect_s3_class(vec_ptype2(factor(), class_pred()), "class_pred")
expect_equal(
levels(
vec_ptype2(
factor(levels = "b"),
class_pred(factor(levels = "a"))
)
),
c("b", "a")
)
expect_equal(
get_equivocal_label(
vec_ptype2(
factor(levels = "b"),
class_pred(factor(levels = "a"), equivocal = "eq")
)
),
"eq"
)
})
test_that("smaller vctrs helpers", {
expect_equal(vec_ptype_abbr(manual_creation_eq), "clss_prd")
})
test_that("reportable rate", {
report_100 <- class_pred(factor(1))
report_0 <- class_pred()
report_50 <- class_pred(factor(c(1, 2)), 2)
report_667 <- class_pred(factor(c(1, 2, 3)), 2)
expect_output(cat_reportable(report_100), "Reportable: 100%")
expect_output(cat_reportable(report_0), "Reportable: 0%")
expect_output(cat_reportable(report_50), "Reportable: 50%")
expect_output(cat_reportable(report_667), "Reportable: 66.7%")
expect_error(reportable_rate(1), "No implementation")
})
test_that("constructor aborts on bad input", {
expect_error(class_pred(which = "hello"))
expect_error(class_pred(equivocal = 1))
expect_error(class_pred(which = 1), "The largest value of `which` can be 0.")
})
test_that("as_class_pred() works like the constructor", {
expect_equal(class_pred(factor_no_eq, 1), as_class_pred(factor_no_eq, 1))
expect_error(as_class_pred(which = "hello"))
expect_error(as_class_pred(1), "No implementation")
})
test_that("locate equivocal helpers", {
expect_equal(is_equivocal(manual_creation_eq), c(TRUE, rep(FALSE, 4)))
expect_error(is_equivocal("a"), "No implementation")
expect_equal(which_equivocal(manual_creation_eq), 1L)
expect_error(which_equivocal("a"), "No implementation")
expect_equal(any_equivocal(manual_creation_eq), TRUE)
expect_error(any_equivocal("a"), "No implementation")
})
test_that("class_pred printing", {
expect_output(
cat_class_pred(manual_creation_eq),
"\\[1\\] \\[EQ\\] low med med high"
)
expect_output(
cat_class_pred(class_pred()),
"class_pred\\(0\\)"
)
expect_output(cat_levels(class_pred()), "Levels:")
expect_output(cat_levels(manual_creation_eq), "Levels: low med high")
expect_output(
cat_levels(class_pred(as.ordered(factor_no_eq))),
"Levels: low < med < high"
)
# long levels
fctrs <- paste0("blaaaaaaaaaaaaaaaaaaaaaaaaa", c(1, 2, 3, 4))
cp <- class_pred(as.factor(fctrs))
expect_output(
cat_levels(cp),
"4 Levels: blaaaaaaaaaaaaaaaaaaaaaaaaa1 ... blaaaaaaaaaaaaaaaaaaaaaaaaa4"
)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.