Nothing
# Tests for ltablesurv.R, which contains
# - vlookup()
# - calc_ltsurv()
# - calc_ex() - which is not actually used anywhere (yet) so not tested
# Vlookup is designed to work like Excel's vlookup() function, except with a choice of interpolation methods
# First let's test single value lookups without any interpolation
# Example lookup-table
looktab1 <- tibble::tibble(
rowno=1:10,
ind=(rowno-6)*10,
val=runif(10)
)
test_that("Exact lookups work", {
expect_equal(vlookup(looktab1$ind[3], looktab1$ind, looktab1$val), looktab1$val[3])
expect_equal(vlookup(looktab1$ind[1], looktab1$ind, looktab1$val), looktab1$val[1])
expect_equal(vlookup(looktab1$ind[10], looktab1$ind, looktab1$val), looktab1$val[10])
})
test_that("Error occurs if lookup value out of range", {
expect_error(vlookup(-90, looktab1$ind, looktab1$val))
expect_error(vlookup(190, looktab1$ind, looktab1$val))
})
test_that("All methods produce the same result, with exact lookup", {
expect_equal(vlookup(looktab1$ind[3], looktab1$ind, looktab1$val, method="floor"), looktab1$val[3])
expect_equal(vlookup(looktab1$ind[3], looktab1$ind, looktab1$val, method="ceiling"), looktab1$val[3])
expect_equal(vlookup(looktab1$ind[3], looktab1$ind, looktab1$val, method="arith"), looktab1$val[3])
expect_equal(vlookup(looktab1$ind[3], looktab1$ind, looktab1$val, method=""), looktab1$val[3])
expect_equal(vlookup(looktab1$ind[1], looktab1$ind, looktab1$val, method="floor"), looktab1$val[1])
expect_equal(vlookup(looktab1$ind[1], looktab1$ind, looktab1$val, method="ceiling"), looktab1$val[1])
expect_equal(vlookup(looktab1$ind[1], looktab1$ind, looktab1$val, method="arith"), looktab1$val[1])
expect_equal(vlookup(looktab1$ind[1], looktab1$ind, looktab1$val, method="garbage"), looktab1$val[1])
expect_equal(vlookup(looktab1$ind[10], looktab1$ind, looktab1$val, method="floor"), looktab1$val[10])
expect_equal(vlookup(looktab1$ind[10], looktab1$ind, looktab1$val, method="ceiling"), looktab1$val[10])
expect_equal(vlookup(looktab1$ind[10], looktab1$ind, looktab1$val, method="arith"), looktab1$val[10])
expect_equal(vlookup(looktab1$ind[10], looktab1$ind, looktab1$val, method=""), looktab1$val[10])
})
# Now try multi-value but exact lookups
mval <- c(1, 3, 10)
test_that("Multivalue exact lookups produce the same combined result", {
expect_equal(vlookup(looktab1$ind[mval], looktab1$ind, looktab1$val, method="floor"), looktab1$val[mval])
expect_equal(vlookup(looktab1$ind[mval], looktab1$ind, looktab1$val, method="ceiling"), looktab1$val[mval])
expect_equal(vlookup(looktab1$ind[mval], looktab1$ind, looktab1$val, method="arith"), looktab1$val[mval])
expect_equal(vlookup(looktab1$ind[mval], looktab1$ind, looktab1$val, method="geom"), looktab1$val[mval])
expect_equal(vlookup(looktab1$ind[mval], looktab1$ind, looktab1$val, method="garbage"), looktab1$val[mval])
expect_equal(vlookup(looktab1$ind[mval], looktab1$ind, looktab1$val, method=NA), looktab1$val[mval])
})
# Single values with interpolations
looktab1$ind[8] <- 18 # was 20
indval1.act <- 24
indval1.lo <- 18
indval1.hi <- 30
lookval1.lo <- looktab1$val[8]
lookval1.hi <- looktab1$val[9]
lookval1.arith <- (lookval1.lo*(indval1.hi-indval1.act) + lookval1.hi*(indval1.act-indval1.lo))/(indval1.hi-indval1.lo)
lookval1.geom <- (lookval1.lo^(indval1.hi-indval1.act) * lookval1.hi^(indval1.act-indval1.lo))^(1/(indval1.hi-indval1.lo))
test_that("Single value interpolation produces the right result with each method", {
expect_equal(vlookup(indval1.act, looktab1$ind, looktab1$val, method="floor"), lookval1.lo)
expect_equal(vlookup(indval1.act, looktab1$ind, looktab1$val, method="ceiling"), lookval1.hi)
expect_equal(vlookup(indval1.act, looktab1$ind, looktab1$val, method="arith"), lookval1.arith)
expect_equal(vlookup(indval1.act, looktab1$ind, looktab1$val, method="geom"), lookval1.geom)
expect_equal(vlookup(indval1.act, looktab1$ind, looktab1$val, method=""), lookval1.geom)
})
# Multi values with interpolations
indval2.act <- -36
indval2.lo <- -40
indval2.hi <- -30
lookval2.lo <- looktab1$val[2]
lookval2.hi <- looktab1$val[3]
lookval2.arith <- (lookval2.lo*(indval2.hi-indval2.act) + lookval2.hi*(indval2.act-indval2.lo))/(indval2.hi-indval2.lo)
lookval2.geom <- (lookval2.lo^(indval2.hi-indval2.act) * lookval2.hi^(indval2.act-indval2.lo))^(1/(indval2.hi-indval2.lo))
combind.act <- c(indval1.act, indval2.act)
combval.lo <- c(lookval1.lo, lookval2.lo)
combval.hi <- c(lookval1.hi, lookval2.hi)
combval.arith <- c(lookval1.arith, lookval2.arith)
combval.geom <- c(lookval1.geom, lookval2.geom)
test_that("Multi value interpolation produces the right result with each method", {
expect_equal(vlookup(combind.act, looktab1$ind, looktab1$val, method="floor"), combval.lo)
expect_equal(vlookup(combind.act, looktab1$ind, looktab1$val, method="ceiling"), combval.hi)
expect_equal(vlookup(combind.act, looktab1$ind, looktab1$val, method="arith"), combval.arith)
expect_equal(vlookup(combind.act, looktab1$ind, looktab1$val, method="geom"), combval.geom)
expect_equal(vlookup(combind.act, looktab1$ind, looktab1$val, method=""), combval.geom)
})
# Now test the lifetime survival function, which requires a lifetable
# Lifetable must have lttime and lx columns
ltable <- data.frame(lttime=0:20, lx=1000-10*(0:20))
timecheck <- 65
rowcheck <- 6
test_that("Single value survivals are correct", {
expect_equal(calc_ltsurv(5, ltable), ltable$lx[6]/ltable$lx[1])
expect_equal(calc_ltsurv(0, ltable), 1)
expect_equal(calc_ltsurv(20, ltable), ltable$lx[21]/ltable$lx[1])
})
test_that("Return error when lookup is out of range", {
expect_error(calc_ltsurv(20.1, ltable))
expect_error(calc_ltsurv(-0.1, ltable))
})
# Now check that the survival functions work with vectors
test_that("Multi value survivals are correct when in range, regardless of order", {
expect_equal(calc_ltsurv(c(1,2,3), ltable), c(calc_ltsurv(1, ltable), calc_ltsurv(2, ltable), calc_ltsurv(3, ltable)))
expect_equal(calc_ltsurv(c(4,13,8), ltable), c(calc_ltsurv(4, ltable), calc_ltsurv(13, ltable), calc_ltsurv(8, ltable)))
})
test_that("Multi value survivals return error when any index is out of range", {
expect_error(calc_ltsurv(c(-5,5,55), ltable))
expect_error(calc_ltsurv(c(-5,55,5), ltable))
})
# Finally check the density
# Derive density
ltable <- ltable |>
dplyr::mutate(
dx = lx - dplyr::lead(lx),
qx = dx/lx,
hx = -log(1-qx),
surv = lx/lx[1],
dens = hx * surv
)
test_that("Density function correctly derived with regular lifetable", {
expect_equal(calc_ltdens(ltable$lttime, ltable), ltable$dens)
expect_equal(calc_ltdens(0:19+0.2, ltable, method="floor"), ltable$dens[0:20])
})
# Try again with some times missing
ltable <- ltable[c(1,3,5,7,8,10,14,15,17,19),] |>
dplyr::select(lttime, lx) |>
dplyr:: mutate(
dx = lx - dplyr::lead(lx),
tx = dplyr::lead(lttime) - lttime,
qx = dx/lx,
hx = -log(1-qx)/tx,
surv = lx/lx[1],
dens = hx * surv
)
test_that("Density function works with times missing", {
expect_equal(calc_ltdens(ltable$lttime, ltable), ltable$dens)
expect_equal(calc_ltdens(ltable$lttime[1:9]+0.2, ltable, method="floor"), ltable$dens[1:9])
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.