DRDataRaft/ docs
GitHub ↗

H21 Prepare numerator and denominator

H21A cancellation rate you can explain2 steps

Use your current course session. Preparation and course runner · R script ↓

H21a Define the period and population

Goal: State the business meaning before calculating.

Prerequisites: H20.

Teaching convention: August 2026. The denominator is policies active on August 1. The numerator is cancellations among those policies after August 1 and through August 31 inclusive. A policy already terminated on August 1 is excluded. New business during August is excluded. This is a simplified teaching definition.

training_step(
  "H21a",
  {
    dated_policies <- selected_rows
    dated_policies$start_date <- as.Date(rep("2026-01-01", 6))
    dated_policies$cancel_date <- as.Date(c(NA, NA, "2026-08-15", NA, NA, NA))
    period_start <- as.Date("2026-08-01")
    period_end <- as.Date("2026-08-31")
    print(dated_policies)
  },
  needs = c("H20")
)

Expected result: Six policies in the opening population and one cancellation date.

Task: Why is cancelled alone insufficient?

Show solution

Without a date, the period of the cancellation is unknown.

H21 Prepare numerator and denominator

Goal: Calculate two explicit indicators.

Prerequisites: H21a.

The recipe makes business logic visible before defining a metric. Its output has a dedicated contract.

training_step(
  "H21",
  {
    cohort_recipe <- dr_recipe() |>
      dr_step_mutate(
        in_opening = start_date <= period_start &
          (is.na(cancel_date) | cancel_date > period_start)
      ) |>
      dr_step_mutate(
        in_cancellations = in_opening &
          !is.na(cancel_date) &
          cancel_date <= period_end
      )
    cohort_contract <- dr_contract(
      "cohort",
      c(
        policy_id = "integer",
        premium = "numeric",
        cancelled = "logical",
        customer_id = "integer",
        broker_id = "integer",
        start_date = "Date",
        cancel_date = "Date",
        in_opening = "logical",
        in_cancellations = "logical"
      ),
      key = "policy_id"
    ) |>
      dr_contract_policy(
        required = c(
          "policy_id",
          "premium",
          "customer_id",
          "broker_id",
          "start_date",
          "in_opening",
          "in_cancellations"
        )
      )
    cohort_product <- dr_product(
      "policies.cohort",
      dated_policies,
      contract = cohort_contract
    ) |>
      dr_add_recipe(cohort_recipe) |>
      dr_add_quality(list(nonempty_denominator = ~ sum(in_opening) > 0))
    cohort_run <- dr_run(cohort_product, write = FALSE)
    cohort_rows <- dr_collect(cohort_run)
    stopifnot(
      sum(cohort_rows$in_opening) == 6L,
      sum(cohort_rows$in_cancellations) == 1L
    )
  },
  needs = c("H21a")
)

Expected result: Denominator 6 and numerator 1. cancel_date may be missing for ongoing policies.

Task: What happens to a policy starting on August 10?

Show solution

in_opening is FALSE. Try it in a copy and preserve the original data.

Search documentation

Search functions, packages and guides.