After full clearance
After 366 recorded full clearances, 239 had a later visit; at that visit 97 recorded moderate cover and 48 high cover. 127 have no later visit.
What the next visit recorded
366 full clearances; each share is out of the 239 with a later visit
Not recordable. The cover form holds no code for "gone": its lowest class is trace, under 1 percent, so a patch that stayed clear can only be written down as a trace. No bar can show it.
Each share as a recorded range
The low end counts none of the 127 clearances without a later visit in the class; the high end counts all of them. The tick is the share of later visits.
Limit on these shares: the cover class domain runs from a trace under one percent up to high, over fifty percent, and its floor is a trace rather than a zero: the form carries no code meaning the plant is gone, and the only recordable stand-in for still-clear is a removal band of none removed, which cannot separate nothing was there from nobody treated it this time.
Reading this result
- One row is
- A visit that wrote its patch down as fully cleared, read against the next visit to that patch.
- Counted over
- The 366 full clearances in these records; 239 of them have a later visit to the same patch.
- Left out
- 127 clearances still waiting for a later visit sit outside the shares and widen each range. 29 visits with no resolvable patch never enter the chain.
- Bear in mind
- The cover a return visit wrote down describes that day only. It is not a measure of how well the clearance held.
By year of clearance
Each bar is one calendar year of clearances, split by what the next visit recorded. Recent years hold more clearances still waiting for a later visit.
- Trace, under 1 percent
- Low, 1 to 10 percent
- Moderate, 11 to 50 percent
- High, over 50 percent
- No later visit yet
| Year | Cleared | Later visit | No later visit yet | Trace, under 1 percent | Low, 1 to 10 percent | Moderate, 11 to 50 percent | High, over 50 percent |
|---|---|---|---|---|---|---|---|
| 2018 | 9 | 9 | 0 | 2 | 5 | 1 | 1 |
| 2019 | 12 | 12 | 0 | 1 | 2 | 4 | 5 |
| 2020 | 15 | 15 | 0 | 2 | 3 | 6 | 4 |
| 2021 | 14 | 14 | 0 | 2 | 4 | 4 | 4 |
| 2022 | 18 | 18 | 0 | 0 | 5 | 10 | 3 |
| 2023 | 66 | 26 | 40 | 5 | 8 | 9 | 4 |
| 2024 | 72 | 59 | 13 | 6 | 14 | 26 | 13 |
| 2025 | 89 | 58 | 31 | 7 | 16 | 27 | 8 |
| 2026 | 71 | 28 | 43 | 4 | 8 | 10 | 6 |
On a narrow screen this table scrolls sideways; the cover classes are its last columns.
Values behind the bars
| Next recorded cover | Records | Share of later visits | Recorded range |
|---|---|---|---|
| Trace, under 1 percent | 29 | 12% | 8% to 43% |
| Low, 1 to 10 percent | 65 | 27% | 18% to 52% |
| Moderate, 11 to 50 percent | 97 | 41% | 27% to 61% |
| High, over 50 percent | 48 | 20% | 13% to 48% |
| No later visit yet | 127 | Outside the shares | Not a class |
Behind this number
3 functions compute it. Each is shown exactly as this build runs it.
.inv_oc_clearance_frame
apps/hub/R/inv_outcomes_revamp.R
.inv_oc_clearance_frame <- function (loaded)
{
slots <- inv_return_data(loaded)
cohort <- attr(slots, "cohort")
follow <- attr(slots, "follow")
rec <- slots[!slots$impossible, , drop = FALSE]
n_cohort <- nrow(cohort)
n_follow <- nrow(follow)
n_open <- n_cohort - n_follow
k <- as.integer(rec$n)
out <- data.frame(code = as.character(rec$code), label = as.character(rec$label),
n = k, share = if (n_follow > 0L)
k/n_follow
else rep(NA, length(k)), lo = if (n_cohort > 0L)
k/n_cohort
else rep(NA, length(k)), hi = if (n_cohort > 0L)
(k + n_open)/n_cohort
else rep(NA, length(k)), stringsAsFactors = FALSE)
attr(out, "n_cohort") <- n_cohort
attr(out, "n_follow") <- n_follow
attr(out, "n_open") <- n_open
attr(out, "arms") <- sort(unique(as.character(cohort$arm)))
attr(out, "gone_label") <- as.character(slots$label[slots$impossible])[1]
attr(out, "cohort") <- cohort
attr(out, "unlinked") <- attr(slots, "chain")$n_no_parent_recorded +
attr(slots, "chain")$n_parent_unresolved
out
}
.inv_oc_year_frame
apps/hub/R/inv_outcomes_revamp.R
.inv_oc_year_frame <- function (frame)
{
cohort <- attr(frame, "cohort")
yr <- as.integer(format(cohort$event_date, "%Y"))
years <- sort(unique(yr[!is.na(yr)]))
rows <- lapply(years, function(y) {
s <- cohort[!is.na(yr) & yr == y, , drop = FALSE]
later <- s[s$has_next, , drop = FALSE]
counts <- as.integer(table(factor(later$next_cover, levels = frame$code)))
data.frame(year = y, cleared = nrow(s), later = nrow(later), open = nrow(s) -
nrow(later), t(stats::setNames(counts, paste0("n_", seq_along(counts)))),
check.names = FALSE, stringsAsFactors = FALSE)
})
out <- if (length(rows))
do.call(rbind, rows)
else data.frame(year = integer(0), cleared = integer(0), later = integer(0),
open = integer(0))
attr(out, "undated") <- sum(is.na(yr))
out
}
inv_return_data
apps/hub/R/fig_invasive.R
inv_return_data <- function (loaded)
{
cfg <- .inv_cfg()
cl <- cfg$clearance
nv <- cfg$next_visit
where <- "inv_return_data"
as_of <- loaded$as_of
x <- .inv_chain(loaded)
ch <- x$chain
arms <- .inv_arms(loaded)
ch[["arm"]] <- arms$visits[["arm"]][match(ch[["visit_key"]], arms$visits[["visit_key"]])]
full_codes <- unlist(cl$full_clearance_codes, use.names = FALSE)
band_lvl <- inv_domain_levels(loaded, cl$band_domain, cl$band_layer,
as_of)
band_seen <- .inv_need(.inv_frame(loaded, "inv_visit"), "percent_removed_band",
where)
n_unrecognised <- sum(nzchar(trimws(band_seen)) & !(band_seen %in% band_lvl[["code"]]))
cohort <- ch[ch[["band"]] %in% full_codes, , drop = FALSE]
follow <- cohort[cohort[["has_next"]], , drop = FALSE]
cover_lvl <- inv_domain_levels(loaded, nv$cover_domain, nv$cover_layer,
as_of)
slots <- data.frame(slot = seq_len(nrow(cover_lvl) + 1L), code = c(NA,
cover_lvl[["code"]]), label = c(cl$no_gone_code_label, cover_lvl[["label"]]),
impossible = c(TRUE, rep(FALSE, nrow(cover_lvl))), stringsAsFactors = FALSE)
cnt <- as.integer(table(factor(follow[["next_cover"]], levels = cover_lvl[["code"]])))
slots[["n"]] <- c(0L, cnt)
slots[["share"]] <- ifelse(slots[["impossible"]], NA, slots[["n"]]/max(nrow(follow),
1L))
slots[["tier"]] <- ifelse(slots[["impossible"]], 3L, ddl_tier(slots[["n"]],
cfg$n_thresholds$cohort_arm))
all_follow <- ch[ch[["has_next"]], , drop = FALSE]
other <- band_lvl[["code"]][!band_lvl[["code"]] %in% full_codes]
ctx <- do.call(rbind, lapply(seq_along(other), function(i) {
s <- all_follow[all_follow[["band"]] == other[i], , drop = FALSE]
k <- as.integer(table(factor(s[["next_cover"]], levels = cover_lvl[["code"]])))
data.frame(band = other[i], band_i = i, label = inv_decode(loaded,
cl$band_domain, other[i], cl$band_layer, as_of), slot = seq_len(nrow(cover_lvl)) +
1L, code = cover_lvl[["code"]], n_band = nrow(s), n = k, share = k/max(nrow(s),
1L), again = sum(s[["next_band"]] != cl$zero_removal_code, na.rm = TRUE)/max(nrow(s),
1L), stringsAsFactors = FALSE)
}))
ctx[["scaled"]] <- ctx[["share"]] * nrow(follow)
tab_band <- table(all_follow[["band"]], all_follow[["next_cover"]])
chi_band <- suppressWarnings(stats::chisq.test(tab_band))
g <- all_follow[["gap_days"]]
qs <- stats::quantile(g, probs = seq(0, 1, length.out = 6), na.rm = TRUE)
qs[1] <- qs[1] - 1
bucket <- cut(g, unique(qs), labels = FALSE)
tab_gap <- table(bucket, all_follow[["next_cover"]])
chi_gap <- suppressWarnings(stats::chisq.test(tab_gap))
ord <- stats::setNames(cover_lvl[["sort_order"]], cover_lvl[["code"]])
ord_mean <- tapply(unname(ord[all_follow[["next_cover"]]]), bucket, mean)
zc <- cl$zero_removal_code
z_full <- sum(follow[["next_band"]] == zc, na.rm = TRUE)
oth_fu <- all_follow[!all_follow[["band"]] %in% full_codes, , drop = FALSE]
z_other <- sum(oth_fu[["next_band"]] == zc, na.rm = TRUE)
weak <- suppressWarnings(stats::prop.test(c(z_full, z_other), c(nrow(follow),
nrow(oth_fu))))
attr(slots, "cohort") <- cohort
attr(slots, "follow") <- follow
attr(slots, "context") <- ctx
attr(slots, "cover_lvl") <- cover_lvl
attr(slots, "band_lvl") <- band_lvl
attr(slots, "chi_band") <- chi_band
attr(slots, "chi_gap") <- chi_gap
attr(slots, "ord_mean") <- ord_mean
attr(slots, "weak") <- weak
attr(slots, "z_full") <- z_full
attr(slots, "z_other") <- z_other
attr(slots, "n_other_follow") <- nrow(oth_fu)
attr(slots, "n_unrecognised") <- n_unrecognised
attr(slots, "chain") <- x
slots
}
Read-only excerpts of this build's calculation code (hash 5912e90e4619). No record appears in them, and this page displays them without running them.