tests/testthat/test-count_n.R

test_that("count_n basic value counting works", {
  df <- tibble::tibble(
    a = c("a", "b", "b"),
    b = c("b", "c", "b"),
    c = c("c", "b", "b")
  )

  expect_equal(count_n(df, count = "b"), c(1, 2, 3))
  expect_equal(count_n(df, count = c("b", "c")), c(2, 3, 3))
})

test_that("count_n works with ignore_case = TRUE", {
  df <- tibble::tibble(x = c("A", "b", "B"), y = c("a", "B", "b"))
  expect_equal(count_n(df, count = "b", ignore_case = TRUE), c(0, 2, 2))
})

test_that("count_n handles strict comparison with allow_coercion = FALSE", {
  df <- tibble::tibble(x = c(1, 2, 2), y = c("2", 2, 3))
  expect_equal(count_n(df, count = 2, allow_coercion = FALSE), c(0, 1, 1))
})

test_that("count_n handles multiple values with allow_coercion = FALSE", {
  df <- tibble::tibble(x = c(1, 2, 2), y = c("2", 2, 3))

  # Same type (character)
  expect_equal(count_n(df, count = c("2", "3"), allow_coercion = FALSE), c(1, 1, 1))

  # Same type (numeric)
  expect_equal(count_n(df, count = c(1, 2), allow_coercion = FALSE), c(1, 1, 1))

})

test_that("count_n handles special = NA, NaN, Inf, -Inf", {
  df <- tibble::tibble(
    a = c(NA, 1, NaN, Inf, -Inf),
    b = c(NaN, Inf, NA, NA, -Inf),
    c = 1:5
  )

  expect_equal(count_n(df, special = "NA"), c(2, 0, 2, 1, 0))
  expect_equal(count_n(df, special = "NaN"), c(1, 0, 1, 0, 0))
  expect_equal(count_n(df, special = "Inf"), c(0, 1, 0, 1, 0))
  expect_equal(count_n(df, special = "-Inf"), c(0, 0, 0, 0, 2))
  expect_equal(count_n(df, special = c("NA", "NaN")), c(2, 0, 2, 1, 0))
  expect_equal(count_n(df, special = "all"), c(2, 1, 2, 2, 2))
})

test_that("count_n handles factor variables including ignore_case", {
  df <- tibble::tibble(
    x = factor(c("a", "b", "c")),        # levels: a, b, c
    y = factor(c("b", "B", "a"))         # levels: a, b, B
  )

  # Default coercion: character "b" matches in both x and y
  expect_equal(count_n(df, count = "b"), c(1, 1, 0))

  # Strict mode: character input fails (character ≠ factor)
  expect_equal(count_n(df, count = "b", allow_coercion = FALSE), c(0, 0, 0))

  # Strict mode: with factor value having matching levels (for x)
  expect_equal(count_n(df, count = factor("b", levels = levels(df$x)), allow_coercion = FALSE), c(0, 1, 0))

  # Using a value from the data (ensures type + levels)
  expect_equal(count_n(df, count = df$x[2], allow_coercion = FALSE), c(0, 1, 0))

  # Case-insensitive match: works for both x and y after conversion to character
  expect_equal(count_n(df, count = "b", ignore_case = TRUE), c(1, 2, 0))
  expect_equal(count_n(df, count = "B", ignore_case = TRUE), c(1, 2, 0))

  # Case-insensitive + strict: internally uses character comparison, not identical()
  expect_equal(count_n(df, count = "b", ignore_case = TRUE, allow_coercion = FALSE), c(1, 2, 0))
  expect_equal(count_n(df, count = factor("b", levels = levels(df$x)), ignore_case = TRUE, allow_coercion = FALSE), c(1, 2, 0))
})



test_that("count_n handles labelled variables from haven", {
  skip_if_not_installed("haven")

  df <- tibble::tibble(
    lab = haven::labelled(
      c(1, 2, 1, 2, NA),
      labels = c(No = 1, Yes = 2)
    ),
    other = c(2, 2, 1, 1, 2)
  )

  expect_equal(count_n(df, count = 2), c(1, 2, 0, 1, 1))
  expect_equal(count_n(df, count = 2, allow_coercion = FALSE), c(1, 1, 0, 0, 1))
})

test_that("count_n handles selection and exclusion", {
  df <- tibble::tibble(x1 = "a", x2 = "b", x3 = "b", skip = "b")
  expect_equal(count_n(df, count = "b", select = starts_with("x")), 2)
  expect_equal(count_n(df, count = "b", select = everything(), exclude = "skip"), 2)
})

test_that("count_n works with regex selection", {
  df <- tibble::tibble(a_1 = "a", a_2 = "b", b_1 = "b")
  expect_equal(count_n(df, count = "b", select = "^a_", regex = TRUE), 1)
})

test_that("count_n returns unnamed numeric vector", {
  df <- tibble::tibble(x = c("a", "b", "b"))
  result <- count_n(df, count = "b")
  expect_true(is.numeric(result))
  expect_null(names(result))
})

test_that("count_n works inside mutate()", {
  df <- tibble::tibble(x = c("a", "b", "c"), y = c("b", "b", "b"))
  out <- df |> dplyr::mutate(n_b = count_n(count = "b"))
  expect_equal(out$n_b, c(1, 2, 1))
})

test_that("count_n ignores incompatible columns safely", {
  df <- tibble::tibble(
    x = c("a", "b"),
    y = as.Date(c("2022-01-01", "2022-01-02")),
    z = list(1, 2)
  )
  expect_equal(count_n(df, count = "b"), c(0, 1))
})

test_that("count_n returns 0 for empty or incompatible selection", {
  df <- tibble::tibble(x = 1:3, y = letters[1:3])
  expect_equal(count_n(df, count = "z", select = "x"), c(0, 0, 0))
  expect_equal(count_n(df, count = "z", select = starts_with("not_here")), c(0, 0, 0))
})

test_that("count_n throws error if neither count nor special is specified", {
  df <- tibble::tibble(x = 1:3, y = letters[1:3])
  expect_error(
    count_n(df),
    "You must specify either `count` or `special`"
  )
})

Try the spicy package in your browser

Any scripts or data that you put into this service are public.

spicy documentation built on June 8, 2025, 11:06 a.m.