diff --git a/SPLICE/.Rhistory b/SPLICE/.Rhistory index 06c2926..996be34 100644 --- a/SPLICE/.Rhistory +++ b/SPLICE/.Rhistory @@ -1,172 +1,3 @@ -View(indicator) -View(as.numeric(indicator)) -View(as.factor(indicator)) -View(output_actual[indicator]) -View(output_actual *indicator) -View(upper.tri(output_actual[, 1:40], diag = TRUE)) -output_actual[!indicator] <- NA -View(output_actual) -x <- output_noinflation -View(x[!indicator]) -x[!indicator] <- NA -View(x) -View(output_noinflation) -document() -?output_incurred -vignette("SPLICE-demo", package = "SPLICE") -vignette("SynthETIC-demo", package = "SynthETIC") -?vignette -# incurred triangles -# Constant dollar value INCREMENTAL triangle -incurred_noInf <- incurred_output(test, incremental = TRUE) -# incurred triangles -# Constant dollar value INCREMENTAL triangle -incurred_noInf <- output_incurred(test, incremental = TRUE) -View(incurred_noInf) -incurred_noInf <- output_incurred(test, incremental = TRUE, aggregate_level = 2) -View(incurred_noInf) -incurred_noInf <- output_incurred(test, incremental = F) -incurred_noInf <- output_incurred(test, incremental = F, future = F) -View(incurred_noInf) -load_all() -incurred_noInf <- output_incurred(test, incremental = F, future = F) -View(incurred_noInf) -load_all() -incurred_noInf <- output_incurred(test, incremental = F, future = F) -View(incurred_noInf) -ceiling(1:10) -ceiling(1:10 / 4) -40 + 40 - 1 -?output_incurred -i <- 1 -j <- 1 -incurred_history <- test -# convert to discrete time scale (t in terms of absolute time) -t <- ceiling(incurred_history[[i]][[j]]$txn_time / aggregate_level) -aggregate_level <- 4 -# convert to discrete time scale (t in terms of absolute time) -t <- ceiling(incurred_history[[i]][[j]]$txn_time / aggregate_level) -t -incurred_right <- incurred_history[[i]][[j]]$incurred_right -i_rescaled <- 1 -side <- 10 -# Now get the latest incurred estimate in a period -incurred_latest <- rep(NA, i_rescaled + side - 1) -incurred_latest -# Fill the incurred estimates -incurred_latest[unique(t)] <- incurred_right[!rev(duplicated(rev(t)))] -incurred_latest -# Fill the NAs prior to the first non-NA with 0 -# (i.e. assume no incurred until claim notified) -firstNonNA <- min(which(!is.na(incurred_latest))) -firstNonNA -i <- 40 -i_rescaled <- 10 -# convert to discrete time scale (t in terms of absolute time) -t <- ceiling(incurred_history[[i]][[j]]$txn_time / aggregate_level) -t -incurred_right <- incurred_history[[i]][[j]]$incurred_right -# Now get the latest incurred estimate in a period -incurred_latest <- rep(NA, i_rescaled + side - 1) -# Fill the incurred estimates -incurred_latest[unique(t)] <- incurred_right[!rev(duplicated(rev(t)))] -incurred_latest -unique(t) -i_rescaled <- ceiling(i / 4) -i_rescaled -load_all() -View(incurred_inflated) -x <- incurred_inflated -y <- output_incurred(test_inflated, incremental = TRUE) -load_all() -y <- output_incurred(test_inflated, incremental = TRUE) -sum(x == y) -sum(x != y) -View(x) -View(y) -View(test_inflated) -test_inflated[[1]][[1]] -set.seed(20201006) -test_claims <- SynthETIC::test_claims_object -major <- claim_maRev_no(test_claims) -major <- claim_maRev_time(test_claims, major) -major <- claim_maRev_size(major) -# minor revisions -minor <- claim_miRev_no(test_claims) -minor <- claim_miRev_time(test_claims, minor) -minor <- claim_miRev_size(test_claims, major, minor) -test <- claim_history(test_claims, major, minor) -test_inflated <- claim_history(test_claims, major, minor, inflated = TRUE, -base_inflation_vector = rep((1 + 0.02)^(1/4) - 1, times = 80)) -test_inflated[[1]][[1]]$miRev -test_inflated[[1]][[1]]$incurred_right -major[[1]][[1]] -major[[1]][[2]] -major[[1]][[29]] -# Incurred triangles -incurred_output <- function( -incurred_history, -aggregate_level = 1, -incremental = TRUE) { -frequency_vector <- lengths(incurred_history) -I <- length(frequency_vector) -incurred_cumulative <- array(0, c(I, I)) -adjustment <- 0 # track the number of corrections required for keeping all the -# transaction times within the bound -for (i in 1:I) { -for (j in 1:frequency_vector[i]) { -# convert to discrete time scale (t in terms of absolute time) -t <- ceiling(incurred_history[[i]][[j]]$txn_t) -incurred_right <- incurred_history[[i]][[j]]$incurred_right -# Firstly need to treat the out-of-bound transaction times -if (any(t - i + 1 > I)) { -t[which(t - i + 1 > I)] <- i + I - 1 -adjustment <- adjustment + 1 -} -# Now get the latest incurred estimate in a period -incurred_latest <- rep(NA, i + I - 1) -# Fill the incurred estimates -incurred_latest[unique(t)] <- incurred_right[!rev(duplicated(rev(t)))] -# Fill the NAs prior to the first non-NA with 0 -# (i.e. assume no incurred until claim notified) -firstNonNA <- min(which(!is.na(incurred_latest))) -if (firstNonNA > i) { -incurred_latest[i:(firstNonNA - 1)] <- 0 -} -# Fill the rest of NAs with the prior non-NAs -incurred_latest <- zoo::na.locf(incurred_latest, na.rm = TRUE) -for (k in 1:I) { -incurred_cumulative[i, k] <- incurred_cumulative[i, k] + incurred_latest[k] -} -} -} -no_txn <- lengths(lapply(unlist(incurred_history, recursive = F), `[[`, "txn_time")) -total_no_txn <- sum(no_txn) -if (adjustment / total_no_txn > 0.03) { -warning("More than 3% of the transactions were outside the bound.") -} -if (aggregate_level != 1) { -# if aggregate at a higher level (e.g. aggregate_level = 4 for yearly triangles) -new_side_length <- I / aggregate_level -incurred_cumulative_orig <- incurred_cumulative -incurred_cumulative <- array(0, c(new_side_length, new_side_length)) -for (i in 1:new_side_length) { -side_occurrence <- (aggregate_level * (i-1) + 1): (aggregate_level * i) -for (j in 1:new_side_length) { -side_development <- aggregate_level * j -incurred_cumulative[i, j] <- sum( -incurred_cumulative_orig[side_occurrence, side_development]) -} -} -} -if (incremental == TRUE) { -incurred_incremental <- incurred_cumulative -for (i in 1:dim(incurred_cumulative)[1]) { -incurred_incremental[i, 1] <- incurred_cumulative[i, 1] -for (j in 2:dim(incurred_cumulative)[2]) { -incurred_incremental[i, j] <- incurred_cumulative[i, j] - incurred_cumulative[i, j - 1] -} -} incurred_incremental } else { incurred_cumulative @@ -510,3 +341,172 @@ major <- claim_maRev_no(test_claims) major <- claim_maRev_time(test_claims, major) major <- claim_maRev_size(major) major[[1]][[29]] +## generated with default assumptions +library(SynthETIC) +set.seed(20200131) +n_vector <- claim_frequency(I = 40, E = 12000, freq = 0.1) +occurrence_times <- claim_occurrence(n_vector) +claim_sizes <- claim_size(n_vector) +notidel <- claim_notification(n_vector, claim_sizes) +setldel <- claim_closure(n_vector, claim_sizes) +no_payments <- claim_payment_no(n_vector, claim_sizes) +payment_sizes <- claim_payment_size(n_vector, claim_sizes, no_payments) +payment_delays <- claim_payment_delay(n_vector, claim_sizes, no_payments, setldel) +payment_times <- claim_payment_time(n_vector, occurrence_times, notidel, payment_delays) +base_inflation_vector <- rep((1.02)^(1/4) - 1, times = 80) +payment_inflated <- claim_payment_inflation( +n_vector, payment_sizes, payment_times, occurrence_times, +claim_sizes, base_inflation_vector) +# generate datasets +# claim level data +claim_dataset <- generate_claim_dataset( +frequency_vector = n_vector, +occurrence_list = occurrence_times, +claim_size_list = claim_sizes, +notification_list = notidel, +settlement_list = setldel, +no_payments_list = no_payments +) +# payment level data +test_claims <- claims( +n_vector, occurrence_times, claim_sizes, notidel, setldel, no_payments, +payment_sizes, payment_delays, payment_times, payment_inflated) +transaction_dataset <- generate_transaction_dataset( +test_claims, +adjust = FALSE # to keep the original simulated payment times +) +write.csv(claim_dataset, "~/Downloads/claim_dataset_20210825.csv") +write.csv(transaction_dataset, "~/Downloads/payment_dataset_inflated_20210825.csv") +## With SPLICE loaded (locally) +major <- claim_maRev_no(test_claims) +library(devtools) +load_all() +## With SPLICE loaded (locally) +major <- claim_maRev_no(test_claims) +major <- claim_maRev_time(test_claims, major) +major <- claim_maRev_size(major) +# minor revisions +minor <- claim_miRev_no(test_claims) +minor <- claim_miRev_time(test_claims, minor) +minor <- claim_miRev_size(test_claims, major, minor) +test <- claim_history(test_claims, major, minor) +test_inflated <- claim_history(test_claims, major, minor, inflated = TRUE, +base_inflation_vector = rep((1 + 0.02)^(1/4) - 1, times = 80)) +test_inflated <- claim_history(test_claims, major, minor, +base_inflation_vector = rep((1 + 0.02)^(1/4) - 1, times = 80)) +test_incurred_dataset <- generate_incurred_dataset(test_claims, test) +test_incurred_dataset_inflated <- generate_incurred_dataset(test_claims, test_inflated) +View(test_incurred_dataset) +test[[1]][[1]] +## generated with default assumptions +library(SynthETIC) +set.seed(20200131) +n_vector <- claim_frequency(I = 40, E = 12000, freq = 0.1) +occurrence_times <- claim_occurrence(n_vector) +claim_sizes <- claim_size(n_vector) +notidel <- claim_notification(n_vector, claim_sizes) +setldel <- claim_closure(n_vector, claim_sizes) +no_payments <- claim_payment_no(n_vector, claim_sizes) +payment_sizes <- claim_payment_size(n_vector, claim_sizes, no_payments) +payment_delays <- claim_payment_delay(n_vector, claim_sizes, no_payments, setldel) +payment_times <- claim_payment_time(n_vector, occurrence_times, notidel, payment_delays) +base_inflation_vector <- rep((1.02)^(1/4) - 1, times = 80) +payment_inflated <- claim_payment_inflation( +n_vector, payment_sizes, payment_times, occurrence_times, +claim_sizes, base_inflation_vector) +# generate datasets +# claim level data +claim_dataset <- generate_claim_dataset( +frequency_vector = n_vector, +occurrence_list = occurrence_times, +claim_size_list = claim_sizes, +notification_list = notidel, +settlement_list = setldel, +no_payments_list = no_payments +) +# payment level data +test_claims <- claims( +n_vector, occurrence_times, claim_sizes, notidel, setldel, no_payments, +payment_sizes, payment_delays, payment_times, payment_inflated) +transaction_dataset <- generate_transaction_dataset( +test_claims, +adjust = FALSE # to keep the original simulated payment times +) +# write.csv(claim_dataset, "~/Downloads/claim_dataset_20210825.csv") +# write.csv(transaction_dataset, "~/Downloads/payment_dataset_inflated_20210825.csv") +# triangles +# Constant dollar value INCREMENTAL triangle +output_noinflation <- claim_output(n_vector, payment_times, payment_sizes, +incremental = TRUE) +# Inflated INCREMENTAL triangle +output_actual <- claim_output(n_vector, payment_times, payment_inflated, +incremental = TRUE) +# write.csv(output_noinflation, "~/Downloads/triangle_noInf_20210825.csv") +# write.csv(output_actual, "~/Downloads/triangle_inflated_20210825.csv") +## With SPLICE loaded (locally) +major <- claim_maRev_no(test_claims) +major <- claim_maRev_time(test_claims, major) +major <- claim_maRev_size(major) +# minor revisions +minor <- claim_miRev_no(test_claims) +minor <- claim_miRev_time(test_claims, minor) +minor <- claim_miRev_size(test_claims, major, minor) +test <- claim_history(test_claims, major, minor) +test_inflated <- claim_history(test_claims, major, minor, +base_inflation_vector = rep((1 + 0.02)^(1/4) - 1, times = 80)) +test_incurred_dataset <- generate_incurred_dataset(test_claims, test) +test_incurred_dataset_inflated <- generate_incurred_dataset(test_claims, test_inflated) +major[[1]][[1]] +View(test_incurred_dataset_inflated) +View(test_incurred_dataset) +View(transaction_dataset) +write.csv(test_incurred_dataset, "~/Downloads/incurred_dataset_noInf_20210825.csv") +write.csv(test_incurred_dataset_inflated, "~/Downloads/incurred_dataset_inflated_20210825.csv") +write.csv(incurred_noInf, "~/Downloads/incurred_triangle_noInf_20210825.csv") +# incurred triangles +# Constant dollar value INCREMENTAL triangle +incurred_noInf <- output_incurred(test, incremental = TRUE) +# Inflated INCREMENTAL triangle +incurred_inflated <- output_incurred(test_inflated, incremental = TRUE) +write.csv(incurred_noInf, "~/Downloads/incurred_triangle_noInf_20210825.csv") +write.csv(incurred_inflated, "~/Downloads/incurred_triangle_inflated_20210825.csv") +x <- claim_dataset %>% +select(claim_no, occurrence_time) %>% +merge(test_incurred_dataset, by = "claim_no") +library(dplyr) +i +x <- claim_dataset %>% +select(claim_no, occurrence_time) %>% +merge(test_incurred_dataset, by = "claim_no") +View(x) +test_incurred_dataset <- generate_incurred_dataset(test_claims, test) +colnames(test_incurred_dataset) +occurrence <- data.frame( +claim_no = claim_dataset$claim_no, +claim_size = claim_dataset$claim_size, +txn_time = claim_dataset$occurrence_time, +txn_delay = -claim_dataset$notidel, +txn_type = "O", +incurred = 0, +OCL = 0, +cumpaid = 0, +multiplier = NA) +View(occurrence) +x <- rbind(test_incurred_dataset, occurrence) %>% +arrange(claim_no, txn_time) +View(x) +nrow(x) +nrow(test_incurred_dataset) + nrow(claim_dataset) +1.7948353 - 0.6238351 +2.5837741 - 0.1206679 +y <- rbind(test_incurred_dataset_inflated, occurrence) %>% +arrange(claim_no, txn_time) +write.csv(x, "~/Downloads/incurred_dataset_noInf_20210825.csv") +write.csv(y, "~/Downloads/incurred_dataset_inflated_20210825.csv") +# incurred triangles +# Constant dollar value INCREMENTAL triangle +incurred_noInf <- output_incurred(test, incremental = TRUE) +# Inflated INCREMENTAL triangle +incurred_inflated <- output_incurred(test_inflated, incremental = TRUE) +write.csv(incurred_noInf, "~/Downloads/incurred_triangle_noInf_20210825.csv") +write.csv(incurred_inflated, "~/Downloads/incurred_triangle_inflated_20210825.csv") diff --git a/SPLICE/NAMESPACE b/SPLICE/NAMESPACE index c831b4c..96efcea 100644 --- a/SPLICE/NAMESPACE +++ b/SPLICE/NAMESPACE @@ -1,12 +1,12 @@ # Generated by roxygen2: do not edit by hand export(claim_history) -export(claim_maRev_no) -export(claim_maRev_size) -export(claim_maRev_time) -export(claim_miRev_no) -export(claim_miRev_size) -export(claim_miRev_time) +export(claim_majRev_freq) +export(claim_majRev_size) +export(claim_majRev_time) +export(claim_minRev_freq) +export(claim_minRev_size) +export(claim_minRev_time) export(dtri) export(generate_incurred_dataset) export(output_incurred) diff --git a/SPLICE/R/data.R b/SPLICE/R/data.R index 9762145..4a193a4 100644 --- a/SPLICE/R/data.R +++ b/SPLICE/R/data.R @@ -28,7 +28,10 @@ #' \item{cumpaid}{double; cumulative claim paid **after** the transaction.} #' \item{multiplier}{revision multipliers (subject to further constraints #' documented in \code{\link{claim_history}}), `NA` for -#' transactions that do not involve a revision.} +#' transactions that do not involve a revision. Note that +#' major revision multipliers apply to the incurred losses, +#' while minor revision multipliers apply to the outstanding +#' claim payments.} #' } #' @seealso \code{\link{generate_incurred_dataset}} #' @name test_incurred_dataset diff --git a/SPLICE/R/features_09_major_revisions.R b/SPLICE/R/features_09_major_revisions.R index 025380a..e5fc8fd 100644 --- a/SPLICE/R/features_09_major_revisions.R +++ b/SPLICE/R/features_09_major_revisions.R @@ -12,10 +12,10 @@ #' simulated quantities (other than those related to incurred loss), see #' \code{\link[SynthETIC]{claims}}. #' @param rfun optional alternative random sampling function for: -#' * `claim_maRev_no`: the number of major revisions; -#' * `claim_maRev_time`: the epochs of major revisions measured from claim +#' * `claim_majRev_freq`: the number of major revisions; +#' * `claim_majRev_time`: the epochs of major revisions measured from claim #' notification; -#' * `claim_maRev_size`: the sizes of the major revision multipliers. +#' * `claim_majRev_size`: the sizes of the major revision multipliers. #' #' See Details for default. #' @param paramfun parameters for the random sampling function, as a function of @@ -28,16 +28,16 @@ #' @param ... other arguments/parameters to be passed onto \code{paramfun}. #' #' For example, if going with the default sampling distribution for -#' `claim_maRev_no`, you can specify a `claim_size_benchmark` (below which +#' `claim_majRev_freq`, you can specify a `claim_size_benchmark` (below which #' claims are assumed to have no major revisions other than one at claim #' notification; default benchmark at 0.075 * `ref_claim`). #' -#' @section Details - `claim_maRev_no` (Frequency): Let *K* represent the number +#' @section Details - `claim_majRev_freq` (Frequency): Let *K* represent the number #' of major revisions associated with a particular claim. The notification of a #' claim is considered as a major revision, so all claims have at least 1 major #' revision (\eqn{K \ge 1}). #' -#' The default `maRev_no_function` specifies that no additional major revisions +#' The default `majRev_freq_function` specifies that no additional major revisions #' will occur for claims of size smaller than or equal to `claim_size_benchmark` #' (0.075 * `ref_claim` by default). For claims above this threshold, #' \tabular{ll}{ @@ -52,27 +52,27 @@ #' not occur at all for the smallest claims. Note also that by default a claim #' may experience **up to a maximum of 2 major revisions** in addition to the #' one at claim notification. This is taken as an assumption in the default -#' setting of `claim_maRev_size()`. If user decides to modify this assumption, +#' setting of `claim_majRev_size()`. If user decides to modify this assumption, #' they will need to take care of the part on the major revision size as well. #' @return A nested list structure such that the *j*th component of the *i*th #' sub-list is a list of information on major revisions of the *j*th claim of #' occurrence period *i*. The "unit list" (i.e. the smallest, innermost #' sub-list) contains the following components: #' \tabular{ll}{ -#' `maRev_no` \tab Number of major revisions of incurred loss -#' \[`claim_maRev_no()`\]. \cr -#' `maRev_time` \tab Time of major revisions (from claim notification) -#' \[`claim_maRev_time()`\]. \cr -#' `maRev_multiplier` \tab Major revision multiplier of **incurred loss** -#' \[`claim_maRev_size()`\]. \cr -#' `maRev_atP` \tab An indicator, `1` if the last major revision occurs at the +#' `majRev_freq` \tab Number of major revisions of incurred loss +#' \[`claim_majRev_freq()`\]. \cr +#' `majRev_time` \tab Time of major revisions (from claim notification) +#' \[`claim_majRev_time()`\]. \cr +#' `majRev_factor` \tab Major revision multiplier of **incurred loss** +#' \[`claim_majRev_size()`\]. \cr +#' `majRev_atP` \tab An indicator, `1` if the last major revision occurs at the #' time of the last major payment (i.e. second last payment), `0` otherwise -#' \[`claim_maRev_time()`\]. +#' \[`claim_majRev_time()`\]. #' } #' @seealso \code{\link[SynthETIC]{claims}} #' @export -#' @name claim_maRev -claim_maRev_no <- function( +#' @name claim_majRev +claim_majRev_freq <- function( claims, rfun, paramfun, @@ -97,7 +97,7 @@ claim_maRev_no <- function( # default function to simulate the number of major revisions # NOTE: the default function takes as an assumption that there are max 3 # major revisions -> if user wants to change this, they need to take care of - # the later module (maRev_size) too + # the later module (majRev_size) too if (missing(rfun)) { rfun <- function( # n = number of observations/claims @@ -141,13 +141,13 @@ claim_maRev_no <- function( I <- length(frequency_vector) no_claims <- sum(frequency_vector) - maRev <- vector("list", I) - # maRev_unit stores all major revision information on a single claim - maRev_unit <- list( - maRev_no = NA, - maRev_time = NA, - maRev_multiplier = NA, - maRev_atP = NA + majRev <- vector("list", I) + # majRev_unit stores all major revision information on a single claim + majRev_unit <- list( + majRev_freq = NA, + majRev_time = NA, + majRev_factor = NA, + majRev_atP = NA ) # set up the simulation parameters params <- mapply(paramfun, @@ -170,39 +170,39 @@ claim_maRev_no <- function( if (paramfun_filled) { # check if the "empty" paramfun is sufficient to call the rfun - tt <- try(no_maRev_vect <- do.call(rfun, keep_formals), TRUE) + tt <- try(no_majRev_vect <- do.call(rfun, keep_formals), TRUE) if (methods::is(tt, "try-error")) { stop("need to specify 'paramfun' for the sampling distribution") } } else { - no_maRev_vect <- do.call(rfun, keep_formals) + no_majRev_vect <- do.call(rfun, keep_formals) } curr <- 1 # curr tracks the claim number for (i in 1:I) { - maRev[[i]] <- vector("list", frequency_vector[i]) + majRev[[i]] <- vector("list", frequency_vector[i]) for (j in 1:frequency_vector[i]) { - maRev[[i]][[j]] <- maRev_unit - maRev[[i]][[j]]$maRev_no <- no_maRev_vect[curr] + majRev[[i]][[j]] <- majRev_unit + majRev[[i]][[j]]$majRev_freq <- no_majRev_vect[curr] curr <- curr + 1 } } - maRev + majRev } -#' @rdname claim_maRev +#' @rdname claim_majRev #' @param claims an \code{\link[SynthETIC]{claims}} object containing all the #' simulated quantities (other than those related to incurred loss), see #' \code{\link[SynthETIC]{claims}}. -#' @param maRev_list nested list of major revision histories (with non-empty +#' @param majRev_list nested list of major revision histories (with non-empty #' revision frequencies). #' @param rfun optional alternative random sampling function for: -#' * `claim_maRev_no`: the number of major revisions; -#' * `claim_maRev_time`: the epochs of major revisions measured from claim +#' * `claim_majRev_freq`: the number of major revisions; +#' * `claim_majRev_time`: the epochs of major revisions measured from claim #' notification; -#' * `claim_maRev_size`: the sizes of the major revision multipliers. +#' * `claim_majRev_size`: the sizes of the major revision multipliers. #' #' See Details for default. #' @param paramfun parameters for the random sampling function, as a function of @@ -216,7 +216,7 @@ claim_maRev_no <- function( #' \code{\link[SynthETIC]{claim_payment_delay}}. #' @param ... other arguments/parameters to be passed onto \code{paramfun}. #' -#' @section Details - `claim_maRev_time` (Time): Let \eqn{\tau_k} represent the +#' @section Details - `claim_majRev_time` (Time): Let \eqn{\tau_k} represent the #' epoch of the *k*th major revision (time measured from claim notification), #' \eqn{k = 1, ..., K}. As the notification of a claim is considered a major #' revision itself, we have \eqn{\tau_1 = 0} for all claims. @@ -243,12 +243,12 @@ claim_maRev_no <- function( #' - maximum density at `mode = settlement_delay / 3`. #' #' Note that when there is a major revision at the time of the second last -#' partial payment, `maRev_atP` (one of the output list components) will be set +#' partial payment, `majRev_atP` (one of the output list components) will be set #' to be 1. #' @export -claim_maRev_time <- function( +claim_majRev_time <- function( claims, - maRev_list, + majRev_list, rfun, paramfun, claim_size_list = claims$claim_size_list, @@ -275,8 +275,8 @@ claim_maRev_time <- function( rfun <- function(n, claim_size, setldel, penultimate_delay) { # n = number of simulations, here n should be the number of major revisions # penultimate_delay = delay from notification to penultimate payment - maRev_time <- rep(NA, times = n) - maRev_time[1] <- 0 # first revision at notification + majRev_time <- rep(NA, times = n) + majRev_time[1] <- 0 # first revision at notification # inherit ref_claim from SynthETIC ref_claim <- SynthETIC::return_parameters()[1] @@ -289,17 +289,17 @@ claim_maRev_time <- function( at_second_last_pmt <- sample(c(0, 1), size = 1, replace = TRUE, prob = c(1-p, p)) if (at_second_last_pmt == 0) { # no revision at second last payment - maRev_time[2:n] <- sort(rtri(n - 1, min = setldel/3, max = setldel, mode = setldel/3)) + majRev_time[2:n] <- sort(rtri(n - 1, min = setldel/3, max = setldel, mode = setldel/3)) } else { # revision at second last payment - maRev_time[n] <- penultimate_delay + majRev_time[n] <- penultimate_delay if (n > 2) { - maRev_time[2:(n-1)] <- sort( - rtri(n - 2, min = maRev_time[n]/3, max = maRev_time[n], mode = maRev_time[n]/3)) + majRev_time[2:(n-1)] <- sort( + rtri(n - 2, min = majRev_time[n]/3, max = majRev_time[n], mode = majRev_time[n]/3)) } } } - maRev_time + majRev_time } # the paramfun needs to account for the "computation" of penultimate_delay @@ -310,7 +310,7 @@ claim_maRev_time <- function( } } - I <- length(maRev_list) + I <- length(majRev_list) params <- mapply( paramfun, claim_size = unlist(claim_size_list, use.names = FALSE), @@ -340,52 +340,52 @@ claim_maRev_time <- function( curr <- 1 for (i in 1:I) { - for (j in 1 : length(maRev_list[[i]])) { + for (j in 1 : length(majRev_list[[i]])) { - k <- maRev_list[[i]][[j]]$maRev_no + k <- majRev_list[[i]][[j]]$majRev_freq if (paramfun_filled) { - tt <- try(maRev_list[[i]][[j]]$maRev_time <- do.call( + tt <- try(majRev_list[[i]][[j]]$majRev_time <- do.call( rfun, c(as.list(args_df[, curr]), n = k))) if (methods::is(tt, "try-error")) { stop("need to specify 'paramfun' for the sampling distribution") } } else { - maRev_list[[i]][[j]]$maRev_time <- do.call( + majRev_list[[i]][[j]]$majRev_time <- do.call( rfun, c(as.list(args_df[, curr]), n = k)) } # is there a revision at second last payment? payment_delays <- payment_delay_list[[i]][[j]] no_pmt <- length(payment_delays) - maRev_list[[i]][[j]]$maRev_atP <- ifelse( - maRev_list[[i]][[j]]$maRev_time[k] == sum(payment_delays[1:(no_pmt - 1)]), + majRev_list[[i]][[j]]$majRev_atP <- ifelse( + majRev_list[[i]][[j]]$majRev_time[k] == sum(payment_delays[1:(no_pmt - 1)]), 1, 0) curr <- curr + 1 } } - maRev_list + majRev_list } -#' @rdname claim_maRev -#' @param maRev_list nested list of major revision histories (with non-empty +#' @rdname claim_majRev +#' @param majRev_list nested list of major revision histories (with non-empty #' revision frequencies). #' @param rfun optional alternative random sampling function for: -#' * `claim_maRev_no`: the number of major revisions; -#' * `claim_maRev_time`: the epochs of major revisions measured from claim +#' * `claim_majRev_freq`: the number of major revisions; +#' * `claim_majRev_time`: the epochs of major revisions measured from claim #' notification; -#' * `claim_maRev_size`: the sizes of the major revision multipliers. +#' * `claim_majRev_size`: the sizes of the major revision multipliers. #' #' See Details for default. #' @param paramfun parameters for the random sampling function, as a function of #' other claim characteristics such as \code{claim_size}; see Details. #' @param ... other arguments/parameters to be passed onto \code{paramfun}. #' -#' @section Details - `claim_maRev_size` (Revision Multiplier): As mentioned in -#' the frequency section ("Details - `claim_maRev_no`"), the default function +#' @section Details - `claim_majRev_size` (Revision Multiplier): As mentioned in +#' the frequency section ("Details - `claim_majRev_freq`"), the default function #' for the major revision multipliers assumes that there are only up to 2 major #' revisions (in addition to the one at claim notification) for all claims. #' @@ -406,26 +406,26 @@ claim_maRev_time <- function( #' is, a revision multiplier of 2.54 means that at the time of the major #' revision the incurred loss increases by a factor of 2.54. We highlight this #' as **in the case of minor revisions, the multipliers will instead apply to -#' outstanding claim amounts**, see \code{\link{claim_miRev}}. +#' outstanding claim amounts**, see \code{\link{claim_minRev}}. #' #' @examples #' set.seed(1) #' test_claims <- SynthETIC::test_claims_object -#' major <- claim_maRev_no(test_claims) +#' major <- claim_majRev_freq(test_claims) #' major[[1]][[1]] # the "unit list" for the first claim #' #' # update the timing information -#' major <- claim_maRev_time(test_claims, major) +#' major <- claim_majRev_time(test_claims, major) #' # observe how this has changed #' major[[1]][[1]] #' #' # update the revision multipliers -#' major <- claim_maRev_size(major) +#' major <- claim_majRev_size(major) #' # again observe how this has changed #' major[[1]][[1]] #' @export -claim_maRev_size <- function( - maRev_list, +claim_majRev_size <- function( + majRev_list, rfun, paramfun, ... @@ -446,21 +446,21 @@ claim_maRev_size <- function( # default function to simulate multiplier sizes # NOTE: this only works for up to 3 major revisions -> if user has adjusted - # the maRev_no_function, they will need to adjust this accordingly + # the majRev_freq_function, they will need to adjust this accordingly if (missing(rfun)) { rfun <- function(n) { # n = number of simulations, here n should be the number of major revisions - maRev_multiplier <- rep(NA, times = n) - maRev_multiplier[1] <- 1 # for first revision (at notification) + majRev_factor <- rep(NA, times = n) + majRev_factor[1] <- 1 # for first revision (at notification) if (n > 1) { # if the claim has multiple major revisions - maRev_multiplier[2] <- stats::rlnorm(n = 1, meanlog = 1.8, sdlog = 0.2) + majRev_factor[2] <- stats::rlnorm(n = 1, meanlog = 1.8, sdlog = 0.2) if (n > 2) { - mu <- 1 + 0.07 * (6 - maRev_multiplier[2]) - maRev_multiplier[3] <- stats::rlnorm(n = 1, meanlog = mu, sdlog = 0.1) + mu <- 1 + 0.07 * (6 - majRev_factor[2]) + majRev_factor[3] <- stats::rlnorm(n = 1, meanlog = mu, sdlog = 0.1) } } - maRev_multiplier + majRev_factor } # the default rfun does not depend on other claim characteristics, so the @@ -471,7 +471,7 @@ claim_maRev_size <- function( } - I <- length(maRev_list) + I <- length(majRev_list) params <- mapply(paramfun, ...) # if params only has one parameter, asplit() won't work @@ -495,18 +495,18 @@ claim_maRev_size <- function( curr <- 1 for (i in 1:I) { - for (j in 1 : length(maRev_list[[i]])) { + for (j in 1 : length(majRev_list[[i]])) { - k <- maRev_list[[i]][[j]]$maRev_no + k <- majRev_list[[i]][[j]]$majRev_freq if (paramfun_filled) { - tt <- try(maRev_list[[i]][[j]]$maRev_multiplier <- do.call( + tt <- try(majRev_list[[i]][[j]]$majRev_factor <- do.call( rfun, c(as.list(args_df[, curr]), n = k))) if (methods::is(tt, "try-error")) { stop("need to specify 'paramfun' for the sampling distribution") } } else { - maRev_list[[i]][[j]]$maRev_multiplier <- do.call( + majRev_list[[i]][[j]]$majRev_factor <- do.call( rfun, c(as.list(args_df[, curr]), n = k)) } @@ -514,6 +514,6 @@ claim_maRev_size <- function( } } - maRev_list + majRev_list } diff --git a/SPLICE/R/features_10_minor_revisions.R b/SPLICE/R/features_10_minor_revisions.R index 072f5ae..7eea200 100644 --- a/SPLICE/R/features_10_minor_revisions.R +++ b/SPLICE/R/features_10_minor_revisions.R @@ -10,23 +10,23 @@ #' #' We separate the case of minor revisions that occur simultaneously with a #' partial payment (denoted `_atP`), and the ones that do not coincide with a -#' payment (denoted `_NatP`). +#' payment (denoted `_notatP`). #' #' @param claims an `claims` object containing all the simulated quantities #' (other than those related to incurred loss), see #' \code{\link[SynthETIC]{claims}}. #' @param prob_atP (optional) probability that a minor revision will occur at #' the time of a partial payment; default value 0.5. -#' @param rfun_NatP optional alternative random sampling function for: -#' * `claim_miRev_no`: the number of minor revisions that occur at an epoch +#' @param rfun_notatP optional alternative random sampling function for: +#' * `claim_minRev_freq`: the number of minor revisions that occur at an epoch #' other than those of partial payments; -#' * `claim_miRev_time`: the epochs of such minor revisions measured from claim +#' * `claim_minRev_time`: the epochs of such minor revisions measured from claim #' notification; -#' * `claim_miRev_size`: the sizes of the minor revision multipliers (common for -#' `_atP` and `_NatP`, hence simply termed `rfun` in this case). +#' * `claim_minRev_size`: the sizes of the minor revision multipliers (common for +#' `_atP` and `_notatP`, hence simply termed `rfun` in this case). #' #' See Details for default. -#' @param paramfun_NatP parameters for the above random sampling function, +#' @param paramfun_notatP parameters for the above random sampling function, #' as a function of other claim characteristics (e.g. `lambda` as a function of #' `claim_size` for an `rpois` simulation); see Examples. #' @param frequency_vector a vector of claim frequencies for all the periods @@ -39,7 +39,7 @@ #' \code{\link[SynthETIC]{claim_payment_no}}. #' @param ... other arguments/parameters to be passed onto \code{paramfun}. #' -#' @section Details - `claim_miRev_no` (Frequency): Minor revisions may occur +#' @section Details - `claim_minRev_freq` (Frequency): Minor revisions may occur #' simultaneously with a partial payment, or at any other time. #' #' For the former case, we sample the occurrence of minor revisions as Bernoulli @@ -50,7 +50,7 @@ #' \eqn{min(3, setldel / 4)}. #' #' One can modify the above sampling distributions by plugging in their own -#' `prob_atP` parameter and `rfun_NatP` function, where the former dictates +#' `prob_atP` parameter and `rfun_notatP` function, where the former dictates #' the probability of incurring a minor revision at the time of a payment, and #' the latter simulates and returns the number of minor revisions at any other #' points in time, with possible dependence on the settlement delay of the claim @@ -61,41 +61,41 @@ #' occurrence period *i*. The "unit list" (i.e. the smallest, innermost #' sub-list) contains the following components: #' \tabular{ll}{ -#' `miRev_atP` \tab A vector of indicators showing whether there is a minor -#' revision at each partial payment \[`claim_miRev_no()`\]. \cr -#' `miRev_no_atP` \tab Number of minor revisions that occur simultaneously with -#' a partial payment, numerically equals to the sum of `miRev_atP` -#' \[`claim_miRev_no()`\]. \cr -#' `miRev_no_NatP` \tab Number of minor revisions that do not occur with a -#' partial payment \[`claim_miRev_no()`\]. \cr -#' `miRev_time_atP` \tab Time of minor revisions that occur simultaneously with +#' `minRev_atP` \tab A vector of indicators showing whether there is a minor +#' revision at each partial payment \[`claim_minRev_freq()`\]. \cr +#' `minRev_freq_atP` \tab Number of minor revisions that occur simultaneously with +#' a partial payment, numerically equals to the sum of `minRev_atP` +#' \[`claim_minRev_freq()`\]. \cr +#' `minRev_freq_notatP` \tab Number of minor revisions that do not occur with a +#' partial payment \[`claim_minRev_freq()`\]. \cr +#' `minRev_time_atP` \tab Time of minor revisions that occur simultaneously with #' a partial payment (time measured from claim notification) -#' \[`claim_miRev_time()`\]. \cr -#' `miRev_time_NatP` \tab Time of minor revisions that do *not* occur +#' \[`claim_minRev_time()`\]. \cr +#' `minRev_time_notatP` \tab Time of minor revisions that do *not* occur #' simultaneously with a partial payment (time measured from claim notification) -#' \[`claim_miRev_time()`\]. \cr -#' `miRev_multiplier_atP` \tab Minor revision multipliers of **outstanding claim -#' payments** for revisions at partial payments \[`claim_miRev_size()`\]. \cr -#' `miRev_multiplier_NatP` \tab Minor revision multipliers of **outstanding claim -#' payments** for revisions at any other times \[`claim_miRev_size()`\]. \cr +#' \[`claim_minRev_time()`\]. \cr +#' `minRev_factor_atP` \tab Minor revision multipliers of **outstanding claim +#' payments** for revisions at partial payments \[`claim_minRev_size()`\]. \cr +#' `minRev_factor_notatP` \tab Minor revision multipliers of **outstanding claim +#' payments** for revisions at any other times \[`claim_minRev_size()`\]. \cr #' } #' @seealso \code{\link[SynthETIC]{claims}} #' @export -#' @name claim_miRev -claim_miRev_no <- function( +#' @name claim_minRev +claim_minRev_freq <- function( claims, prob_atP = 0.5, # probability of coinciding with a partial payment - rfun_NatP, # miRev_no_NatP_function - paramfun_NatP, # paramfun for miRev_no_NatP (not at payment) + rfun_notatP, # minRev_freq_notatP_function + paramfun_notatP, # paramfun for minRev_freq_notatP (not at payment) frequency_vector = claims$frequency_vector, settlement_list = claims$settlement_list, no_payments_list = claims$no_payments_list, ... ) { - if (!missing(rfun_NatP) & missing(paramfun_NatP)) { + if (!missing(rfun_notatP) & missing(paramfun_notatP)) { # we will see if we can continue without parameterisation - paramfun_NatP <- function(...) { + paramfun_notatP <- function(...) { c(...) } # paramfun_filled indicates whether an "empty" paramfun is taken by default @@ -119,8 +119,8 @@ claim_miRev_no <- function( # default function to simulate the number of minor revisions # ... that are not simultaneous with partial payment - if (missing(rfun_NatP)) { - rfun_NatP <- function(n, setldel) { + if (missing(rfun_notatP)) { + rfun_notatP <- function(n, setldel) { # n = number of observations/claims k2 <- stats::rgeom(n, prob = 1 / (min(3, setldel/4) + 1)) k2 @@ -128,22 +128,22 @@ claim_miRev_no <- function( # the default rfun directly takes setldel as an input, so the "empty" # paramfun would do the trick - paramfun_NatP <- function(...) { + paramfun_notatP <- function(...) { c(...) } } I <- length(frequency_vector) - miRev <- vector("list", I) - # miRev_unit stores all minor revision information on a single claim - miRev_unit <- list( - miRev_atP = NA, - miRev_no_atP = NA, miRev_no_NatP = NA, - miRev_time_atP = NA, miRev_time_NatP = NA, - miRev_multiplier_atP = NA, miRev_multiplier_NatP = NA + minRev <- vector("list", I) + # minRev_unit stores all minor revision information on a single claim + minRev_unit <- list( + minRev_atP = NA, + minRev_freq_atP = NA, minRev_freq_notatP = NA, + minRev_time_atP = NA, minRev_time_notatP = NA, + minRev_factor_atP = NA, minRev_factor_notatP = NA ) # set up the simulation parameters - params <- mapply(paramfun_NatP, + params <- mapply(paramfun_notatP, setldel = unlist(settlement_list, use.names = FALSE), ...) # convert to function arguments @@ -156,9 +156,9 @@ claim_miRev_no <- function( params_split <- params } - # do.call rfun_NatP, but ignore unused arguments + # do.call rfun_notatP, but ignore unused arguments args <- as.list(params_split) - keep_names <- c(intersect(names(args), names(formals(rfun_NatP)))) + keep_names <- c(intersect(names(args), names(formals(rfun_notatP)))) keep_formals <- c(args[keep_names]) # turn keep_formals, which is a list of arguments, to a dataframe @@ -168,42 +168,42 @@ claim_miRev_no <- function( curr <- 1 for (i in 1:I) { - miRev[[i]] <- vector("list", frequency_vector[i]) + minRev[[i]] <- vector("list", frequency_vector[i]) for (j in 1:frequency_vector[i]) { - miRev[[i]][[j]] <- miRev_unit + minRev[[i]][[j]] <- minRev_unit - # miRev simultaneous with a payment - miRev[[i]][[j]]$miRev_atP <- rfun_atP( + # minRev simultaneous with a payment + minRev[[i]][[j]]$minRev_atP <- rfun_atP( n = no_payments_list[[i]][j], prob = prob_atP) - miRev[[i]][[j]]$miRev_no_atP <- sum(miRev[[i]][[j]]$miRev_atP) + minRev[[i]][[j]]$minRev_freq_atP <- sum(minRev[[i]][[j]]$minRev_atP) - # miRev non-simultaneous with a payment + # minRev non-simultaneous with a payment if (paramfun_filled) { - tt <- try(miRev[[i]][[j]]$miRev_no_NatP <- do.call( - rfun_NatP, c(as.list(args_df[, curr]), n = 1))) + tt <- try(minRev[[i]][[j]]$minRev_freq_notatP <- do.call( + rfun_notatP, c(as.list(args_df[, curr]), n = 1))) if (methods::is(tt, "try-error")) { - stop("need to specify 'paramfun_NatP' for the sampling distribution") + stop("need to specify 'paramfun_notatP' for the sampling distribution") } } else { - miRev[[i]][[j]]$miRev_no_NatP <- do.call( - rfun_NatP, c(as.list(args_df[, curr]), n = 1)) + minRev[[i]][[j]]$minRev_freq_notatP <- do.call( + rfun_notatP, c(as.list(args_df[, curr]), n = 1)) } curr <- curr + 1 } } - miRev + minRev } -#' @rdname claim_miRev -#' @param miRev_list nested list of minor revision histories (with non-empty +#' @rdname claim_minRev +#' @param minRev_list nested list of minor revision histories (with non-empty #' revision frequencies). #' @param payment_delay_list (compound) list of inter partial delays (not #' required if the `claims` argument is provided); see #' \code{\link[SynthETIC]{claim_payment_delay}}. #' -#' @section Details - `claim_miRev_time` (Time): For minor revisions that occur +#' @section Details - `claim_minRev_time` (Time): For minor revisions that occur #' simultaneously with a partial payment, the revision times simply coincide #' with the epochs of the relevant partial payments. #' @@ -212,25 +212,25 @@ claim_miRev_no <- function( #' settlement_delay / 6} and `max` \eqn{= settlement_delay}. #' #' One can modify the above sampling distribution by plugging in their own -#' `rfun_NatP` and `paramfun_NatP` in `claim_miRev_time()`, which together +#' `rfun_notatP` and `paramfun_notatP` in `claim_minRev_time()`, which together #' simulate the epochs of minor revisions that do not coincide with a payment, #' with possible dependence on the settlement delay of the claim and/or other #' claim characteristics (see Examples). #' #' @export -claim_miRev_time <- function( +claim_minRev_time <- function( claims, - miRev_list, - rfun_NatP, - paramfun_NatP, + minRev_list, + rfun_notatP, + paramfun_notatP, settlement_list = claims$settlement_list, payment_delay_list = claims$payment_delay_list, ... ) { - if (!missing(rfun_NatP) & missing(paramfun_NatP)) { + if (!missing(rfun_notatP) & missing(paramfun_notatP)) { # we will see if we can continue without parameterisation - paramfun_NatP <- function(...) { + paramfun_notatP <- function(...) { c(...) } # paramfun_filled indicates whether an "empty" paramfun is taken by default @@ -241,22 +241,22 @@ claim_miRev_time <- function( # default function to simulate the timing of minor revisions (from notification) # for revisions non-simultaneous with payments - if (missing(rfun_NatP)) { - rfun_NatP <- function(n, setldel) { + if (missing(rfun_notatP)) { + rfun_notatP <- function(n, setldel) { # n = number of minor revisions non-simultaneous with payments sort(stats::runif(n, min = setldel/6, max = setldel)) } # the default rfun directly takes setldel as an input, so the "empty" # paramfun would do the trick - paramfun_NatP <- function(...) { + paramfun_notatP <- function(...) { c(...) } } - I <- length(miRev_list) + I <- length(minRev_list) params <- mapply( - paramfun_NatP, + paramfun_notatP, setldel = unlist(settlement_list, use.names = FALSE), ...) @@ -271,7 +271,7 @@ claim_miRev_time <- function( # do.call rfun, but ignore unused arguments args <- as.list(params_split) - keep_names <- c(intersect(names(args), names(formals(rfun_NatP)))) + keep_names <- c(intersect(names(args), names(formals(rfun_notatP)))) keep_formals <- c(args[keep_names]) # turn keep_formals, which is a list of arguments, to a dataframe @@ -281,52 +281,52 @@ claim_miRev_time <- function( curr <- 1 for (i in 1:I) { - for (j in 1 : length(miRev_list[[i]])) { + for (j in 1 : length(minRev_list[[i]])) { - k1 <- miRev_list[[i]][[j]]$miRev_no_atP - k2 <- miRev_list[[i]][[j]]$miRev_no_NatP + k1 <- minRev_list[[i]][[j]]$minRev_freq_atP + k2 <- minRev_list[[i]][[j]]$minRev_freq_notatP k <- k1 + k2 - rev_atP <- miRev_list[[i]][[j]]$miRev_atP + rev_atP <- minRev_list[[i]][[j]]$minRev_atP payment_delays <- payment_delay_list[[i]][[j]] # revisions that coincide with the payments - miRev_list[[i]][[j]]$miRev_time_atP <- + minRev_list[[i]][[j]]$minRev_time_atP <- cumsum(payment_delays)[as.logical(rev_atP)] # revisions that occur non-simultaneously with a payment if (paramfun_filled) { - tt <- try(miRev_list[[i]][[j]]$miRev_time_NatP <- do.call( - rfun_NatP, c(as.list(args_df[, curr]), n = k2))) + tt <- try(minRev_list[[i]][[j]]$minRev_time_notatP <- do.call( + rfun_notatP, c(as.list(args_df[, curr]), n = k2))) if (methods::is(tt, "try-error")) { - stop("need to specify 'paramfun_NatP' for the sampling distribution") + stop("need to specify 'paramfun_notatP' for the sampling distribution") } } else { - miRev_list[[i]][[j]]$miRev_time_NatP <- do.call( - rfun_NatP, c(as.list(args_df[, curr]), n = k2)) + minRev_list[[i]][[j]]$minRev_time_notatP <- do.call( + rfun_notatP, c(as.list(args_df[, curr]), n = k2)) } curr <- curr + 1 } } - miRev_list + minRev_list } -#' @rdname claim_miRev -#' @param maRev_list nested list of major revision histories (with non-empty +#' @rdname claim_minRev +#' @param majRev_list nested list of major revision histories (with non-empty #' revision frequencies). #' @param rfun optional alternative random sampling function for the sizes of -#' the minor revision multipliers (common for `_atP` and `_NatP`, hence simply +#' the minor revision multipliers (common for `_atP` and `_notatP`, hence simply #' termed `rfun` in this case). -#' @param paramfun_atP parameters for `rfun` in `claim_miRev_size()` for minor +#' @param paramfun_atP parameters for `rfun` in `claim_minRev_size()` for minor #' revisions that occur at the time of a partial payment. #' -#' @section Details - `claim_miRev_size` (Revision Multiplier): The sampling +#' @section Details - `claim_minRev_size` (Revision Multiplier): The sampling #' distribution for minor revision multipliers is the same for both revisions #' that occur with and without a partial payment. In the default setting, we #' incorporate sampling dependence on the delay from notification to settlement #' (`setldel`), the delay from notification to the subject minor revisions -#' (`miRev_time`), and the history of major revisions (in particular, the time +#' (`minRev_time`), and the history of major revisions (in particular, the time #' of the second major revision). #' #' Let \eqn{\tau} denote the delay from notification to the epoch of the minor @@ -360,49 +360,49 @@ claim_miRev_time <- function( #' @examples #' set.seed(1) #' test_claims <- SynthETIC::test_claims_object -#' minor <- claim_miRev_no(test_claims) +#' minor <- claim_minRev_freq(test_claims) #' minor[[1]][[1]] # the "unit list" for the first claim #' #' # update the timing information -#' minor <- claim_miRev_time(test_claims, minor) +#' minor <- claim_minRev_time(test_claims, minor) #' # observe how this has changed #' minor[[1]][[1]] #' # with an alternative sampling distribution e.g. triangular -#' miRev_time_NatP <- function(n, setldel) { +#' minRev_time_notatP <- function(n, setldel) { #' sort(rtri(n, min = setldel/6, max = setldel, mode = setldel)) #' } -#' minor_2 <- claim_miRev_time(test_claims, minor, miRev_time_NatP) +#' minor_2 <- claim_minRev_time(test_claims, minor, minRev_time_notatP) #' #' # update the revision multipliers (need to generate "major" first) -#' # minor <- claim_miRev_size(test_claims, major, minor) +#' # minor <- claim_minRev_size(test_claims, major, minor) #' @export -claim_miRev_size <- function( +claim_minRev_size <- function( claims, - maRev_list, # to get the time of the 2nd major revision - miRev_list, + majRev_list, # to get the time of the 2nd major revision + minRev_list, rfun, paramfun_atP, - paramfun_NatP, + paramfun_notatP, settlement_list = claims$settlement_list, ... ) { - if (!missing(rfun) & (missing(paramfun_atP) | missing(paramfun_NatP))) { + if (!missing(rfun) & (missing(paramfun_atP) | missing(paramfun_notatP))) { stop("need to specify 'paramfun' for the sampling distribution") } - # default function to simulate multiplier sizes (common for miRev atP and NatP) + # default function to simulate multiplier sizes (common for minRev atP and NatP) if (missing(rfun)) { rfun <- function( # n = number of minor revisions - n, miRev_time, maRev_time_2nd, setldel) { + n, minRev_time, majRev_time_2nd, setldel) { - k <- length(miRev_time) - miRev_multiplier <- vector(length = k) + k <- length(minRev_time) + minRev_factor <- vector(length = k) if (k >= 1) { for (i in 1:k) { - curr <- miRev_time[i] + curr <- minRev_time[i] if (curr <= setldel/3) { meanlog <- 0.15 } else if (curr <= (2/3) * setldel) { @@ -410,47 +410,47 @@ claim_miRev_size <- function( } else { meanlog <- -0.1 } - sdlog <- ifelse(curr > maRev_time_2nd, 0.05, 0.1) - miRev_multiplier[i] <- stats::rlnorm(n = 1, meanlog, sdlog) + sdlog <- ifelse(curr > majRev_time_2nd, 0.05, 0.1) + minRev_factor[i] <- stats::rlnorm(n = 1, meanlog, sdlog) } } - miRev_multiplier + minRev_factor } - # extract miRev_time and maRev_time_2nd + # extract minRev_time and majRev_time_2nd paramfun_atP <- function(major, minor, setldel, ...) { - list(miRev_time = minor$miRev_time_atP, - maRev_time_2nd = ifelse( - # so it always holds miRev_time < maRev_time_2nd - is.na(major$maRev_time[2]), setldel + 1, major$maRev_time[2]), + list(minRev_time = minor$minRev_time_atP, + majRev_time_2nd = ifelse( + # so it always holds minRev_time < majRev_time_2nd + is.na(major$majRev_time[2]), setldel + 1, major$majRev_time[2]), setldel = setldel, ...) } - paramfun_NatP <- function(major, minor, setldel, ...) { - list(miRev_time = minor$miRev_time_NatP, - maRev_time_2nd = ifelse( - # so it always holds miRev_time < maRev_time_2nd - is.na(major$maRev_time[2]), setldel + 1, major$maRev_time[2]), + paramfun_notatP <- function(major, minor, setldel, ...) { + list(minRev_time = minor$minRev_time_notatP, + majRev_time_2nd = ifelse( + # so it always holds minRev_time < majRev_time_2nd + is.na(major$majRev_time[2]), setldel + 1, major$majRev_time[2]), setldel = setldel, ...) } } - I <- length(miRev_list) + I <- length(minRev_list) params_atP <- mapply( paramfun_atP, setldel = unlist(settlement_list, use.names = FALSE), - major = unlist(maRev_list, use.names = FALSE, recursive = FALSE), - minor = unlist(miRev_list, use.names = FALSE, recursive = FALSE), + major = unlist(majRev_list, use.names = FALSE, recursive = FALSE), + minor = unlist(minRev_list, use.names = FALSE, recursive = FALSE), ... ) - params_NatP <- mapply( - paramfun_NatP, + params_notatP <- mapply( + paramfun_notatP, setldel = unlist(settlement_list, use.names = FALSE), - major = unlist(maRev_list, use.names = FALSE, recursive = FALSE), - minor = unlist(miRev_list, use.names = FALSE, recursive = FALSE), + major = unlist(majRev_list, use.names = FALSE, recursive = FALSE), + minor = unlist(minRev_list, use.names = FALSE, recursive = FALSE), ... ) @@ -470,34 +470,34 @@ claim_miRev_size <- function( # in the dataframe, each row represents a parameter, and each column gives the # parameter values for a specific claim - # repeat for params_NatP - if (!is.null(names(params_NatP))) { - params_split_NatP <- split(unname(params_NatP), names(params_NatP)) - } else if (length(params_NatP)) { - params_split_NatP <- asplit(params_NatP, 1) + # repeat for params_notatP + if (!is.null(names(params_notatP))) { + params_split_notatP <- split(unname(params_notatP), names(params_notatP)) + } else if (length(params_notatP)) { + params_split_notatP <- asplit(params_notatP, 1) } else { - params_split_NatP <- params_NatP + params_split_notatP <- params_notatP } - args <- as.list(params_split_NatP) + args <- as.list(params_split_notatP) keep_names <- c(intersect(names(args), names(formals(rfun)))) keep_formals <- c(args[keep_names]) - args_df_NatP <- do.call(rbind, keep_formals) + args_df_notatP <- do.call(rbind, keep_formals) curr <- 1 for (i in 1:I) { - for (j in 1 : length(miRev_list[[i]])) { + for (j in 1 : length(minRev_list[[i]])) { - k1 <- miRev_list[[i]][[j]]$miRev_no_atP - k2 <- miRev_list[[i]][[j]]$miRev_no_NatP + k1 <- minRev_list[[i]][[j]]$minRev_freq_atP + k2 <- minRev_list[[i]][[j]]$minRev_freq_notatP - miRev_list[[i]][[j]]$miRev_multiplier_atP <- do.call( + minRev_list[[i]][[j]]$minRev_factor_atP <- do.call( rfun, c(as.list(args_df_atP[, curr]), n = k1)) - miRev_list[[i]][[j]]$miRev_multiplier_NatP <- do.call( - rfun, c(as.list(args_df_NatP[, curr]), n = k2)) + minRev_list[[i]][[j]]$minRev_factor_notatP <- do.call( + rfun, c(as.list(args_df_notatP[, curr]), n = k2)) curr <- curr + 1 } } - miRev_list + minRev_list } diff --git a/SPLICE/R/features_11_incurred_history.R b/SPLICE/R/features_11_incurred_history.R index 5a2b7f8..1b0ba2a 100644 --- a/SPLICE/R/features_11_incurred_history.R +++ b/SPLICE/R/features_11_incurred_history.R @@ -5,7 +5,7 @@ # Development of case estimates # Helper function (hidden from users) individual_claim_history <- function( - maRev, miRev, + majRev, minRev, claim_size, no_pmt, payment_delays, payment_sizes, occurrence, notidel, k1, k2, # k1_inv for major revision, k2_inv for minor revision inflated, base_inflation_vector, @@ -34,39 +34,39 @@ individual_claim_history <- function( # rewrite the inter-partial delays as delays from notification Ptimes <- cumsum(payment_delays) # incurred revision indicator - rev_atP <- miRev$miRev_atP + rev_atP <- minRev$minRev_atP rev_atP <- ifelse(rev_atP == 1, "PMi", "P") - if (maRev$maRev_atP == 1) { + if (majRev$majRev_atP == 1) { rev_atP[no_pmt - 1] <- "PMa" - # if there is a simultaneous maRev and miRev at the second last payment + # if there is a simultaneous majRev and minRev at the second last payment # then discard the minor revision - if (miRev$miRev_atP[no_pmt - 1] == 1) { - no_miRev <- miRev$miRev_no_atP - if (miRev$miRev_atP[no_pmt] == 0) { + if (minRev$minRev_atP[no_pmt - 1] == 1) { + no_minRev <- minRev$minRev_freq_atP + if (minRev$minRev_atP[no_pmt] == 0) { # no minor revision at the last payment - miRev$miRev_time_atP <- miRev$miRev_time_atP[-no_miRev] - miRev$miRev_multiplier_atP <- miRev$miRev_multiplier_atP[-no_miRev] + minRev$minRev_time_atP <- minRev$minRev_time_atP[-no_minRev] + minRev$minRev_factor_atP <- minRev$minRev_factor_atP[-no_minRev] } else { # if there was a minor revision at the last payment too - miRev$miRev_time_atP <- miRev$miRev_time_atP[-(no_miRev - 1)] - miRev$miRev_multiplier_atP <- miRev$miRev_multiplier_atP[-(no_miRev - 1)] + minRev$minRev_time_atP <- minRev$minRev_time_atP[-(no_minRev - 1)] + minRev$minRev_factor_atP <- minRev$minRev_factor_atP[-(no_minRev - 1)] } - miRev$miRev_atP[no_pmt - 1] <- 0 - miRev$miRev_no_atP <- miRev$miRev_no_atP - 1 + minRev$minRev_atP[no_pmt - 1] <- 0 + minRev$minRev_freq_atP <- minRev$minRev_freq_atP - 1 } } # insert the revisions that do not occur at a payment - maRev_NatP <- maRev$maRev_time - if (maRev$maRev_atP == 1) { - maRev_NatP <- maRev_NatP[-maRev$maRev_no] + majRev_freqtatP <- majRev$majRev_time + if (majRev$majRev_atP == 1) { + majRev_freqtatP <- majRev_freqtatP[-majRev$majRev_freq] } - miRev_NatP <- miRev$miRev_time_NatP - txn_delay <- sort(c(Ptimes, maRev_NatP, miRev_NatP)) + minRev_freqtatP <- minRev$minRev_time_notatP + txn_delay <- sort(c(Ptimes, majRev_freqtatP, minRev_freqtatP)) txn_time <- txn_delay + occurrence + notidel # in absolute time txn_type <- rep(NA, length(txn_delay)) txn_type[txn_delay %in% Ptimes] <- rev_atP - txn_type[txn_delay %in% maRev_NatP] <- "Ma" - txn_type[txn_delay %in% miRev_NatP] <- "Mi" + txn_type[txn_delay %in% majRev_freqtatP] <- "Ma" + txn_type[txn_delay %in% minRev_freqtatP] <- "Mi" stopifnot(txn_type %in% c("P", "PMi", "PMa", "Mi", "Ma")) # need cumulative claims paid, outstanding claims liability and incurred @@ -75,12 +75,12 @@ individual_claim_history <- function( no_txn <- length(txn_delay) c_left <- x_left <- y_left <- c_right <- x_right <- y_right <- rep(NA, no_txn) p_index <- no_pmt - Ma_index <- maRev$maRev_no - Mi_index_atP <- miRev$miRev_no_atP - Mi_index_NatP <- miRev$miRev_no_NatP - Ma_multp <- maRev$maRev_multiplier - Mi_multp_atP <- miRev$miRev_multiplier_atP - Mi_multp_NatP <- miRev$miRev_multiplier_NatP + Ma_index <- majRev$majRev_freq + Mi_index_atP <- minRev$minRev_freq_atP + Mi_index_notatP <- minRev$minRev_freq_notatP + Ma_multp <- majRev$majRev_factor + Mi_multp_atP <- minRev$minRev_factor_atP + Mi_multp_notatP <- minRev$minRev_factor_notatP # inherit time unit from SynthETIC time_unit <- SynthETIC::return_parameters()[2] @@ -173,17 +173,17 @@ individual_claim_history <- function( # need y >= k2_inv * c after the retrospective revision k2_inv <- 1 / k2 - x_left[i] <- (y_left[i] - c_left[i]) / Mi_multp_NatP[Mi_index_NatP] + x_left[i] <- (y_left[i] - c_left[i]) / Mi_multp_notatP[Mi_index_notatP] y_left[i] <- x_left[i] + c_left[i] y_right[i - 1] <- y_left[i] <- max(y_left[i], k2_inv * c_left[i]) x_right[i - 1] <- x_left[i] <- y_left[i] - c_left[i] - Mi_index_NatP <- Mi_index_NatP - 1 + Mi_index_notatP <- Mi_index_notatP - 1 } } } - stopifnot(Ma_index == 1 && Mi_index_atP == 0 && Mi_index_NatP == 0 && p_index == 0) + stopifnot(Ma_index == 1 && Mi_index_atP == 0 && Mi_index_notatP == 0 && p_index == 0) y_left[1] <- y_right[1] x_left[1] <- x_right[1] c_left[1] <- c_right[1] <- 0 # claim paid at notification should be zero @@ -194,7 +194,7 @@ individual_claim_history <- function( cumpaid_left = c_left, cumpaid_right = c_right, OCL_left = x_left, OCL_right = x_right, incurred_left = y_left, incurred_right = y_right, - miRev = miRev, maRev = maRev) + minRev = minRev, majRev = majRev) } else { result <- list( txn_delay = txn_delay, @@ -203,8 +203,8 @@ individual_claim_history <- function( cumpaid_right = c_right, OCL_right = x_right, incurred_right = y_right, - miRev = miRev, - maRev = maRev) + minRev = minRev, + majRev = majRev) } return(result) @@ -220,10 +220,10 @@ individual_claim_history <- function( #' @param claims an `claims` object containing all the simulated quantities #' (other than those related to incurred loss), see #' \code{\link[SynthETIC]{claims}}. -#' @param maRev_list nested list of major revision histories, see -#' \code{\link{claim_maRev}}. -#' @param miRev_list nested list of minor revision histories, see -#' \code{\link{claim_miRev}}. +#' @param majRev_list nested list of major revision histories, see +#' \code{\link{claim_majRev}}. +#' @param minRev_list nested list of minor revision histories, see +#' \code{\link{claim_minRev}}. #' @param k1 maximum amount of cumulative claims paid as a proportion of #' total incurred estimate for major revisions; between 0 and 1. #' @param k2 maximum amount of cumulative claims paid as a proportion of @@ -244,7 +244,7 @@ individual_claim_history <- function( #' - Major and minor revisions should not occur simultaneously. In the event #' that they do (which is only possible at the second last partial payment), #' the major revision takes precedence, and the minor revision be discarded. -#' This will be reflected in the `maRev` and `miRev` components of the output +#' This will be reflected in the `majRev` and `minRev` components of the output #' list. #' - Estimates of incurred loss are specified to be computed in reverse order, #' and it is necessary that the total incurred estimate is always strictly @@ -293,10 +293,10 @@ individual_claim_history <- function( #' after each of the transactions (in the "right" continuous sense). \cr #' `incurred_right` \tab Case estimate of incurred loss immediately after each #' of the transactions (in the "right" continuous sense). \cr -#' `miRev` \tab A list containing full history of minor revisions (frequency, -#' time and revision size); \code{\link{claim_miRev}}. \cr -#' `maRev` \tab A list containing full history of major revisions (frequency, -#' time and revision size); see \code{\link{claim_maRev}}. +#' `minRev` \tab A list containing full history of minor revisions (frequency, +#' time and revision size); \code{\link{claim_minRev}}. \cr +#' `majRev` \tab A list containing full history of major revisions (frequency, +#' time and revision size); see \code{\link{claim_majRev}}. #' } #' #' and optionally (by setting `keep_all = TRUE`), @@ -311,8 +311,8 @@ individual_claim_history <- function( #' @export claim_history <- function( claims, - maRev_list, - miRev_list, + majRev_list, + minRev_list, k1 = 0.95, k2 = 0.95, # k1 for major revision, k2 for minor revision base_inflation_vector = NULL, keep_all = FALSE @@ -349,8 +349,8 @@ claim_history <- function( } full_history[[i]][[j]] <- individual_claim_history( - maRev = maRev_list[[i]][[j]], - miRev = miRev_list[[i]][[j]], + majRev = majRev_list[[i]][[j]], + minRev = minRev_list[[i]][[j]], claim_size = claims$claim_size[[i]][j], no_pmt = claims$no_payments_list[[i]][j], payment_delays = claims$payment_delay_list[[i]][[j]], diff --git a/SPLICE/R/output_incurred.R b/SPLICE/R/output_incurred.R index cf0407e..911ae87 100644 --- a/SPLICE/R/output_incurred.R +++ b/SPLICE/R/output_incurred.R @@ -37,28 +37,28 @@ generate_incurred_dataset <- function( ) # Extract and append the multiplier information - maRev_multiplier <- miRev_multiplier_atP <- miRev_multiplier_NatP <- vector() + majRev_factor <- minRev_factor_atP <- minRev_factor_notatP <- vector() tcount <- 0 for (i in 1:I) { for (j in 1:claims$frequency_vector[i]) { - extract_ma <- incurred_history[[i]][[j]]$maRev$maRev_multiplier - extract_miP <- incurred_history[[i]][[j]]$miRev$miRev_multiplier_atP - extract_miNP <- incurred_history[[i]][[j]]$miRev$miRev_multiplier_NatP - num <- incurred_history[[i]][[j]]$miRev$miRev_no_atP - - maRev_multiplier <- c(maRev_multiplier, extract_ma) - miRev_multiplier_atP <- c(miRev_multiplier_atP, extract_miP) - miRev_multiplier_NatP <- c(miRev_multiplier_NatP, extract_miNP) + extract_ma <- incurred_history[[i]][[j]]$majRev$majRev_factor + extract_miP <- incurred_history[[i]][[j]]$minRev$minRev_factor_atP + extract_miNP <- incurred_history[[i]][[j]]$minRev$minRev_factor_notatP + num <- incurred_history[[i]][[j]]$minRev$minRev_freq_atP + + majRev_factor <- c(majRev_factor, extract_ma) + minRev_factor_atP <- c(minRev_factor_atP, extract_miP) + minRev_factor_notatP <- c(minRev_factor_notatP, extract_miNP) tcount <- tcount + num } } incurred_dataset[incurred_dataset$txn_type %in% c("Ma", "PMa"), "multiplier"] <- - maRev_multiplier + majRev_factor incurred_dataset[incurred_dataset$txn_type == "PMi", "multiplier"] <- - miRev_multiplier_atP + minRev_factor_atP incurred_dataset[incurred_dataset$txn_type == "Mi", "multiplier"] <- - miRev_multiplier_NatP + minRev_factor_notatP incurred_dataset } diff --git a/SPLICE/data-raw/test_data.R b/SPLICE/data-raw/test_data.R index 6d1078d..eb91ec9 100644 --- a/SPLICE/data-raw/test_data.R +++ b/SPLICE/data-raw/test_data.R @@ -5,14 +5,14 @@ ## v2 incurred program set.seed(20201006) test_claims <- SynthETIC::test_claims_object -major <- claim_maRev_no(test_claims) -major <- claim_maRev_time(test_claims, major) -major <- claim_maRev_size(major) +major <- claim_majRev_freq(test_claims) +major <- claim_majRev_time(test_claims, major) +major <- claim_majRev_size(major) # minor revisions -minor <- claim_miRev_no(test_claims) -minor <- claim_miRev_time(test_claims, minor) -minor <- claim_miRev_size(test_claims, major, minor) +minor <- claim_minRev_freq(test_claims) +minor <- claim_minRev_time(test_claims, minor) +minor <- claim_minRev_size(test_claims, major, minor) test <- claim_history(test_claims, major, minor) test_inflated <- claim_history(test_claims, major, minor, diff --git a/SPLICE/man/claim_history.Rd b/SPLICE/man/claim_history.Rd index c17b14f..85d3a29 100644 --- a/SPLICE/man/claim_history.Rd +++ b/SPLICE/man/claim_history.Rd @@ -6,8 +6,8 @@ \usage{ claim_history( claims, - maRev_list, - miRev_list, + majRev_list, + minRev_list, k1 = 0.95, k2 = 0.95, base_inflation_vector = NULL, @@ -19,11 +19,11 @@ claim_history( (other than those related to incurred loss), see \code{\link[SynthETIC]{claims}}.} -\item{maRev_list}{nested list of major revision histories, see -\code{\link{claim_maRev}}.} +\item{majRev_list}{nested list of major revision histories, see +\code{\link{claim_majRev}}.} -\item{miRev_list}{nested list of minor revision histories, see -\code{\link{claim_miRev}}.} +\item{minRev_list}{nested list of minor revision histories, see +\code{\link{claim_minRev}}.} \item{k1}{maximum amount of cumulative claims paid as a proportion of total incurred estimate for major revisions; between 0 and 1.} @@ -60,10 +60,10 @@ transactions (in the "right" continuous sense). \cr after each of the transactions (in the "right" continuous sense). \cr \code{incurred_right} \tab Case estimate of incurred loss immediately after each of the transactions (in the "right" continuous sense). \cr -\code{miRev} \tab A list containing full history of minor revisions (frequency, -time and revision size); \code{\link{claim_miRev}}. \cr -\code{maRev} \tab A list containing full history of major revisions (frequency, -time and revision size); see \code{\link{claim_maRev}}. +\code{minRev} \tab A list containing full history of minor revisions (frequency, +time and revision size); \code{\link{claim_minRev}}. \cr +\code{majRev} \tab A list containing full history of major revisions (frequency, +time and revision size); see \code{\link{claim_majRev}}. } and optionally (by setting \code{keep_all = TRUE}), @@ -90,7 +90,7 @@ adjustments: \item Major and minor revisions should not occur simultaneously. In the event that they do (which is only possible at the second last partial payment), the major revision takes precedence, and the minor revision be discarded. -This will be reflected in the \code{maRev} and \code{miRev} components of the output +This will be reflected in the \code{majRev} and \code{minRev} components of the output list. \item Estimates of incurred loss are specified to be computed in reverse order, and it is necessary that the total incurred estimate is always strictly diff --git a/SPLICE/man/claim_maRev.Rd b/SPLICE/man/claim_majRev.Rd similarity index 79% rename from SPLICE/man/claim_maRev.Rd rename to SPLICE/man/claim_majRev.Rd index 5bf713c..8cea5fe 100644 --- a/SPLICE/man/claim_maRev.Rd +++ b/SPLICE/man/claim_majRev.Rd @@ -1,13 +1,13 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/features_09_major_revisions.R -\name{claim_maRev} -\alias{claim_maRev} -\alias{claim_maRev_no} -\alias{claim_maRev_time} -\alias{claim_maRev_size} +\name{claim_majRev} +\alias{claim_majRev} +\alias{claim_majRev_freq} +\alias{claim_majRev_time} +\alias{claim_majRev_size} \title{Major Revisions of Incurred Loss} \usage{ -claim_maRev_no( +claim_majRev_freq( claims, rfun, paramfun, @@ -16,9 +16,9 @@ claim_maRev_no( ... ) -claim_maRev_time( +claim_majRev_time( claims, - maRev_list, + majRev_list, rfun, paramfun, claim_size_list = claims$claim_size_list, @@ -27,7 +27,7 @@ claim_maRev_time( ... ) -claim_maRev_size(maRev_list, rfun, paramfun, ...) +claim_majRev_size(majRev_list, rfun, paramfun, ...) } \arguments{ \item{claims}{an \code{\link[SynthETIC]{claims}} object containing all the @@ -36,10 +36,10 @@ simulated quantities (other than those related to incurred loss), see \item{rfun}{optional alternative random sampling function for: \itemize{ -\item \code{claim_maRev_no}: the number of major revisions; -\item \code{claim_maRev_time}: the epochs of major revisions measured from claim +\item \code{claim_majRev_freq}: the number of major revisions; +\item \code{claim_majRev_time}: the epochs of major revisions measured from claim notification; -\item \code{claim_maRev_size}: the sizes of the major revision multipliers. +\item \code{claim_majRev_size}: the sizes of the major revision multipliers. } See Details for default.} @@ -56,7 +56,7 @@ argument is provided); see \code{\link[SynthETIC]{claim_size}}.} \item{...}{other arguments/parameters to be passed onto \code{paramfun}.} -\item{maRev_list}{nested list of major revision histories (with non-empty +\item{majRev_list}{nested list of major revision histories (with non-empty revision frequencies).} \item{settlement_list}{list of settlement delays (not required if the @@ -72,15 +72,15 @@ sub-list is a list of information on major revisions of the \emph{j}th claim of occurrence period \emph{i}. The "unit list" (i.e. the smallest, innermost sub-list) contains the following components: \tabular{ll}{ -\code{maRev_no} \tab Number of major revisions of incurred loss -[\code{claim_maRev_no()}]. \cr -\code{maRev_time} \tab Time of major revisions (from claim notification) -[\code{claim_maRev_time()}]. \cr -\code{maRev_multiplier} \tab Major revision multiplier of \strong{incurred loss} -[\code{claim_maRev_size()}]. \cr -\code{maRev_atP} \tab An indicator, \code{1} if the last major revision occurs at the +\code{majRev_freq} \tab Number of major revisions of incurred loss +[\code{claim_majRev_freq()}]. \cr +\code{majRev_time} \tab Time of major revisions (from claim notification) +[\code{claim_majRev_time()}]. \cr +\code{majRev_factor} \tab Major revision multiplier of \strong{incurred loss} +[\code{claim_majRev_size()}]. \cr +\code{majRev_atP} \tab An indicator, \code{1} if the last major revision occurs at the time of the last major payment (i.e. second last payment), \code{0} otherwise -[\code{claim_maRev_time()}]. +[\code{claim_majRev_time()}]. } } \description{ @@ -88,13 +88,13 @@ A suite of functions that works together to simulate, in order, the (1) frequency, (2) time, and (3) size of major revisions of incurred loss, for each of the claims occurring in each of the periods. } -\section{Details - \code{claim_maRev_no} (Frequency)}{ +\section{Details - \code{claim_majRev_freq} (Frequency)}{ Let \emph{K} represent the number of major revisions associated with a particular claim. The notification of a claim is considered as a major revision, so all claims have at least 1 major revision (\eqn{K \ge 1}). -The default \code{maRev_no_function} specifies that no additional major revisions +The default \code{majRev_freq_function} specifies that no additional major revisions will occur for claims of size smaller than or equal to \code{claim_size_benchmark} (0.075 * \code{ref_claim} by default). For claims above this threshold, \tabular{ll}{ @@ -109,11 +109,11 @@ The idea is that major revisions are more likely for larger claims, and do not occur at all for the smallest claims. Note also that by default a claim may experience \strong{up to a maximum of 2 major revisions} in addition to the one at claim notification. This is taken as an assumption in the default -setting of \code{claim_maRev_size()}. If user decides to modify this assumption, +setting of \code{claim_majRev_size()}. If user decides to modify this assumption, they will need to take care of the part on the major revision size as well. } -\section{Details - \code{claim_maRev_time} (Time)}{ +\section{Details - \code{claim_majRev_time} (Time)}{ Let \eqn{\tau_k} represent the epoch of the \emph{k}th major revision (time measured from claim notification), \eqn{k = 1, ..., K}. As the notification of a claim is considered a major @@ -145,13 +145,13 @@ distribution with parameters } Note that when there is a major revision at the time of the second last -partial payment, \code{maRev_atP} (one of the output list components) will be set +partial payment, \code{majRev_atP} (one of the output list components) will be set to be 1. } -\section{Details - \code{claim_maRev_size} (Revision Multiplier)}{ +\section{Details - \code{claim_majRev_size} (Revision Multiplier)}{ As mentioned in -the frequency section ("Details - \code{claim_maRev_no}"), the default function +the frequency section ("Details - \code{claim_majRev_freq}"), the default function for the major revision multipliers assumes that there are only up to 2 major revisions (in addition to the one at claim notification) for all claims. @@ -174,22 +174,22 @@ This is dicussed in \code{\link{claim_history}}. is, a revision multiplier of 2.54 means that at the time of the major revision the incurred loss increases by a factor of 2.54. We highlight this as \strong{in the case of minor revisions, the multipliers will instead apply to -outstanding claim amounts}, see \code{\link{claim_miRev}}. +outstanding claim amounts}, see \code{\link{claim_minRev}}. } \examples{ set.seed(1) test_claims <- SynthETIC::test_claims_object -major <- claim_maRev_no(test_claims) +major <- claim_majRev_freq(test_claims) major[[1]][[1]] # the "unit list" for the first claim # update the timing information -major <- claim_maRev_time(test_claims, major) +major <- claim_majRev_time(test_claims, major) # observe how this has changed major[[1]][[1]] # update the revision multipliers -major <- claim_maRev_size(major) +major <- claim_majRev_size(major) # again observe how this has changed major[[1]][[1]] } diff --git a/SPLICE/man/claim_miRev.Rd b/SPLICE/man/claim_minRev.Rd similarity index 71% rename from SPLICE/man/claim_miRev.Rd rename to SPLICE/man/claim_minRev.Rd index 22380c9..2380a8b 100644 --- a/SPLICE/man/claim_miRev.Rd +++ b/SPLICE/man/claim_minRev.Rd @@ -1,40 +1,40 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/features_10_minor_revisions.R -\name{claim_miRev} -\alias{claim_miRev} -\alias{claim_miRev_no} -\alias{claim_miRev_time} -\alias{claim_miRev_size} +\name{claim_minRev} +\alias{claim_minRev} +\alias{claim_minRev_freq} +\alias{claim_minRev_time} +\alias{claim_minRev_size} \title{Minor Revisions of Outstanding Claim Payments} \usage{ -claim_miRev_no( +claim_minRev_freq( claims, prob_atP = 0.5, - rfun_NatP, - paramfun_NatP, + rfun_notatP, + paramfun_notatP, frequency_vector = claims$frequency_vector, settlement_list = claims$settlement_list, no_payments_list = claims$no_payments_list, ... ) -claim_miRev_time( +claim_minRev_time( claims, - miRev_list, - rfun_NatP, - paramfun_NatP, + minRev_list, + rfun_notatP, + paramfun_notatP, settlement_list = claims$settlement_list, payment_delay_list = claims$payment_delay_list, ... ) -claim_miRev_size( +claim_minRev_size( claims, - maRev_list, - miRev_list, + majRev_list, + minRev_list, rfun, paramfun_atP, - paramfun_NatP, + paramfun_notatP, settlement_list = claims$settlement_list, ... ) @@ -47,19 +47,19 @@ claim_miRev_size( \item{prob_atP}{(optional) probability that a minor revision will occur at the time of a partial payment; default value 0.5.} -\item{rfun_NatP}{optional alternative random sampling function for: +\item{rfun_notatP}{optional alternative random sampling function for: \itemize{ -\item \code{claim_miRev_no}: the number of minor revisions that occur at an epoch +\item \code{claim_minRev_freq}: the number of minor revisions that occur at an epoch other than those of partial payments; -\item \code{claim_miRev_time}: the epochs of such minor revisions measured from claim +\item \code{claim_minRev_time}: the epochs of such minor revisions measured from claim notification; -\item \code{claim_miRev_size}: the sizes of the minor revision multipliers (common for -\verb{_atP} and \verb{_NatP}, hence simply termed \code{rfun} in this case). +\item \code{claim_minRev_size}: the sizes of the minor revision multipliers (common for +\verb{_atP} and \verb{_notatP}, hence simply termed \code{rfun} in this case). } See Details for default.} -\item{paramfun_NatP}{parameters for the above random sampling function, +\item{paramfun_notatP}{parameters for the above random sampling function, as a function of other claim characteristics (e.g. \code{lambda} as a function of \code{claim_size} for an \code{rpois} simulation); see Examples.} @@ -76,21 +76,21 @@ the \code{claims} argument is provided); see \item{...}{other arguments/parameters to be passed onto \code{paramfun}.} -\item{miRev_list}{nested list of minor revision histories (with non-empty +\item{minRev_list}{nested list of minor revision histories (with non-empty revision frequencies).} \item{payment_delay_list}{(compound) list of inter partial delays (not required if the \code{claims} argument is provided); see \code{\link[SynthETIC]{claim_payment_delay}}.} -\item{maRev_list}{nested list of major revision histories (with non-empty +\item{majRev_list}{nested list of major revision histories (with non-empty revision frequencies).} \item{rfun}{optional alternative random sampling function for the sizes of -the minor revision multipliers (common for \verb{_atP} and \verb{_NatP}, hence simply +the minor revision multipliers (common for \verb{_atP} and \verb{_notatP}, hence simply termed \code{rfun} in this case).} -\item{paramfun_atP}{parameters for \code{rfun} in \code{claim_miRev_size()} for minor +\item{paramfun_atP}{parameters for \code{rfun} in \code{claim_minRev_size()} for minor revisions that occur at the time of a partial payment.} } \value{ @@ -99,23 +99,23 @@ sub-list is a list of information on minor revisions of the \emph{j}th claim of occurrence period \emph{i}. The "unit list" (i.e. the smallest, innermost sub-list) contains the following components: \tabular{ll}{ -\code{miRev_atP} \tab A vector of indicators showing whether there is a minor -revision at each partial payment [\code{claim_miRev_no()}]. \cr -\code{miRev_no_atP} \tab Number of minor revisions that occur simultaneously with -a partial payment, numerically equals to the sum of \code{miRev_atP} -[\code{claim_miRev_no()}]. \cr -\code{miRev_no_NatP} \tab Number of minor revisions that do not occur with a -partial payment [\code{claim_miRev_no()}]. \cr -\code{miRev_time_atP} \tab Time of minor revisions that occur simultaneously with +\code{minRev_atP} \tab A vector of indicators showing whether there is a minor +revision at each partial payment [\code{claim_minRev_freq()}]. \cr +\code{minRev_freq_atP} \tab Number of minor revisions that occur simultaneously with +a partial payment, numerically equals to the sum of \code{minRev_atP} +[\code{claim_minRev_freq()}]. \cr +\code{minRev_freq_notatP} \tab Number of minor revisions that do not occur with a +partial payment [\code{claim_minRev_freq()}]. \cr +\code{minRev_time_atP} \tab Time of minor revisions that occur simultaneously with a partial payment (time measured from claim notification) -[\code{claim_miRev_time()}]. \cr -\code{miRev_time_NatP} \tab Time of minor revisions that do \emph{not} occur +[\code{claim_minRev_time()}]. \cr +\code{minRev_time_notatP} \tab Time of minor revisions that do \emph{not} occur simultaneously with a partial payment (time measured from claim notification) -[\code{claim_miRev_time()}]. \cr -\code{miRev_multiplier_atP} \tab Minor revision multipliers of \strong{outstanding claim -payments} for revisions at partial payments [\code{claim_miRev_size()}]. \cr -\code{miRev_multiplier_NatP} \tab Minor revision multipliers of \strong{outstanding claim -payments} for revisions at any other times [\code{claim_miRev_size()}]. \cr +[\code{claim_minRev_time()}]. \cr +\code{minRev_factor_atP} \tab Minor revision multipliers of \strong{outstanding claim +payments} for revisions at partial payments [\code{claim_minRev_size()}]. \cr +\code{minRev_factor_notatP} \tab Minor revision multipliers of \strong{outstanding claim +payments} for revisions at any other times [\code{claim_minRev_size()}]. \cr } } \description{ @@ -125,9 +125,9 @@ claim payments, for each of the claims occurring in each of the periods. We separate the case of minor revisions that occur simultaneously with a partial payment (denoted \verb{_atP}), and the ones that do not coincide with a -payment (denoted \verb{_NatP}). +payment (denoted \verb{_notatP}). } -\section{Details - \code{claim_miRev_no} (Frequency)}{ +\section{Details - \code{claim_minRev_freq} (Frequency)}{ Minor revisions may occur simultaneously with a partial payment, or at any other time. @@ -139,14 +139,14 @@ simultaneous) minor revisions from a geometric distribution with mean = \eqn{min(3, setldel / 4)}. One can modify the above sampling distributions by plugging in their own -\code{prob_atP} parameter and \code{rfun_NatP} function, where the former dictates +\code{prob_atP} parameter and \code{rfun_notatP} function, where the former dictates the probability of incurring a minor revision at the time of a payment, and the latter simulates and returns the number of minor revisions at any other points in time, with possible dependence on the settlement delay of the claim and/or other claim characteristics. } -\section{Details - \code{claim_miRev_time} (Time)}{ +\section{Details - \code{claim_minRev_time} (Time)}{ For minor revisions that occur simultaneously with a partial payment, the revision times simply coincide with the epochs of the relevant partial payments. @@ -156,19 +156,19 @@ times are sampled from a uniform distribution with parameters \code{min} \eqn{= settlement_delay / 6} and \code{max} \eqn{= settlement_delay}. One can modify the above sampling distribution by plugging in their own -\code{rfun_NatP} and \code{paramfun_NatP} in \code{claim_miRev_time()}, which together +\code{rfun_notatP} and \code{paramfun_notatP} in \code{claim_minRev_time()}, which together simulate the epochs of minor revisions that do not coincide with a payment, with possible dependence on the settlement delay of the claim and/or other claim characteristics (see Examples). } -\section{Details - \code{claim_miRev_size} (Revision Multiplier)}{ +\section{Details - \code{claim_minRev_size} (Revision Multiplier)}{ The sampling distribution for minor revision multipliers is the same for both revisions that occur with and without a partial payment. In the default setting, we incorporate sampling dependence on the delay from notification to settlement (\code{setldel}), the delay from notification to the subject minor revisions -(\code{miRev_time}), and the history of major revisions (in particular, the time +(\code{minRev_time}), and the history of major revisions (in particular, the time of the second major revision). Let \eqn{\tau} denote the delay from notification to the epoch of the minor @@ -205,21 +205,21 @@ increases by a factor of 2.54. \examples{ set.seed(1) test_claims <- SynthETIC::test_claims_object -minor <- claim_miRev_no(test_claims) +minor <- claim_minRev_freq(test_claims) minor[[1]][[1]] # the "unit list" for the first claim # update the timing information -minor <- claim_miRev_time(test_claims, minor) +minor <- claim_minRev_time(test_claims, minor) # observe how this has changed minor[[1]][[1]] # with an alternative sampling distribution e.g. triangular -miRev_time_NatP <- function(n, setldel) { +minRev_time_notatP <- function(n, setldel) { sort(rtri(n, min = setldel/6, max = setldel, mode = setldel)) } -minor_2 <- claim_miRev_time(test_claims, minor, miRev_time_NatP) +minor_2 <- claim_minRev_time(test_claims, minor, minRev_time_notatP) # update the revision multipliers (need to generate "major" first) -# minor <- claim_miRev_size(test_claims, major, minor) +# minor <- claim_minRev_size(test_claims, major, minor) } \seealso{ \code{\link[SynthETIC]{claims}} diff --git a/SPLICE/man/test_incurred_dataset.Rd b/SPLICE/man/test_incurred_dataset.Rd index 30f3e08..b69b4c3 100644 --- a/SPLICE/man/test_incurred_dataset.Rd +++ b/SPLICE/man/test_incurred_dataset.Rd @@ -25,7 +25,10 @@ revision, "Mi" for minor revision, "P" for payment, \item{cumpaid}{double; cumulative claim paid \strong{after} the transaction.} \item{multiplier}{revision multipliers (subject to further constraints documented in \code{\link{claim_history}}), \code{NA} for -transactions that do not involve a revision.} +transactions that do not involve a revision. Note that +major revision multipliers apply to the incurred losses, +while minor revision multipliers apply to the outstanding +claim payments.} } } \usage{ diff --git a/SPLICE/vignettes/SPLICE-demo.Rmd b/SPLICE/vignettes/SPLICE-demo.Rmd index c96c2f7..58a7f4a 100644 --- a/SPLICE/vignettes/SPLICE-demo.Rmd +++ b/SPLICE/vignettes/SPLICE-demo.Rmd @@ -20,8 +20,8 @@ This vignette aims to illustrate how the `SPLICE` package can be used to generat `SPLICE` enables the modelling of incurred loss estimates, via the following three modules: -1. [*Major Revision Histories*](#maRev): [Frequency](#maRev_no), [Time](#maRev_time) and [Size](#maRev_size) of major revisions of incurred losses -2. [*Minor Revision Histories*](#miRev): [Frequency](#miRev_no), [Time](#miRev_time) and [Size](#miRev_size) of minor revisions of incurred losses +1. [*Major Revision Histories*](#majRev): [Frequency](#majRev_freq), [Time](#majRev_time) and [Size](#majRev_size) of major revisions of incurred losses +2. [*Minor Revision Histories*](#minRev): [Frequency](#minRev_freq), [Time](#minRev_time) and [Size](#minRev_size) of minor revisions of incurred losses 3. [*Development of Case Estimates*](#claim_history): Consolidation of payments and incurred revisions, including optional adjustment for inflation in the case estimates. Set Up @@ -46,18 +46,18 @@ Sections 1-3 introduce the three modelling steps in detail and include extensive ```{r} # major revisions -major <- claim_maRev_no(test_claims) -major <- claim_maRev_time(test_claims, major) -major <- claim_maRev_size(major) +major <- claim_majRev_freq(test_claims) +major <- claim_majRev_time(test_claims, major) +major <- claim_majRev_size(major) # minor revisions -minor <- claim_miRev_no(test_claims) -minor <- claim_miRev_time(test_claims, minor) -minor <- claim_miRev_size(test_claims, major, minor) +minor <- claim_minRev_freq(test_claims) +minor <- claim_minRev_time(test_claims, minor) +minor <- claim_minRev_size(test_claims, major, minor) # development of case estimates test <- claim_history(test_claims, major, minor) -test_inflated <- claim_history(test_claims, major, minor, inflated = TRUE, +test_inflated <- claim_history(test_claims, major, minor, base_inflation_vector = rep((1 + 0.02)^(1/4) - 1, times = 80)) # transactional data @@ -68,28 +68,28 @@ test_incurred_dataset_inflated <- generate_incurred_dataset(test_claims, test_in incurred_inflated <- output_incurred(test_inflated, incremental = FALSE) ``` -1. Major Revisions {#maRev} +1. Major Revisions {#majRev} --- This section introduces a suite of functions that works together to simulate, in sequential order, the (1) frequency, (2) time, and (3) size of major revisions of incurred loss, for each of the claims occurring in each of the occurrence periods. -In particular, `claim_maRev_no()` sets up the structure of the major revisions: a nested list such that the *j*th component of the *i*th sub-list is a list of information on major revisions of the *j*th claim of occurrence period *i*. The "unit list" (i.e. the smallest, innermost sub-list) contains the following components: +In particular, `claim_majRev_freq()` sets up the structure of the major revisions: a nested list such that the *j*th component of the *i*th sub-list is a list of information on major revisions of the *j*th claim of occurrence period *i*. The "unit list" (i.e. the smallest, innermost sub-list) contains the following components: ------------------------------------------------------------------------------- Name Description ----------------- ------------------------------------------------------------ -`maRev_no` Number of major revisions of incurred loss; see [`claim_maRev_no()`](#maRev_no) +`majRev_freq` Number of major revisions of incurred loss; see [`claim_majRev_freq()`](#majRev_freq) -`maRev_time` Time of major revisions (from claim notification); see [`claim_maRev_time()`](#maRev_time) +`majRev_time` Time of major revisions (from claim notification); see [`claim_majRev_time()`](#majRev_time) -`maRev_multiplier` Major revision multiplier of **incurred loss**; see [`claim_maRev_size()`](#maRev_size) +`majRev_factor` Major revision multiplier of **incurred loss**; see [`claim_majRev_size()`](#majRev_size) -`maRev_atP` An indicator, `1` if the last major revision occurs at the time of the last major payment (i.e. second last payment), `0` otherwise; see [`claim_maRev_time()`](#maRev_time) +`majRev_atP` An indicator, `1` if the last major revision occurs at the time of the last major payment (i.e. second last payment), `0` otherwise; see [`claim_majRev_time()`](#majRev_time) ------------------------------------------------------------------------------- -## 1.1 Frequency of Major Revisions {#maRev_no} -`claim_maRev_no()` generates the number of major revisions associated with a particular claim, from a user-defined random generation function. Users are free to choose *any* distribution (through the argument `rfun`), whether it be a pre-defined distribution in `R`, or more advanced ones from packages, or a proper user-defined function, to better match their own claim experience. +## 1.1 Frequency of Major Revisions {#majRev_freq} +`claim_majRev_freq()` generates the number of major revisions associated with a particular claim, from a user-defined random generation function. Users are free to choose *any* distribution (through the argument `rfun`), whether it be a pre-defined distribution in `R`, or more advanced ones from packages, or a proper user-defined function, to better match their own claim experience. Let $K$ represent the number of major revisions associated with a particular claim. The notification of a claim is considered as a major revision, so all claims have at least 1 major revision ($K \ge 1$). @@ -101,14 +101,14 @@ One possible sampling distribution for this is the zero-truncated Poisson distri ```{r} ## paramfun input # lambda as a function of claim size -no_maRev_param <- function(claim_size) { - maRevNo_mean <- pmax(1, log(claim_size / 15000) - 2) - c(lambda = maRevNo_mean) +no_majRev_param <- function(claim_size) { + majRevNo_mean <- pmax(1, log(claim_size / 15000) - 2) + c(lambda = majRevNo_mean) } ## implementation and output -major_test <- claim_maRev_no( - test_claims, rfun = actuar::rztpois, paramfun = no_maRev_param) +major_test <- claim_majRev_freq( + test_claims, rfun = actuar::rztpois, paramfun = no_majRev_param) # show the distribution of number of major revisions table(unlist(major_test)) ``` @@ -116,26 +116,26 @@ table(unlist(major_test)) ### Example 1.1.2 Additional dependencies {#ex1.1.2} Like [`SynthETIC`](https://CRAN.R-project.org/package=SynthETIC), users of `SPLICE` are able to add further dependencies in their simulation. This is illustrated in the example below. -Suppose we would like to add the additional dependence of `claim_maRev_no` (number of major revisions) on the number of partial payments of the claim - which is not natively included in `SPLICE` default setting. For example, let's consider the following parameter function: +Suppose we would like to add the additional dependence of `claim_majRev_freq` (number of major revisions) on the number of partial payments of the claim - which is not natively included in `SPLICE` default setting. For example, let's consider the following parameter function: ```{r} ## paramfun input # an extended parameter function -maRevNo_param <- function(claim_size, no_payment) { - maRevNo_mean <- pmax(0, log(claim_size / 1500000)) + no_payment / 10 - c(lambda = maRevNo_mean) +majRevNo_param <- function(claim_size, no_payment) { + majRevNo_mean <- pmax(0, log(claim_size / 1500000)) + no_payment / 10 + c(lambda = majRevNo_mean) } ``` -As this parameter function is dependent on `no_payment`, it should not come at a surprise that we need to supply the number of partial payments when calling `claim_maRev_no()`. We need to make sure that the argument names are matched exactly (`no_payment` in this example) and that the input is specified as a vector of simulated quantities (not a list). +As this parameter function is dependent on `no_payment`, it should not come at a surprise that we need to supply the number of partial payments when calling `claim_majRev_freq()`. We need to make sure that the argument names are matched exactly (`no_payment` in this example) and that the input is specified as a vector of simulated quantities (not a list). ```{r} ## implementation and output no_payments_vect <- unlist(test_claims$no_payments_list) # sample the frequency of major revisions from zero-truncated Poisson # with parameters above -major_test <- claim_maRev_no( - test_claims, rfun = actuar::rztpois, paramfun = maRevNo_param, +major_test <- claim_majRev_freq( + test_claims, rfun = actuar::rztpois, paramfun = majRevNo_param, no_payment = no_payments_vect) # show the distribution of number of major revisions table(unlist(major_test)) @@ -143,14 +143,14 @@ table(unlist(major_test)) ### Example 1.1.3 Default implementation {#ex1.1.3} -The default `claim_maRev_no()` assumes that no additional major revisions will occur for claims of size smaller than or equal to a `claim_size_benchmark`. For claims above this threshold, a maximum of 3 major revisions can occur and the larger the claim size, the more likely there will be more major revisions. +The default `claim_majRev_freq()` assumes that no additional major revisions will occur for claims of size smaller than or equal to a `claim_size_benchmark`. For claims above this threshold, a maximum of 3 major revisions can occur and the larger the claim size, the more likely there will be more major revisions. **There is no need to specify a sampling distribution if the user is happy with the default specification.** This example is mainly to demonstrate how the default function works, and at the same time, to provide an example that one can modify to input a random sampling distribution of their choosing. ```{r} ## input # package default function for frequency of major revisions -dflt.maRev_no_function <- function( +dflt.majRev_freq_function <- function( n, claim_size, claim_size_benchmark = 0.075 * ref_claim) { # construct the range indicator @@ -158,7 +158,7 @@ dflt.maRev_no_function <- function( # if claim_size <= claim_size_benchmark # "small" claims assumed to have no major revisions except at notification - no_maRev <- rep(1, n) + no_majRev <- rep(1, n) # if claim_size is above the benchmark # probability of 2 major revisions, increases with claim size Pr2 <- 0.1 + 0.3 * @@ -168,21 +168,21 @@ dflt.maRev_no_function <- function( min(1, max(0, claim_size[test] - 0.25 * ref_claim)/(0.75 * ref_claim)) # probability of 1 major revision i.e. only one at claim notification Pr1 <- 1 - Pr2 - Pr3 - no_maRev[test] <- sample( + no_majRev[test] <- sample( c(1, 2, 3), size = sum(test), replace = T, prob = c(Pr1, Pr2, Pr3)) - no_maRev + no_majRev } ``` -Since the random function directly takes `claim_size` as an input, no additional parameterisation is required (unlike in Examples [1](#ex1.1.1) and [2](#ex1.1.2), where we first need a `paramfun` that turns the `claim_size` into the `lambda` parameter required in a zero-truncated Poisson distribution). Here we can simply run `claim_maRev_no()` without inputting a `paramfun`. +Since the random function directly takes `claim_size` as an input, no additional parameterisation is required (unlike in Examples [1](#ex1.1.1) and [2](#ex1.1.2), where we first need a `paramfun` that turns the `claim_size` into the `lambda` parameter required in a zero-truncated Poisson distribution). Here we can simply run `claim_majRev_freq()` without inputting a `paramfun`. ```{r} ## implementation and output # simulate the number of major revisions -major <- claim_maRev_no( +major <- claim_majRev_freq( claims = test_claims, - rfun = dflt.maRev_no_function + rfun = dflt.majRev_freq_function ) # show the distribution of number of major revisions @@ -193,64 +193,68 @@ table(unlist(major)) major[[1]][[1]] ``` -Note that `SPLICE` by default assumes the (removable) dependence of frequency of major revisions on claim size, hence there is no need to supply any additional arguments to `claim_maRev_no()`, unlike in [Example 1.1.2](#ex1.1.2). +Note that `SPLICE` by default assumes the (removable) dependence of frequency of major revisions on claim size, hence there is no need to supply any additional arguments to `claim_majRev_freq()`, unlike in [Example 1.1.2](#ex1.1.2). If one would like to keep the structure of the default sampling function but modify the benchmark value, they may do so via e.g. ```{r} -major_test <- claim_maRev_no( +major_test <- claim_majRev_freq( claims = test_claims, claim_size_benchmark = 30000 ) ``` -## 1.2 Time of Major Revisions {#maRev_time} -`claim_maRev_time()` generates the epochs of the major revisions (time measured from claim notification). It takes a very similar structure as [`claim_maRev_no()`](#maRev_no), allowing users to input a sampling distribution via `rfun` and a parameter function which relates the parameter(s) of the distribution to selected claim characteristics. +## 1.2 Time of Major Revisions {#majRev_time} +`claim_majRev_time()` generates the epochs of the major revisions (time measured from claim notification). It takes a very similar structure as [`claim_majRev_freq()`](#majRev_freq), allowing users to input a sampling distribution via `rfun` and a parameter function which relates the parameter(s) of the distribution to selected claim characteristics. Let $\tau_k$ represent the epoch of the $k$th major revision (time measured from claim notification), $k = 1, ..., K$. As the notification of a claim is considered a major revision itself, we have $\tau_1 = 0$ for all claims. ### Example 1.2.1 Modified uniform distribution {#ex1.2.1} One simplistic option is to use a modified version of the uniform distribution (modified such that the first major revision always occurs at time 0 i.e. at claim notification). -`maRev_time_paramfun` in the example below specifies the `min` and `max` parameters for an individual claim as a function of `setldel` (settlement delay). Note that `SPLICE` by default assumes the (removable) dependence of timing of major revisions on claim size, settlement delay, and the partial payment times. Thanks to that, there is no need to supply any additional arguments to `claim_maRev_time()`. Users who wish to add further dependencies to the simulator can refer to [Example 1.1.2](#ex1.1.2). +`majRev_time_paramfun` in the example below specifies the `min` and `max` parameters for an individual claim as a function of `setldel` (settlement delay). Note that `SPLICE` by default assumes the (removable) dependence of timing of major revisions on claim size, settlement delay, and the partial payment times. Thanks to that, there is no need to supply any additional arguments to `claim_majRev_time()`. Users who wish to add further dependencies to the simulator can refer to [Example 1.1.2](#ex1.1.2). ```{r} ## input -maRev_time_rfun <- function(n, min, max) { +majRev_time_rfun <- function(n, min, max) { # n = number of major revisions of an individual claim - maRev_time <- vector(length = n) - maRev_time[1] <- 0 # first major revision at notification + majRev_time <- vector(length = n) + majRev_time[1] <- 0 # first major revision at notification if (n > 1) { - maRev_time[2:n] <- sort(stats::runif(n - 1, min, max)) + majRev_time[2:n] <- sort(stats::runif(n - 1, min, max)) } - return(maRev_time) + return(majRev_time) } -maRev_time_paramfun <- function(setldel, ...) { +majRev_time_paramfun <- function(setldel, ...) { + # setldel = settlement delay c(min = setldel/3, max = setldel) } ## implementation and output -major_test <- claim_maRev_time( - test_claims, major, rfun = maRev_time_rfun, paramfun = maRev_time_paramfun +major_test <- claim_majRev_time( + test_claims, major, rfun = majRev_time_rfun, paramfun = majRev_time_paramfun ) major_test[[1]][[1]] ``` ### Example 1.2.2 Default implementation {#ex1.2.2} -The default implementation takes into account much complexity from the real-life claim process. It assumes that with a positive probability, the last major revision for a claim may coincide with the second last partial payment (which is usually the major settlement payment). In such cases, `maRev_atP` would be set to 1 indicating that there is a major revision simultaneous with the penultimate payment. +The default implementation takes into account much complexity from the real-life claim process. It assumes that with a positive probability, the last major revision for a claim may coincide with the second last partial payment (which is usually the major settlement payment). In such cases, `majRev_atP` would be set to 1 indicating that there is a major revision simultaneous with the penultimate payment. The epochs of the remaining major revisions are sampled from triangular distributions with maximum density at the earlier part of the claim's lifetime. ```{r} ## package default function for time of major revisions -dflt.maRev_time_function <- function( +dflt.majRev_time_function <- function( + # n = number of major revisions + # setldel = settlement delay + # penultimate_delay = time from claim notification to second last payment n, claim_size, setldel, penultimate_delay) { - maRev_time <- rep(NA, times = n) + majRev_time <- rep(NA, times = n) # first revision at notification - maRev_time[1] <- 0 + majRev_time[1] <- 0 if (n > 1) { # if the claim has multiple major revisions # the probability of having the last revision exactly at the second last partial payment @@ -261,17 +265,17 @@ dflt.maRev_time_function <- function( # does the last revision occur at the second last partial payment? if (at_second_last_pmt == 0) { # -> no revision at second last payment - maRev_time[2:n] <- sort(rtri(n - 1, min = setldel/3, max = setldel, mode = setldel/3)) + majRev_time[2:n] <- sort(rtri(n - 1, min = setldel/3, max = setldel, mode = setldel/3)) } else { # -> yes, revision at second last payment - maRev_time[n] <- penultimate_delay + majRev_time[n] <- penultimate_delay if (n > 2) { - maRev_time[2:(n-1)] <- sort( - rtri(n - 2, min = maRev_time[n]/3, max = maRev_time[n], mode = maRev_time[n]/3)) + majRev_time[2:(n-1)] <- sort( + rtri(n - 2, min = majRev_time[n]/3, max = majRev_time[n], mode = majRev_time[n]/3)) } } } - maRev_time + majRev_time } ``` @@ -280,7 +284,7 @@ Note that `rtri` is a function to generate random numbers from a triangular dist `claim_size` and `setldel` are both directly accessible claim characteristics, but we need `paramfun` to take care of the computation of `penultimate_delay` as a function of the partial payment delays that we can access. ```{r} -dflt.maRev_time_paramfun <- function(payment_delays, ...) { +dflt.majRev_time_paramfun <- function(payment_delays, ...) { c(penultimate_delay = sum(payment_delays[1:length(payment_delays) - 1]), ...) } @@ -288,11 +292,11 @@ dflt.maRev_time_paramfun <- function(payment_delays, ...) { ```{r} ## implementation and output -major <- claim_maRev_time( +major <- claim_majRev_time( claims = test_claims, - maRev_list = major, # we will update the previous major list - rfun = dflt.maRev_time_function, - paramfun = dflt.maRev_time_paramfun + majRev_list = major, # we will update the previous major list + rfun = dflt.majRev_time_function, + paramfun = dflt.majRev_time_paramfun ) # view the major revision history of the first claim in the 1st occurrence period @@ -303,13 +307,13 @@ major[[1]][[1]] The above sampling distribution has been included as the default. **There is no need to reproduce the above code if the user is happy with this default distribution.** A simple equivalent to the above code is just ```{r, eval=FALSE} -major <- claim_maRev_time(claims = test_claims, maRev_list = major) +major <- claim_majRev_time(claims = test_claims, majRev_list = major) ``` This example is here only to demonstrate how the default function operates. -## 1.3 Size of Major Revisions {#maRev_size} -`claim_maRev_size()` generates the sizes of the major revisions. The major revision multipliers apply to the incurred loss estimates, that is, a revision multiplier of 2.54 means that at the time of the major revision the incurred loss increases by a factor of 2.54. We highlight this as in the case of minor revisions, the multipliers will instead apply to outstanding claim amounts, see [claim_miRev_size()](#miRev_size). +## 1.3 Size of Major Revisions {#majRev_size} +`claim_majRev_size()` generates the sizes of the major revisions. The major revision multipliers apply to the incurred loss estimates, that is, a revision multiplier of 2.54 means that at the time of the major revision the incurred loss increases by a factor of 2.54. We highlight this as in the case of minor revisions, the multipliers will instead apply to outstanding claim amounts, see [claim_minRev_size()](#minRev_size). The reason for this differentiation is that major revisions represent a total change of perspective on ultimate incurred cost, whereas minor revisions respond more to matters of detail, causing the case estimator to apply a revision factor to the estimate of outstanding payments. @@ -318,33 +322,33 @@ Suppose that we believe the major revision multipliers follow a gamma distributi ```{r} ## input -maRev_size_rfun <- function(n, shape, rate) { +majRev_size_rfun <- function(n, shape, rate) { # n = number of major revisions of an individual claim - maRev_size <- vector(length = n) - maRev_size[1] <- 1 # first major revision at notification + majRev_size <- vector(length = n) + majRev_size[1] <- 1 # first major revision at notification if (n > 1) { - maRev_size[2:n] <- stats::rgamma(n - 1, shape, rate) + majRev_size[2:n] <- stats::rgamma(n - 1, shape, rate) } - maRev_size + majRev_size } -maRev_size_paramfun <- function(claim_size) { +majRev_size_paramfun <- function(claim_size) { shape <- max(log(claim_size / 5000), 1) rate <- 10 / shape c(shape = shape, rate = rate) } ``` -The [default implementation of `claim_maRev_size()`](#ex1.3.2) assumes no further dependencies on claim characteristics. Hence we need to supply `claim_size` as an additional argument when running `claim_maRev_size()` when the above set up. +The [default implementation of `claim_majRev_size()`](#ex1.3.2) assumes no further dependencies on claim characteristics. Hence we need to supply `claim_size` as an additional argument when running `claim_majRev_size()` when the above set up. ```{r} ## implementation and output claim_size_vect <- unlist(test_claims$claim_size_list) -major_test <- claim_maRev_size( - maRev_list = major, - rfun = maRev_size_rfun, - paramfun = maRev_size_paramfun, +major_test <- claim_majRev_size( + majRev_list = major, + rfun = majRev_size_rfun, + paramfun = majRev_size_paramfun, claim_size = claim_size_vect ) @@ -359,27 +363,27 @@ The default implementation samples the major revision multipliers from lognormal ```{r} ## input # package default function for sizes of major revisions -dflt.maRev_size_function <- function(n) { - maRev_multiplier <- rep(NA, times = n) +dflt.majRev_size_function <- function(n) { + majRev_factor <- rep(NA, times = n) # set revision size = 1 for first revision (i.e. the one at notification) - maRev_multiplier[1] <- 1 + majRev_factor[1] <- 1 if (n > 1) { # if the claim has multiple major revisions - maRev_multiplier[2] <- stats::rlnorm(n = 1, meanlog = 1.8, sdlog = 0.2) + majRev_factor[2] <- stats::rlnorm(n = 1, meanlog = 1.8, sdlog = 0.2) if (n > 2) { # the last revision factor depends on what happened at the second major revision - mu <- 1 + 0.07 * (6 - maRev_multiplier[2]) - maRev_multiplier[3] <- stats::rlnorm(n = 1, meanlog = mu, sdlog = 0.1) + mu <- 1 + 0.07 * (6 - majRev_factor[2]) + majRev_factor[3] <- stats::rlnorm(n = 1, meanlog = mu, sdlog = 0.1) } } - maRev_multiplier + majRev_factor } ## implementation and output -major <- claim_maRev_size( - maRev_list = major, - rfun = dflt.maRev_size_function +major <- claim_majRev_size( + majRev_list = major, + rfun = dflt.majRev_size_function ) # view the major revision history of the first claim in the 1st occurrence period @@ -389,55 +393,56 @@ major[[1]][[1]] For this particular claim record, we observe 3 major revisions: -- First one at claim notification with revision size $g_1 =$ `r major[[1]][[1]]$maRev_multiplier[1]` (note that the notification of a claim is considered as a major revision, so all claims have at least 1 major revision); -- Second one at delay $\tau_2 =$ `r major[[1]][[1]]$maRev_time[2]` from notification and has revision size of $g_2 =$ `r major[[1]][[1]]$maRev_multiplier[2]` on the incurred loss; -- Third one at delay $\tau_3 =$ `r major[[1]][[1]]$maRev_time[3]` from notification and has revision size of $g_3 =$ `r major[[1]][[1]]$maRev_multiplier[3]` on the incurred loss. As commented in the paper, a claim may experience up to two major revisions in addition to the initial one, but the second, if it occurs at all, is likely to be smaller than the first. +- First one at claim notification with revision size $g_1 =$ `r major[[1]][[1]]$majRev_factor[1]` (note that the notification of a claim is considered as a major revision, so all claims have at least 1 major revision); +- Second one at delay $\tau_2 =$ `r major[[1]][[1]]$majRev_time[2]` from notification and has revision size of $g_2 =$ `r major[[1]][[1]]$majRev_factor[2]` on the incurred loss; +- Third one at delay $\tau_3 =$ `r major[[1]][[1]]$majRev_time[3]` from notification and has revision size of $g_3 =$ `r major[[1]][[1]]$majRev_factor[3]` on the incurred loss. As commented in the paper, a claim may experience up to two major revisions in addition to the initial one, but the second, if it occurs at all, is likely to be smaller than the first. -2. Minor Revisions {#miRev} +2. Minor Revisions {#minRev} --- -Compared to the major revisions, the simulation of minor revisions may require slightly more complicated input specification, as we need to separate the case of minor revisions that occur simultaneously with a partial payment (`miRev_atP`) and the ones that do not. +Compared to the major revisions, the simulation of minor revisions may require slightly more complicated input specification, as we need to separate the case of minor revisions that occur simultaneously with a partial payment (`minRev_atP`) and the ones that do not. -Similar to the case of major revisions, the suite of functions under this heading run in sequential order to simulate the (1) frequency, (2) time, and (3) size of minor revisions of outstanding claim payments, for each of the claims occurring in each of the occurrence periods. In particular, `claim_miRev_no()` sets up the structure of the minor revisions: a nested list such that the *j*th component of the *i*th sub-list is a list of information on minor revisions of the *j*th claim of occurrence period *i*. The "unit list" contains the following components: +Similar to the case of major revisions, the suite of functions under this heading run in sequential order to simulate the (1) frequency, (2) time, and (3) size of minor revisions of outstanding claim payments, for each of the claims occurring in each of the occurrence periods. In particular, `claim_minRev_freq()` sets up the structure of the minor revisions: a nested list such that the *j*th component of the *i*th sub-list is a list of information on minor revisions of the *j*th claim of occurrence period *i*. The "unit list" contains the following components: ------------------------------------------------------------------------------- Name Description ----------------------- ------------------------------------------------------ -`miRev_atP` A logical vector indicating whether there is a minor revision at each partial payment; see [`claim_miRev_no()`](#miRev_no) +`minRev_atP` A logical vector indicating whether there is a minor revision at each partial payment; see [`claim_minRev_freq()`](#minRev_freq) -`miRev_no_atP` -(`miRev_no_NatP`) Number of minor revisions that occur (or do not occur) simultaneously with a partial payment. `miRev_no_atP` is numerically equal to the sum of `miRev_atP` +`minRev_freq_atP` +(`minRev_freq_notatP`) Number of minor revisions that occur (or do not occur) simultaneously with a partial payment. `minRev_freq_atP` is numerically equal to the sum of `minRev_atP` -`miRev_time_atP`, -(`miRev_time_NatP`) Time of minor revisions that occur (or do not occur) simultaneously with a partial payment (time measured from claim notification); see [`claim_miRev_time()`](#miRev_time) +`minRev_time_atP`, +(`minRev_time_notatP`) Time of minor revisions that occur (or do not occur) simultaneously with a partial payment (time measured from claim notification); see [`claim_minRev_time()`](#minRev_time) -`miRev_multiplier_atP`, -(`miRev_multiplier_NatP`) Minor revision multiplier of **outstanding claim payments** for revisions at partial payments and at any other times, respectively; see [`claim_miRev_size()`](#miRev_size) +`minRev_factor_atP`, +(`minRev_factor_notatP`) Minor revision multiplier of **outstanding claim payments** for revisions at partial payments and at any other times, respectively; see [`claim_minRev_size()`](#minRev_size) ------------------------------------------------------------------------------- -## 2.1 Frequency of Minor Revisions {#miRev_no} +## 2.1 Frequency of Minor Revisions {#minRev_freq} Minor revisions may occur simultaneously with a partial payment, or at any other time: * For the former case, we sample the occurrence of minor revisions as Bernoulli random variables with a probability parameter `prob_atP` (defaults to 1/2); -* For the latter case, users have the option to specify an `rfun_NatP` for simulation and a `paramfun_NatP` to input the parameters for the sampling distribution, much in the same way as [the analogous case of major revisions](#maRev_no). The default implementation assumes a geometric distribution with mean = `min(3, setldel / 4)` and is illustrated below. +* For the latter case, users have the option to specify an `rfun_notatP` for simulation and a `paramfun_notatP` to input the parameters for the sampling distribution, much in the same way as [the analogous case of major revisions](#majRev_freq). The default implementation assumes a geometric distribution with mean = `min(3, setldel / 4)` and is illustrated below. ### Example 2.1.1 Default implementation {#ex2.1.1} ```{r} ## input # package default function for frequency of minor revisions at partial payments -dflt.miRev_no_NatP_function <- function(n, setldel) { - miRev_no_NatP <- stats::rgeom(n, prob = 1 / (min(3, setldel/4) + 1)) - miRev_no_NatP +dflt.minRev_freq_notatP_function <- function(n, setldel) { + # setldel = settlement delay + minRev_freq_notatP <- stats::rgeom(n, prob = 1 / (min(3, setldel/4) + 1)) + minRev_freq_notatP } ## implementation and output -minor <- claim_miRev_no( +minor <- claim_minRev_freq( test_claims, prob_atP = 0.5, - rfun_NatP = dflt.miRev_no_NatP_function) + rfun_notatP = dflt.minRev_freq_notatP_function) # view the minor revision history of the 10th claim in the 1st occurrence period minor[[1]][[10]] @@ -446,44 +451,44 @@ minor[[1]][[10]] An equivalent way of setting up the same structure using `paramfun`: ```{r eval=FALSE} -miRev_no_NatP_paramfun <- function(setldel) { +minRev_freq_notatP_paramfun <- function(setldel) { c(prob = 1 / (min(3, setldel/4) + 1)) } -minor <- claim_miRev_no( +minor <- claim_minRev_freq( test_claims, prob_atP = 0.5, - rfun_NatP = stats::rgeom, - paramfun_NatP = miRev_no_NatP_paramfun) + rfun_notatP = stats::rgeom, + paramfun_notatP = minRev_freq_notatP_paramfun) ``` Again the above example is only for illustrative purposes and users can run the default without explicitly spelling out the sampling distributions as above: ```{r eval=FALSE} -minor <- claim_miRev_no(claims = test_claims) +minor <- claim_minRev_freq(claims = test_claims) ``` ### Example 2.1.2 Alternative sampling distribution {#ex2.1.2} Suppose we believe that there should be no minor revisions at partial payments (`prob_atP = 0`) and that the number of minor revisions should follow a geometric distribution but with a higher mean. `SPLICE` can easily account for these assumptions through the following code. ```{r} -miRev_no_NatP_paramfun <- function(setldel) { +minRev_freq_notatP_paramfun <- function(setldel) { c(prob = 1 / (min(3, setldel/4) + 2)) } -minor_test <- claim_miRev_no( +minor_test <- claim_minRev_freq( test_claims, prob_atP = 0, - rfun_NatP = stats::rgeom, - paramfun_NatP = miRev_no_NatP_paramfun) + rfun_notatP = stats::rgeom, + paramfun_notatP = minRev_freq_notatP_paramfun) minor_test[[1]][[10]] ``` -## 2.2 Time of Minor Revisions {#miRev_time} -`claim_miRev_time()` generates the epochs of the minor revisions (time measured from claim notification). Note that there is no need to specify a random sampling function for minor revisions that occur simultaneously with a partial payment because the revision times simply coincide with the epochs of the relevant partial payments. +## 2.2 Time of Minor Revisions {#minRev_time} +`claim_minRev_time()` generates the epochs of the minor revisions (time measured from claim notification). Note that there is no need to specify a random sampling function for minor revisions that occur simultaneously with a partial payment because the revision times simply coincide with the epochs of the relevant partial payments. -For revisions outside of the partial payments, users are free to input a sampling distribution via `rfun_NatP` and a parameter function `paramfun_NatP` which relates the parameter(s) of the distribution to selected claim characteristics. +For revisions outside of the partial payments, users are free to input a sampling distribution via `rfun_notatP` and a parameter function `paramfun_notatP` which relates the parameter(s) of the distribution to selected claim characteristics. ### Example 2.2.1 Default implementation {#ex2.2.1} By default we assume that the epochs of the minor revision can be sampled from a uniform distribution: @@ -491,15 +496,15 @@ By default we assume that the epochs of the minor revision can be sampled from a ```{r} ## input # package default function for time of minor revisions that do not coincide with a payment -dflt.miRev_time_NatP <- function(n, setldel) { +dflt.minRev_time_notatP <- function(n, setldel) { sort(stats::runif(n, min = setldel/6, max = setldel)) } ## implementation and output -minor <- claim_miRev_time( +minor <- claim_minRev_time( claims = test_claims, - miRev_list = minor, # we will update the previous minor list - rfun_NatP = dflt.miRev_time_NatP + minRev_list = minor, # we will update the previous minor list + rfun_notatP = dflt.minRev_time_notatP ) # view the minor revision history of the 10th claim in the 1st occurrence period @@ -512,15 +517,17 @@ Let's consider an alternative example where we believe the epochs of minor revis ```{r} ## input -miRev_time_NatP_rfun <- function(n, setldel) { +minRev_time_notatP_rfun <- function(n, setldel) { + # n = number of minor revisions + # setldel = settlement delay sort(rtri(n, min = setldel/6, max = setldel, mode = setldel/6)) } ## implementation and output -minor_test <- claim_miRev_time( +minor_test <- claim_minRev_time( claims = test_claims, - miRev_list = minor, # we will update the previous minor list - rfun_NatP = miRev_time_NatP_rfun + minRev_list = minor, # we will update the previous minor list + rfun_notatP = minRev_time_notatP_rfun ) # view the minor revision history of the 10th claim in the 1st occurrence period @@ -528,10 +535,10 @@ minor_test <- claim_miRev_time( minor_test[[1]][[10]] ``` -## 2.3 Size of Minor Revisions {#miRev_size} -`claim_miRev_size()` generates the sizes of the minor revisions. Unlike the major revision multipliers which apply to the **incurred loss estimates**, the minor revision multipliers apply to the case estimate of **outstanding claim payments** i.e. a revision multiplier of 2.54 means that at the time of the minor revision the outstanding claims payment increases by a factor of 2.54. The reason for making this differentiation is briefly explained [here](#maRev_size). +## 2.3 Size of Minor Revisions {#minRev_size} +`claim_minRev_size()` generates the sizes of the minor revisions. Unlike the major revision multipliers which apply to the **incurred loss estimates**, the minor revision multipliers apply to the case estimate of **outstanding claim payments** i.e. a revision multiplier of 2.54 means that at the time of the minor revision the outstanding claims payment increases by a factor of 2.54. The reason for making this differentiation is briefly explained [here](#majRev_size). -`SPLICE` assumes a common sampling distribution for minor revisions that occur at partial payments and those that occur at any other times. But users may provide separate parameter functions (`paramfun_atP` and `paramfun_NatP`) for the two cases. +`SPLICE` assumes a common sampling distribution for minor revisions that occur at partial payments and those that occur at any other times. But users may provide separate parameter functions (`paramfun_atP` and `paramfun_notatP`) for the two cases. ### Example 2.3.1 Default implementation {#ex2.3.1} In the default setting, we incorporate sampling dependence on the delay from notification to settlement, the delay from notification to the subject minor revisions, and the history of major revisions (in particular, the time of the second major revision). @@ -547,16 +554,19 @@ Note that minor revisions tend to be upward in the early part of a claim’s lif ```{r} ## input # package default function for the size of minor revisions -dflt.miRev_size <- function( +dflt.minRev_size <- function( # n = number of minor revisions - n, miRev_time, maRev_time_2nd, setldel) { + # minRev_time = epochs of the minor revisions (from claim notification) + # majRev_time_2nd = epoch of 2nd major revision (from claim notification) + # setldel = settlement delay + n, minRev_time, majRev_time_2nd, setldel) { - k <- length(miRev_time) - miRev_multiplier <- vector(length = k) + k <- length(minRev_time) + minRev_factor <- vector(length = k) if (k >= 1) { for (i in 1:k) { - curr <- miRev_time[i] + curr <- minRev_time[i] if (curr <= setldel/3) { meanlog <- 0.15 } else if (curr <= (2/3) * setldel) { @@ -564,44 +574,46 @@ dflt.miRev_size <- function( } else { meanlog <- -0.1 } - sdlog <- ifelse(curr > maRev_time_2nd, 0.05, 0.1) - miRev_multiplier[i] <- stats::rlnorm(n = 1, meanlog, sdlog) + sdlog <- ifelse(curr > majRev_time_2nd, 0.05, 0.1) + minRev_factor[i] <- stats::rlnorm(n = 1, meanlog, sdlog) } } - miRev_multiplier + minRev_factor } ``` -While `setldel` is a directly accessible claim characteristic, we need `paramfun` to take care of the extraction and computation of `maRev_time_2nd` and `miRev_time` as a function of the revision lists that we can access. +While `setldel` (settlement delay) is a directly accessible claim characteristic, we need `paramfun` to take care of the extraction and computation of `majRev_time_2nd` and `minRev_time` as a function of the revision lists that we can access. ```{r} -miRev_size_param_atP <- function(major, minor, setldel) { - list(miRev_time = minor$miRev_time_atP, - maRev_time_2nd = ifelse( - # so it always holds miRev_time < maRev_time_2nd - is.na(major$maRev_time[2]), setldel + 1, major$maRev_time[2]), +# parameter function for minor revision at payments +minRev_size_param_atP <- function(major, minor, setldel) { + list(minRev_time = minor$minRev_time_atP, + majRev_time_2nd = ifelse( + # so it always holds minRev_time < majRev_time_2nd + is.na(major$majRev_time[2]), setldel + 1, major$majRev_time[2]), setldel = setldel) } -miRev_size_param_NatP <- function(major, minor, setldel) { - list(miRev_time = minor$miRev_time_NatP, - maRev_time_2nd = ifelse( - # so it always holds miRev_time < maRev_time_2nd - is.na(major$maRev_time[2]), setldel + 1, major$maRev_time[2]), +# parameter function for minor revisions NOT at payments +minRev_size_param_notatP <- function(major, minor, setldel) { + list(minRev_time = minor$minRev_time_notatP, + majRev_time_2nd = ifelse( + # so it always holds minRev_time < majRev_time_2nd + is.na(major$majRev_time[2]), setldel + 1, major$majRev_time[2]), setldel = setldel) } ``` ```{r} ## implementation and output -minor <- claim_miRev_size( +minor <- claim_minRev_size( claims = test_claims, - maRev_list = major, - miRev_list = minor, - rfun = dflt.miRev_size, - paramfun_atP = miRev_size_param_atP, - paramfun_NatP = miRev_size_param_NatP + majRev_list = major, + minRev_list = minor, + rfun = dflt.minRev_size, + paramfun_atP = minRev_size_param_atP, + paramfun_notatP = minRev_size_param_notatP ) # view the minor revision history of the 10th claim in the 1st occurrence period @@ -609,7 +621,7 @@ minor <- claim_miRev_size( minor[[1]][[10]] ``` -For this particular claim record, we observe `r minor[[1]][[10]]$miRev_no_atP` minor revisions that coincide with a payment and `r minor[[1]][[10]]$miRev_no_NatP` minor revisions outside of the partial payment times. +For this particular claim record, we observe `r minor[[1]][[10]]$minRev_freq_atP` minor revisions that coincide with a payment and `r minor[[1]][[10]]$minRev_freq_notatP` minor revisions outside of the partial payment times. ### Example 2.3.2 Uniform distribution for minor revision multipliers {#ex2.3.2} For illustrative purposes, let's now assume that the minor revision multipliers should be sampled from a uniform distribution. @@ -620,13 +632,13 @@ paramfun_atP <- function(claim_size, ...) { c(min = pmin(1, pmax(log(claim_size / 15000), 0.5)), max = pmin(1, pmax(log(claim_size / 15000), 0.5)) + 1) } -paramfun_NatP <- paramfun_atP +paramfun_notatP <- paramfun_atP ## implementation and output claim_size_vect <- unlist(test_claims$claim_size_list) -minor_test <- claim_miRev_size( +minor_test <- claim_minRev_size( test_claims, major, minor, - rfun = stats::runif, paramfun_atP, paramfun_NatP, + rfun = stats::runif, paramfun_atP, paramfun_notatP, claim_size = claim_size_vect) minor_test[[1]][[10]] ```