From 119173b7214f88be7da320a594127c7a0f67902d Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Sat, 15 Oct 2016 05:50:55 -0700 Subject: [PATCH 01/29] MackChainLadder argument checks tail and est.sigma --- R/MackChainLadderFunctions.R | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/R/MackChainLadderFunctions.R b/R/MackChainLadderFunctions.R index ba310ecd..34d23f09 100755 --- a/R/MackChainLadderFunctions.R +++ b/R/MackChainLadderFunctions.R @@ -22,6 +22,11 @@ MackChainLadder <- function( # 2013-02-25 Parameter risk recursive formula may have a third term per # Murphy and BBMW if (! mse.method %in% c("Mack", "Independence")) stop("mse.method must be 'Mack' or 'Independence'") + if (! est.sigma %in% c("Mack", "log-linear")) { + if (!is.numeric(est.sigma)) + stop("est.sigma must be 'Mack' or 'log-linear' or numeric") + } + if (!is.logical(tail) & !is.numeric(tail)) stop("tail must be logical or numeric") Triangle <- checkTriangle(Triangle) m <- dim(Triangle)[1] From 1035a54063e38d560a4727df9f5d4da6f94ace22 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Sat, 15 Oct 2016 13:40:47 -0700 Subject: [PATCH 02/29] NULL tail.se tail.sigma Before fitting loglinear regressions from which tail.se and/or tail.sigma will be predicted, check for the number of positive values of f.se and sigma. --- R/MackChainLadderFunctions.R | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/R/MackChainLadderFunctions.R b/R/MackChainLadderFunctions.R index 34d23f09..a0bdaaf2 100755 --- a/R/MackChainLadderFunctions.R +++ b/R/MackChainLadderFunctions.R @@ -352,15 +352,41 @@ tail.SE <- function(FullTriangle, StdErr, Total.SE, tail.factor, tail.se = NULL, if(is.null(tail.se)){ .fse <- StdErr$f.se[start:(n-2)] - mse <- lm(log(.fse) ~ .dev) - tail.se <- exp(predict(mse, newdata=data.frame(.dev=tail.pos))) + ndx <- .fse > 0 + numpos <- sum(ndx) + if (numpos) { + .devse <- .dev[ndx] + .fse <- .fse[ndx] + mse <- lm(log(.fse) ~ .devse) + if (numpos > 1) tail.se <- exp(predict(mse, newdata=data.frame(.devse=tail.pos))) + else { + warning("Only one column for estimating tail.se") + tail.se <- suppressWarnings( + exp(predict(mse, newdata=data.frame(.dev=tail.pos)))) + } + } + else { + warning("No development variability in triangle. Setting tail.se = 0") + tail.se <- 0 + } } StdErr$f.se <- c(StdErr$f.se, tail.se = tail.se) if(is.null(tail.sigma)){ .sigma <- StdErr$sigma[start:(n-2)] - msig <- lm(log(.sigma) ~ .dev) - tail.sigma <- exp(predict(msig, newdata = data.frame(.dev = tail.pos))) + ndx <- .sigma > 0 + numpos <- sum(ndx) + if (numpos) { + .devsigma <- .dev[ndx] + .sigma <- .sigma[ndx] + msig <- lm(log(.sigma) ~ .devsigma) + if (numpos > 1) tail.sigma <- exp( + predict(msig, newdata = data.frame(.devsigma = tail.pos))) + else { + warning("No development variability in triangle. Setting tail.sigma = 0") + tail.sigma <- 0 + } + } } StdErr$sigma <- c(StdErr$sigma, tail.sigma = as.numeric(tail.sigma)) From bae2f7f29b92b448bfea4e8beed62bea329c8f3f Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Sat, 15 Oct 2016 14:13:58 -0700 Subject: [PATCH 03/29] est.sigma can be a numeric vector Check only 1st element for Mack or log-linear --- R/MackChainLadderFunctions.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/MackChainLadderFunctions.R b/R/MackChainLadderFunctions.R index a0bdaaf2..9f6c9e5d 100755 --- a/R/MackChainLadderFunctions.R +++ b/R/MackChainLadderFunctions.R @@ -22,7 +22,7 @@ MackChainLadder <- function( # 2013-02-25 Parameter risk recursive formula may have a third term per # Murphy and BBMW if (! mse.method %in% c("Mack", "Independence")) stop("mse.method must be 'Mack' or 'Independence'") - if (! est.sigma %in% c("Mack", "log-linear")) { + if (! est.sigma[1] %in% c("Mack", "log-linear")) { if (!is.numeric(est.sigma)) stop("est.sigma must be 'Mack' or 'log-linear' or numeric") } From b7b9024b9a6aff097cce4ebba2c1f51959405ed0 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Mon, 17 Oct 2016 12:58:37 -0700 Subject: [PATCH 04/29] first commit --- R/plotParms.R | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 R/plotParms.R diff --git a/R/plotParms.R b/R/plotParms.R new file mode 100644 index 00000000..42089429 --- /dev/null +++ b/R/plotParms.R @@ -0,0 +1,232 @@ +plotParms <- function(x) UseMethod("plotParms") +plot.cl.f <- function(x) { + require(ggplot2) + smmry <- suppressWarnings(lapply(x$Models, summary)) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + n <- length(f) + f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + sigma <- sapply(smmry, function(x) x$sigma) + nobs <- as.character(sapply(x$Models, nobs)) + na_sigma <- is.na(sigma) + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f, f.se, sigma, na_sigma, nobs, + label = nobs, + stringsAsFactors = FALSE) + df$f.se[na_sigma] <- 0 + P <- ggplot(df, aes(x=xx, y=f, label = label)) + + geom_errorbar(aes(ymin=f-f.se, ymax=f+f.se), colour="black", width=.1) + + xlab(names(dimnames(x$Triangle))[1L]) + + geom_line(aes(colour = na_sigma, group = 1)) + + geom_point(aes(colour = na_sigma)) + + ggtitle("f estimates") + if (all(!na_sigma)) P <- P + theme(legend.position="none") + P +} +plot.cl.f1 <- function(x) { + require(ggplot2) + smmry <- suppressWarnings(lapply(x$Models, summary)) + f1 <- sapply(smmry, function(x) x$coef["x","Estimate"]) - 1 + n <- length(f1) + f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + sigma <- sapply(smmry, function(x) x$sigma) + nobs <- as.character(sapply(x$Models, nobs)) + na_sigma <- is.na(sigma) + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f1, f.se, sigma, na_sigma, nobs, + label = nobs, + stringsAsFactors = FALSE) + df$f.se[na_sigma] <- 0 + P <- ggplot(df, aes(x=xx, y=f1, label = label)) + + geom_errorbar(aes(ymin=f1-f.se, ymax=f1+f.se), colour="black", width=.1) + + xlab(names(dimnames(x$Triangle))[1L]) + + geom_line(aes(colour = na_sigma, group = 1)) + + geom_point(aes(colour = na_sigma)) + + ggtitle("f-1 estimates") + if (all(!na_sigma)) P <- P + theme(legend.position="none") + P +} +plot.cl.sigma <- function(x) { + require(ggplot2) + smmry <- suppressWarnings(lapply(x$Models, summary)) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + n <- length(f) + f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + sigma <- sapply(smmry, function(x) x$sigma) + nobs <- as.character(sapply(x$Models, nobs)) + na_sigma <- is.na(sigma) + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f1, f.se, sigma, na_sigma, nobs, + sigmapoint = sigma, + label = nobs, + stringsAsFactors = FALSE) + df$sigmapoint[na_sigma] <- 0 + P <- ggplot(df, aes(x=xx, y=sigma, label = label)) + + xlab(names(dimnames(x$Triangle))[1L]) + + geom_line(aes(colour = na_sigma, group = 1), na.rm = TRUE) + + geom_point(aes(y = sigmapoint, colour = na_sigma)) + + ggtitle("sigma estimates") + if (all(!na_sigma)) P <- P + theme(legend.position="none") + P +} +plot.cl.f.se <- function(x) { + require(ggplot2) + smmry <- suppressWarnings(lapply(x$Models, summary)) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + n <- length(f) + f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + sigma <- sapply(smmry, function(x) x$sigma) + na_sigma <- is.na(sigma) + #isna <- is.na(f.cv) + #sigma[isna] <- 0 + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f, f.se, sigma, na_sigma, + f.se.point = f.se, + stringsAsFactors = FALSE) + df$f.se.point[na_sigma] <- 0 + P <- ggplot(df, aes(x=xx, y=f.se, colour = na_sigma)) + + xlab(names(dimnames(x$Triangle))[2L]) + + geom_line(aes(colour = na_sigma, group = 1), na.rm = TRUE) + + geom_point(aes(y = f.se.point, colour = na_sigma), na.rm = TRUE) + + ggtitle("f.se estimates") + if (all(!na_sigma)) P <- P + theme(legend.position="none") + P +} +plot.cl.f.cv <- function(x) { + require(ggplot2) + smmry <- suppressWarnings(lapply(x$Models, summary)) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + n <- length(f) + f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + f.cv <- f.se / (f-1) + sigma <- sapply(smmry, function(x) x$sigma) + na_sigma <- is.na(sigma) + est_source <- rep("regr", n) + est_source[na_sigma] <- "sigma=NA" + est_source[f==1] <- "f=1" + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f, f.se, sigma, na_sigma, f.cv, + f.cv.point = f.cv, + est_source, + stringsAsFactors = FALSE) + df$f.cv.point[est_source!="regr"] <- 0 + P <- ggplot(df, aes(x=xx, y=f.cv, colour = est_source)) + + xlab(names(dimnames(x$Triangle))[2L]) + + geom_line(aes(group = 1), na.rm = TRUE) + + geom_point(aes(y=f.cv.point, colour = est_source), na.rm = TRUE) + + ggtitle("cv(f-1) estimates") + P +} + +# Now MackCL +plot.MackCL.f <- function(x) { + require(ggplot2) + smmry <- suppressWarnings(lapply(x$Models, summary)) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + n <- length(f) + f.se <- x$f.se #sapply(smmry, function(x) x$coef["x","Std. Error"]) + sigma <- sapply(smmry, function(x) x$sigma) + nobs <- as.character(sapply(x$Models, nobs)) + nasigma <- is.na(sigma) + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f, f.se, sigma, nasigma, nobs, + label = nobs, + stringsAsFactors = FALSE) + P <- ggplot(df, aes(x=xx, y=f, label = label)) + + geom_errorbar(aes(ymin=f-f.se, ymax=f+f.se), colour="black", width=.1) + + xlab(names(dimnames(x$Triangle))[1L]) + + geom_line(aes(colour = nasigma[1], group = 1)) + + geom_point(aes(colour = nasigma)) + + ggtitle("f estimates") + P <- P + theme(legend.position="none") + P +} +plot.MackCL.f1 <- function(x) { + require(ggplot2) + smmry <- suppressWarnings(lapply(x$Models, summary)) + f1 <- sapply(smmry, function(x) x$coef["x","Estimate"]) - 1 + n <- length(f1) + f.se <- x$f.se #sapply(smmry, function(x) x$coef["x","Std. Error"]) + sigma <- sapply(smmry, function(x) x$sigma) + nobs <- as.character(sapply(x$Models, nobs)) + nasigma <- is.na(sigma) + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f1, f.se, sigma, nasigma, nobs, + label = nobs, + stringsAsFactors = FALSE) + P <- ggplot(df, aes(x=xx, y=f1, label = label)) + + geom_errorbar(aes(ymin=f1-f.se, ymax=f1+f.se), colour="black", width=.1) + + xlab(names(dimnames(x$Triangle))[1L]) + + geom_line(aes(colour = nasigma[1], group = 1)) + + geom_point(aes(colour = nasigma)) + + ggtitle("f-1 estimates") + P <- P + theme(legend.position="none") + P +} +plot.MackCL.sigma <- function(x) { + require(ggplot2) + smmry <- suppressWarnings(lapply(x$Models, summary)) + #smmry <- lapply(x$Models, summary) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + n <- length(f) + f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + sigma <- sapply(smmry, function(x) x$sigma) + #nobs <- rep(">1", n) + imputed <- is.na(sigma) + nasigma <- is.na(sigma) + #nobs[nasigma] <- "T" + sigma[nasigma] <- x$sigma[imputed] + # df <- sapply(smmry, function(x) x$df[2L]) + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, sigma, imputed, stringsAsFactors = FALSE) + P <- ggplot(df, aes(x=xx, y=sigma, colour = imputed)) + + xlab(names(dimnames(x$Triangle))[2L]) + + geom_line(aes(colour = imputed[1], group = 1)) + + geom_point(aes(colour = imputed)) + + ggtitle("sigma estimates") + if (all(!nasigma)) P <- P + theme(legend.position="none") + P +} +plot.MackCL.f.se <- function(x) { + require(ggplot2) + smmry <- suppressWarnings(lapply(x$Models, summary)) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + n <- length(f) + f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + f.cv <- f.se / (f-1) + sigma <- sapply(smmry, function(x) x$sigma) + imputed <- is.na(sigma) + sigma[imputed] <- x$sigma[imputed] + f.se[imputed] <- x$f.se[imputed] + #isna <- is.na(f.cv) + #sigma[isna] <- 0 + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f, f.se, sigma, imputed, f.cv, stringsAsFactors = FALSE) + P <- ggplot(df, aes(x=xx, y=f.se, colour = imputed)) + + xlab(names(dimnames(x$Triangle))[2L]) + + geom_line(aes(colour = imputed[1], group = 1), na.rm = TRUE) + + geom_point(aes(colour = imputed), na.rm = TRUE) + + ggtitle("f.se estimates") + if (all(!imputed)) P <- P + theme(legend.position="none") + P +} +plot.MackCL.f.cv <- function(x) { + require(ggplot2) + smmry <- suppressWarnings(lapply(x$Models, summary)) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + n <- length(f) + f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + sigma <- sapply(smmry, function(x) x$sigma) + imputed <- is.na(sigma) + sigma[imputed] <- x$sigma[imputed] + f.se[imputed] <- x$f.se[imputed] + f.cv <- f.se / (f-1) + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f, f.se, sigma, imputed, f.cv, stringsAsFactors = FALSE) + P <- ggplot(df, aes(x=xx, y=f.cv, colour = imputed)) + + xlab(names(dimnames(x$Triangle))[2L]) + + geom_line(aes(colour = imputed[1], group = 1), na.rm = TRUE) + + geom_point(aes(colour = imputed), na.rm = TRUE) + + ggtitle("f.cv estimates") + if (all(!imputed)) P <- P + theme(legend.position="none") + P +} From b59d7a69e59be19e17cc6ca36f64349f82a585b5 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Mon, 17 Oct 2016 14:12:14 -0700 Subject: [PATCH 05/29] plotParms.ChainLadder --- R/plotParms.R | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/R/plotParms.R b/R/plotParms.R index 42089429..756b2cb3 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -1,4 +1,14 @@ plotParms <- function(x) UseMethod("plotParms") +plotParms.ChainLadder <- function(x) { + library(grid) + library(gridExtra) + p1 <- plot.cl.f(x) + theme(axis.title.y=element_blank()) + p2 <- plot.cl.f.se(x) + theme(axis.title.y=element_blank()) + p3 <- plot.cl.f.cv(x) + theme(axis.title.y=element_blank()) + p4 <- plot.cl.sigma(x) + theme(axis.title.y=element_blank()) + arrangeGrob(grobs=list(p1, p2, p3, p4), ncol = 2, nrow = 2, + top = "chainladder(GenIns) parameter estimates") +} plot.cl.f <- function(x) { require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) @@ -55,7 +65,7 @@ plot.cl.sigma <- function(x) { nobs <- as.character(sapply(x$Models, nobs)) na_sigma <- is.na(sigma) xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f1, f.se, sigma, na_sigma, nobs, + df <- data.frame(xx, f.se, sigma, na_sigma, nobs, sigmapoint = sigma, label = nobs, stringsAsFactors = FALSE) @@ -111,6 +121,7 @@ plot.cl.f.cv <- function(x) { df$f.cv.point[est_source!="regr"] <- 0 P <- ggplot(df, aes(x=xx, y=f.cv, colour = est_source)) + xlab(names(dimnames(x$Triangle))[2L]) + + ylab("cv(f-1)") + geom_line(aes(group = 1), na.rm = TRUE) + geom_point(aes(y=f.cv.point, colour = est_source), na.rm = TRUE) + ggtitle("cv(f-1) estimates") From 77497574861d000de0a1a87738511f35194b2e33 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Mon, 17 Oct 2016 14:37:24 -0700 Subject: [PATCH 06/29] title with name of Triangle --- R/ChainLadder.R | 5 ++++- R/MackChainLadderFunctions.R | 1 + R/plotParms.R | 12 ++++++++---- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/R/ChainLadder.R b/R/ChainLadder.R index 228d4358..26ff7770 100644 --- a/R/ChainLadder.R +++ b/R/ChainLadder.R @@ -5,6 +5,8 @@ chainladder <- function(Triangle, weights=1, delta=1){ + + TriangleName <- deparse(substitute(Triangle)) Triangle <- checkTriangle(Triangle) n <- dim(Triangle)[2] @@ -27,7 +29,8 @@ chainladder <- function(Triangle, weights=1, } myModel <- lapply(c(1:(n-1)), lmCL, Triangle) - output <- list(Models=myModel, Triangle=Triangle, delta=delta, weights=weights) + output <- list(Models=myModel, Triangle=Triangle, delta=delta, + weights=weights, TriangleName = TriangleName) class(output) <- c("ChainLadder", "TriangleModel", class(output)) return(output) } diff --git a/R/MackChainLadderFunctions.R b/R/MackChainLadderFunctions.R index 9f6c9e5d..bbcb4725 100755 --- a/R/MackChainLadderFunctions.R +++ b/R/MackChainLadderFunctions.R @@ -123,6 +123,7 @@ MackChainLadder <- function( output[["Total.ProcessRisk"]] <- attr(Total.SE, "processrisk") output[["Total.ParameterRisk"]] <- attr(Total.SE, "paramrisk") output[["tail"]] <- tail + output[["TriangleName"]] <- CL$TriangleName class(output) <- c("MackChainLadder", "TriangleModel", "list") return(output) } diff --git a/R/plotParms.R b/R/plotParms.R index 756b2cb3..5e01f7df 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -1,13 +1,17 @@ -plotParms <- function(x) UseMethod("plotParms") -plotParms.ChainLadder <- function(x) { +plotParms <- function(x, ...) UseMethod("plotParms") +plotParms.ChainLadder <- function(x, title) { library(grid) library(gridExtra) p1 <- plot.cl.f(x) + theme(axis.title.y=element_blank()) p2 <- plot.cl.f.se(x) + theme(axis.title.y=element_blank()) p3 <- plot.cl.f.cv(x) + theme(axis.title.y=element_blank()) p4 <- plot.cl.sigma(x) + theme(axis.title.y=element_blank()) - arrangeGrob(grobs=list(p1, p2, p3, p4), ncol = 2, nrow = 2, - top = "chainladder(GenIns) parameter estimates") + if (missing(title)) title <- paste0("ChainLadder(", + x$TriangleName, + ") parameter estimates") + + marrangeGrob(grobs=list(p1, p2, p3, p4), ncol = 2, nrow = 2, + top = title) } plot.cl.f <- function(x) { require(ggplot2) From a9ea0d0df81115cc69e298604add4628308bbd98 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Mon, 17 Oct 2016 15:16:13 -0700 Subject: [PATCH 07/29] Save inputs to MackChainLadder --- R/MackChainLadderFunctions.R | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/R/MackChainLadderFunctions.R b/R/MackChainLadderFunctions.R index bbcb4725..b1686177 100755 --- a/R/MackChainLadderFunctions.R +++ b/R/MackChainLadderFunctions.R @@ -19,6 +19,7 @@ MackChainLadder <- function( ## idea: have a list for tail factor ## tail=list(f=FALSE, f.se=NULL, sigma=NULL, F.se=NULL) ## + tail.input <- tail # 2013-02-25 Parameter risk recursive formula may have a third term per # Murphy and BBMW if (! mse.method %in% c("Mack", "Independence")) stop("mse.method must be 'Mack' or 'Independence'") @@ -124,6 +125,11 @@ MackChainLadder <- function( output[["Total.ParameterRisk"]] <- attr(Total.SE, "paramrisk") output[["tail"]] <- tail output[["TriangleName"]] <- CL$TriangleName + output$est.sigma <- est.sigma + output$tail <- tail.input + output$tail.se <- tail.se + output$tail.sigma <- tail.sigma + output$mse.method <- mse.method class(output) <- c("MackChainLadder", "TriangleModel", "list") return(output) } From 30b3681cc30953fef4f61bc6f4f6c5c8cefa0170 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Tue, 18 Oct 2016 10:42:50 -0700 Subject: [PATCH 08/29] imports gridExtra --- DESCRIPTION | 1 + 1 file changed, 1 insertion(+) diff --git a/DESCRIPTION b/DESCRIPTION index 9d492e3a..f49255a2 100755 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -32,6 +32,7 @@ Imports: reshape2, lattice, grid, + gridExtra, tweedie, utils, systemfit, From 57f19bdcc0d7964d90f80bae3d0100504ba0f0c8 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Tue, 18 Oct 2016 10:43:12 -0700 Subject: [PATCH 09/29] add roxygen comments --- R/plotParms.R | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/R/plotParms.R b/R/plotParms.R index 5e01f7df..d8125083 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -1,7 +1,18 @@ +#' plotParms Plot the estimated parameters of a model +#' +#' Methods to visualize the estimated parameters. +#' S3 methods currently exist for objects of class +#' ChainLadder and MackChainLadder. +#' +#' @param x object whose parameters are to be visualized +#' +#' @param title optional; character holding title of the plot; +#' defaults to something the class author deems appropriate. +library(ggplot2) +library(grid) +library(gridExtra) plotParms <- function(x, ...) UseMethod("plotParms") plotParms.ChainLadder <- function(x, title) { - library(grid) - library(gridExtra) p1 <- plot.cl.f(x) + theme(axis.title.y=element_blank()) p2 <- plot.cl.f.se(x) + theme(axis.title.y=element_blank()) p3 <- plot.cl.f.cv(x) + theme(axis.title.y=element_blank()) @@ -14,7 +25,7 @@ plotParms.ChainLadder <- function(x, title) { top = title) } plot.cl.f <- function(x) { - require(ggplot2) +# require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) f <- sapply(smmry, function(x) x$coef["x","Estimate"]) n <- length(f) From fecb1249d83fe7c5341fa1990c99bc3e2c3fed6a Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Tue, 18 Oct 2016 12:55:48 -0700 Subject: [PATCH 10/29] create plotParms help file --- man/plotParms.Rd | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 man/plotParms.Rd diff --git a/man/plotParms.Rd b/man/plotParms.Rd new file mode 100644 index 00000000..63cf763d --- /dev/null +++ b/man/plotParms.Rd @@ -0,0 +1,48 @@ +\name{plotParms} +\alias{plotParms} +%\alias{plotParms.MackChainLadder} +\alias{plotParms.ChainLadder} +\alias{plotParms.default} +\title{ +Plot the estimated parameters of a model +} + +\encoding{UTF-8} + +\description{ +Methods to visualize the estimated parameters. +S3 methods currently exist for objects of class +ChainLadder and MackChainLadder. +} + +\usage{ +plotParms(x, \dots) +\method{plotParms}{ChainLadder}(x, title, \dots) +\method{plotParms}{default}(x, \dots) + +} +%- maybe also 'usage' for other objects documented here. +\arguments{ + + \item{x}{object whose parameters are to be visualized} + \item{title}{optional; character holding title of the plot; +defaults to something the class author deems appropriate. + } + \item{\dots}{unused at this time} +} +\details{ +TBD +} +\value{ +In the case of class ChainLadder, +list of class arrangelist returned by +gridExtra::marrangeGrob. +In all other cases, a stop error is executed at this time. +} +\author{ +Dan Murphy for class ChainLadder. +} +\examples{ +plotParms(chainladder(GenIns)) +} +\keyword{ models } From b7f664760a2e6b4a129d80f2b6b2e3b86c0aad77 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Tue, 18 Oct 2016 12:57:03 -0700 Subject: [PATCH 11/29] Clean up R file so no NOTES Needed aes_. Eliminated library, etc. calls. --- R/plotParms.R | 51 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/R/plotParms.R b/R/plotParms.R index d8125083..22e0ad9c 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -8,11 +8,15 @@ #' #' @param title optional; character holding title of the plot; #' defaults to something the class author deems appropriate. -library(ggplot2) -library(grid) -library(gridExtra) +#library(ggplot2) +#library(grid) +#library(gridExtra) plotParms <- function(x, ...) UseMethod("plotParms") -plotParms.ChainLadder <- function(x, title) { +plotParms.default <- function(x, ...){ + stop("No 'plotParms' method exists for objects of class ", + class(x)) +} +plotParms.ChainLadder <- function(x, title, ...) { p1 <- plot.cl.f(x) + theme(axis.title.y=element_blank()) p2 <- plot.cl.f.se(x) + theme(axis.title.y=element_blank()) p3 <- plot.cl.f.cv(x) + theme(axis.title.y=element_blank()) @@ -38,7 +42,12 @@ plot.cl.f <- function(x) { label = nobs, stringsAsFactors = FALSE) df$f.se[na_sigma] <- 0 - P <- ggplot(df, aes(x=xx, y=f, label = label)) + + # Need for aes_: see exchange at link (wrapped) below + # and final solution + # http://stackoverflow.com/questions/9439256/ + # how-can-i-handle-r-cmd-check-no-visible-binding-for- + # global-variable-notes-when + P <- ggplot(df, aes_(x=~xx, y=~f, label = ~label)) + geom_errorbar(aes(ymin=f-f.se, ymax=f+f.se), colour="black", width=.1) + xlab(names(dimnames(x$Triangle))[1L]) + geom_line(aes(colour = na_sigma, group = 1)) + @@ -48,7 +57,7 @@ plot.cl.f <- function(x) { P } plot.cl.f1 <- function(x) { - require(ggplot2) +# require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) f1 <- sapply(smmry, function(x) x$coef["x","Estimate"]) - 1 n <- length(f1) @@ -61,7 +70,7 @@ plot.cl.f1 <- function(x) { label = nobs, stringsAsFactors = FALSE) df$f.se[na_sigma] <- 0 - P <- ggplot(df, aes(x=xx, y=f1, label = label)) + + P <- ggplot(df, aes_(x=~xx, y=~f1, label = ~label)) + geom_errorbar(aes(ymin=f1-f.se, ymax=f1+f.se), colour="black", width=.1) + xlab(names(dimnames(x$Triangle))[1L]) + geom_line(aes(colour = na_sigma, group = 1)) + @@ -71,7 +80,7 @@ plot.cl.f1 <- function(x) { P } plot.cl.sigma <- function(x) { - require(ggplot2) +# require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) f <- sapply(smmry, function(x) x$coef["x","Estimate"]) n <- length(f) @@ -85,16 +94,16 @@ plot.cl.sigma <- function(x) { label = nobs, stringsAsFactors = FALSE) df$sigmapoint[na_sigma] <- 0 - P <- ggplot(df, aes(x=xx, y=sigma, label = label)) + + P <- ggplot(df, aes_(x=~xx, y=~sigma, label = ~label)) + xlab(names(dimnames(x$Triangle))[1L]) + geom_line(aes(colour = na_sigma, group = 1), na.rm = TRUE) + - geom_point(aes(y = sigmapoint, colour = na_sigma)) + + geom_point(aes_(y = ~sigmapoint, colour = ~na_sigma)) + ggtitle("sigma estimates") if (all(!na_sigma)) P <- P + theme(legend.position="none") P } plot.cl.f.se <- function(x) { - require(ggplot2) +# require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) f <- sapply(smmry, function(x) x$coef["x","Estimate"]) n <- length(f) @@ -111,13 +120,13 @@ plot.cl.f.se <- function(x) { P <- ggplot(df, aes(x=xx, y=f.se, colour = na_sigma)) + xlab(names(dimnames(x$Triangle))[2L]) + geom_line(aes(colour = na_sigma, group = 1), na.rm = TRUE) + - geom_point(aes(y = f.se.point, colour = na_sigma), na.rm = TRUE) + + geom_point(aes_(y = ~f.se.point, colour = ~na_sigma), na.rm = TRUE) + ggtitle("f.se estimates") if (all(!na_sigma)) P <- P + theme(legend.position="none") P } plot.cl.f.cv <- function(x) { - require(ggplot2) +# require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) f <- sapply(smmry, function(x) x$coef["x","Estimate"]) n <- length(f) @@ -138,14 +147,14 @@ plot.cl.f.cv <- function(x) { xlab(names(dimnames(x$Triangle))[2L]) + ylab("cv(f-1)") + geom_line(aes(group = 1), na.rm = TRUE) + - geom_point(aes(y=f.cv.point, colour = est_source), na.rm = TRUE) + + geom_point(aes_(y=~f.cv.point, colour = ~est_source), na.rm = TRUE) + ggtitle("cv(f-1) estimates") P } # Now MackCL plot.MackCL.f <- function(x) { - require(ggplot2) +# require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) f <- sapply(smmry, function(x) x$coef["x","Estimate"]) n <- length(f) @@ -157,7 +166,7 @@ plot.MackCL.f <- function(x) { df <- data.frame(xx, f, f.se, sigma, nasigma, nobs, label = nobs, stringsAsFactors = FALSE) - P <- ggplot(df, aes(x=xx, y=f, label = label)) + + P <- ggplot(df, aes_(x=~xx, y=~f, label = ~label)) + geom_errorbar(aes(ymin=f-f.se, ymax=f+f.se), colour="black", width=.1) + xlab(names(dimnames(x$Triangle))[1L]) + geom_line(aes(colour = nasigma[1], group = 1)) + @@ -167,7 +176,7 @@ plot.MackCL.f <- function(x) { P } plot.MackCL.f1 <- function(x) { - require(ggplot2) +# require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) f1 <- sapply(smmry, function(x) x$coef["x","Estimate"]) - 1 n <- length(f1) @@ -179,7 +188,7 @@ plot.MackCL.f1 <- function(x) { df <- data.frame(xx, f1, f.se, sigma, nasigma, nobs, label = nobs, stringsAsFactors = FALSE) - P <- ggplot(df, aes(x=xx, y=f1, label = label)) + + P <- ggplot(df, aes_(x=~xx, y=~f1, label = ~label)) + geom_errorbar(aes(ymin=f1-f.se, ymax=f1+f.se), colour="black", width=.1) + xlab(names(dimnames(x$Triangle))[1L]) + geom_line(aes(colour = nasigma[1], group = 1)) + @@ -189,7 +198,7 @@ plot.MackCL.f1 <- function(x) { P } plot.MackCL.sigma <- function(x) { - require(ggplot2) +# require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) #smmry <- lapply(x$Models, summary) f <- sapply(smmry, function(x) x$coef["x","Estimate"]) @@ -213,7 +222,7 @@ plot.MackCL.sigma <- function(x) { P } plot.MackCL.f.se <- function(x) { - require(ggplot2) +# require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) f <- sapply(smmry, function(x) x$coef["x","Estimate"]) n <- length(f) @@ -236,7 +245,7 @@ plot.MackCL.f.se <- function(x) { P } plot.MackCL.f.cv <- function(x) { - require(ggplot2) +# require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) f <- sapply(smmry, function(x) x$coef["x","Estimate"]) n <- length(f) From cd3e83e0d520856e84f21bd9fbf8fc3f2a40def8 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Tue, 18 Oct 2016 13:00:41 -0700 Subject: [PATCH 12/29] plotParms changes Needed much more of ggplot2. Needed a function from gridExtra. Export plotParms methods. Cropped to no more than 80 chars wide. --- NAMESPACE | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 62385ad4..1aae9be0 100755 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,7 @@ import(stats) -importFrom(ggplot2, ggplot, geom_density, facet_wrap, aes, "scale_x_continuous") +import(ggplot2) +#importFrom(ggplot2, ggplot, geom_density, facet_wrap, aes, "scale_x_continuous") +importFrom(gridExtra, marrangeGrob) importFrom(tweedie, rtweedie, "tweedie.profile") importFrom(statmod, tweedie) importFrom(systemfit, systemfit, systemfit.control) @@ -20,7 +22,8 @@ importFrom(cplm, cpglm) importFrom(MASS, glm.nb) importClassesFrom(cplm, NullNum, NullList) -importMethodsFrom(cplm, show, predict, vcov, residuals, resid, coef, fitted, plot, terms) +importMethodsFrom(cplm, show, predict, vcov, residuals, resid, coef, fitted, + plot, terms) importMethodsFrom(Matrix, summary) export(MackChainLadder, MunichChainLadder, BootChainLadder, @@ -59,7 +62,6 @@ S3method(print, ClarkLDF) S3method(print, ClarkCapeCod) S3method(print, ata) - S3method(as.triangle, matrix) S3method(as.triangle, data.frame) S3method(as.data.frame, triangle) @@ -89,8 +91,10 @@ S3method(mean, BootChainLadder) S3method(vcov, clark) exportMethods(predict, Mse, summary, show, coerce, - "[", "$", "[[", "[<-", names, coef, vcov, residCov, residCor, - residuals, resid, rstandard, fitted, plot, cbind2, rbind2, dim) + "[", "$", "[[", "[<-", names, coef, + vcov, residCov, residCor, + residuals, resid, rstandard, fitted, + plot, cbind2, rbind2, dim) S3method(CDR, MackChainLadder) S3method(CDR, BootChainLadder) @@ -101,4 +105,8 @@ export(tweedieReserve) S3method(print, tweedieReserve) S3method(summary, tweedieReserve) +export(plotParms) +S3method(plotParms, ChainLadder) +#S3method(plotParms, MackChainLadder) + export(PaidIncurredChain) From 78de1857d88432e7b2a9d11f0c5f9d05e9679aab Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Tue, 18 Oct 2016 17:42:58 -0700 Subject: [PATCH 13/29] Fix TriangleName in Mack --- R/MackChainLadderFunctions.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/MackChainLadderFunctions.R b/R/MackChainLadderFunctions.R index b1686177..90f789a4 100755 --- a/R/MackChainLadderFunctions.R +++ b/R/MackChainLadderFunctions.R @@ -16,6 +16,7 @@ MackChainLadder <- function( tail.sigma=NULL, mse.method = "Mack") { + TriangleName <- deparse(substitute(Triangle)) ## idea: have a list for tail factor ## tail=list(f=FALSE, f.se=NULL, sigma=NULL, F.se=NULL) ## @@ -124,7 +125,7 @@ MackChainLadder <- function( output[["Total.ProcessRisk"]] <- attr(Total.SE, "processrisk") output[["Total.ParameterRisk"]] <- attr(Total.SE, "paramrisk") output[["tail"]] <- tail - output[["TriangleName"]] <- CL$TriangleName + output[["TriangleName"]] <- TriangleName output$est.sigma <- est.sigma output$tail <- tail.input output$tail.se <- tail.se From 814962365596d4d30dd10dfd5101a8de256f63c2 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Tue, 18 Oct 2016 17:43:23 -0700 Subject: [PATCH 14/29] First stab at plotParms.MackChainLadder --- R/plotParms.R | 72 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/R/plotParms.R b/R/plotParms.R index 22e0ad9c..835fcc3c 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -72,7 +72,7 @@ plot.cl.f1 <- function(x) { df$f.se[na_sigma] <- 0 P <- ggplot(df, aes_(x=~xx, y=~f1, label = ~label)) + geom_errorbar(aes(ymin=f1-f.se, ymax=f1+f.se), colour="black", width=.1) + - xlab(names(dimnames(x$Triangle))[1L]) + + xlab(names(dimnames(x$Triangle))[2L]) + geom_line(aes(colour = na_sigma, group = 1)) + geom_point(aes(colour = na_sigma)) + ggtitle("f-1 estimates") @@ -95,7 +95,7 @@ plot.cl.sigma <- function(x) { stringsAsFactors = FALSE) df$sigmapoint[na_sigma] <- 0 P <- ggplot(df, aes_(x=~xx, y=~sigma, label = ~label)) + - xlab(names(dimnames(x$Triangle))[1L]) + + xlab(names(dimnames(x$Triangle))[2L]) + geom_line(aes(colour = na_sigma, group = 1), na.rm = TRUE) + geom_point(aes_(y = ~sigmapoint, colour = ~na_sigma)) + ggtitle("sigma estimates") @@ -153,6 +153,49 @@ plot.cl.f.cv <- function(x) { } # Now MackCL +plotParms.MackChainLadder <- function(x, title, ...) { + p1 <- plot.mackcl.f(x) + theme(axis.title.y=element_blank()) + p2 <- plot.cl.f.se(x) + theme(axis.title.y=element_blank()) + p3 <- plot.cl.f.cv(x) + theme(axis.title.y=element_blank()) + p4 <- plot.cl.sigma(x) + theme(axis.title.y=element_blank()) + if (missing(title)) title <- paste0("MackChainLadder(", + x$TriangleName, + ") parameter estimates") + + marrangeGrob(grobs=list(p1, p2, p3, p4), ncol = 2, nrow = 2, + top = title) +} +plot.mackcl.f <- function(x) { + smmry <- suppressWarnings(lapply(x$Models, summary)) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + n <- length(f) + f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + f.cv <- f.se / (f-1) + sigma <- sapply(smmry, function(x) x$sigma) + na_sigma <- is.na(sigma) + # set the display order + src <- factor(c("regr", "est'd", "deflt", "input"), + levels = c("regr", "est'd", "deflt", "input")) + source <- rep(src[1L], n) + source[n] <- src[ifelse(is.logical(x$tail), + ifelse(x$tail, 2L, 3L), + 4L)] +# source[f==1] <- "f=1" + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f, f.se, sigma, na_sigma, f.cv, + f.cv.point = f.cv, + source, + stringsAsFactors = FALSE) + df$f.cv.point[source!="regr"] <- 0 + P <- ggplot(df, aes(x = xx, y = f, colour = source)) + + xlab(names(dimnames(x$Triangle))[2L]) + +# ylab("cv(f-1)") + + geom_line(aes(group = 1), na.rm = TRUE) + + geom_point() + +# geom_point(aes_(y=~f.cv.point, colour = ~source), na.rm = TRUE) + + ggtitle("f estimates") + P +} plot.MackCL.f <- function(x) { # require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) @@ -265,3 +308,28 @@ plot.MackCL.f.cv <- function(x) { if (all(!imputed)) P <- P + theme(legend.position="none") P } +plot.mackcl.f.cv <- function(x) { + smmry <- suppressWarnings(lapply(x$Models, summary)) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + n <- length(f) + f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + f.cv <- f.se / (f-1) + sigma <- sapply(smmry, function(x) x$sigma) + na_sigma <- is.na(sigma) + est_source <- rep("regr", n) + est_source[na_sigma] <- "sigma=NA" + est_source[f==1] <- "f=1" + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f, f.se, sigma, na_sigma, f.cv, + f.cv.point = f.cv, + est_source, + stringsAsFactors = FALSE) + df$f.cv.point[est_source!="regr"] <- 0 + P <- ggplot(df, aes(x=xx, y=f.cv, colour = est_source)) + + xlab(names(dimnames(x$Triangle))[2L]) + + ylab("cv(f-1)") + + geom_line(aes(group = 1), na.rm = TRUE) + + geom_point(aes_(y=~f.cv.point, colour = ~est_source), na.rm = TRUE) + + ggtitle("cv(f-1) estimates") + P +} From 9a6d73e18d454e5e31cc0bffe0dab11515176229 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Wed, 19 Oct 2016 20:08:07 -0700 Subject: [PATCH 15/29] add plot.MackChainLadder --- NAMESPACE | 2 +- R/plotParms.R | 289 ++++++++++++++++++++++++++--------------------- man/plotParms.Rd | 8 +- 3 files changed, 165 insertions(+), 134 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 1aae9be0..05e173a3 100755 --- a/NAMESPACE +++ b/NAMESPACE @@ -107,6 +107,6 @@ S3method(summary, tweedieReserve) export(plotParms) S3method(plotParms, ChainLadder) -#S3method(plotParms, MackChainLadder) +S3method(plotParms, MackChainLadder) export(PaidIncurredChain) diff --git a/R/plotParms.R b/R/plotParms.R index 835fcc3c..5267ae7d 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -19,7 +19,7 @@ plotParms.default <- function(x, ...){ plotParms.ChainLadder <- function(x, title, ...) { p1 <- plot.cl.f(x) + theme(axis.title.y=element_blank()) p2 <- plot.cl.f.se(x) + theme(axis.title.y=element_blank()) - p3 <- plot.cl.f.cv(x) + theme(axis.title.y=element_blank()) + p3 <- plot.cl.f1.cv(x) + theme(axis.title.y=element_blank()) p4 <- plot.cl.sigma(x) + theme(axis.title.y=element_blank()) if (missing(title)) title <- paste0("ChainLadder(", x$TriangleName, @@ -126,6 +126,32 @@ plot.cl.f.se <- function(x) { P } plot.cl.f.cv <- function(x) { + # require(ggplot2) + smmry <- suppressWarnings(lapply(x$Models, summary)) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + n <- length(f) + f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + f.cv <- f.se / f + sigma <- sapply(smmry, function(x) x$sigma) + na_sigma <- is.na(sigma) + est_source <- rep("regres", n) + est_source[na_sigma] <- "sigma=NA" + est_source[f==1] <- "f=1" + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f, f.se, sigma, na_sigma, f.cv, + f.cv.point = f.cv, + est_source, + stringsAsFactors = FALSE) + df$f.cv.point[est_source!="regres"] <- 0 + P <- ggplot(df, aes(x=xx, y=f.cv, colour = est_source)) + + xlab(names(dimnames(x$Triangle))[2L]) + + ylab("cv(f)") + + geom_line(aes(group = 1), na.rm = TRUE) + + geom_point(aes_(y=~f.cv.point, colour = ~est_source), na.rm = TRUE) + + ggtitle("cv(f) estimates") + P +} +plot.cl.f1.cv <- function(x) { # require(ggplot2) smmry <- suppressWarnings(lapply(x$Models, summary)) f <- sapply(smmry, function(x) x$coef["x","Estimate"]) @@ -134,7 +160,7 @@ plot.cl.f.cv <- function(x) { f.cv <- f.se / (f-1) sigma <- sapply(smmry, function(x) x$sigma) na_sigma <- is.na(sigma) - est_source <- rep("regr", n) + est_source <- rep("regres", n) est_source[na_sigma] <- "sigma=NA" est_source[f==1] <- "f=1" xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) @@ -142,7 +168,7 @@ plot.cl.f.cv <- function(x) { f.cv.point = f.cv, est_source, stringsAsFactors = FALSE) - df$f.cv.point[est_source!="regr"] <- 0 + df$f.cv.point[est_source!="regres"] <- 0 P <- ggplot(df, aes(x=xx, y=f.cv, colour = est_source)) + xlab(names(dimnames(x$Triangle))[2L]) + ylab("cv(f-1)") + @@ -155,9 +181,9 @@ plot.cl.f.cv <- function(x) { # Now MackCL plotParms.MackChainLadder <- function(x, title, ...) { p1 <- plot.mackcl.f(x) + theme(axis.title.y=element_blank()) - p2 <- plot.cl.f.se(x) + theme(axis.title.y=element_blank()) - p3 <- plot.cl.f.cv(x) + theme(axis.title.y=element_blank()) - p4 <- plot.cl.sigma(x) + theme(axis.title.y=element_blank()) + p2 <- plot.mackcl.f.se(x) + theme(axis.title.y=element_blank()) + p3 <- plot.mackcl.f1.cv(x) + theme(axis.title.y=element_blank()) + p4 <- plot.mackcl.sigma(x) + theme(axis.title.y=element_blank()) if (missing(title)) title <- paste0("MackChainLadder(", x$TriangleName, ") parameter estimates") @@ -167,27 +193,35 @@ plotParms.MackChainLadder <- function(x, title, ...) { } plot.mackcl.f <- function(x) { smmry <- suppressWarnings(lapply(x$Models, summary)) - f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + #f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + f <- x$f n <- length(f) - f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) - f.cv <- f.se / (f-1) - sigma <- sapply(smmry, function(x) x$sigma) - na_sigma <- is.na(sigma) + #f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + f.se <- x$f.se + if (length(f.se < n)) f.se <- c(f.se, NA) + #f.se[is.na(f.se)] <- 0 +# f.cv <- f.se / (f-1) +# sigma <- sapply(smmry, function(x) x$sigma) +# na_sigma <- is.na(sigma) # set the display order - src <- factor(c("regr", "est'd", "deflt", "input"), - levels = c("regr", "est'd", "deflt", "input")) + src <- factor(c("regres", "est'd", "default", "input", "NA"), + levels = c("regres", "est'd", "default", "input", "NA")) source <- rep(src[1L], n) source[n] <- src[ifelse(is.logical(x$tail), ifelse(x$tail, 2L, 3L), 4L)] + source.se <- rep(src[1L], n) + source.se[is.na(f.se)] <- src[5L] + f.se[is.na(f.se)] <- 0 # source[f==1] <- "f=1" xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f, f.se, sigma, na_sigma, f.cv, - f.cv.point = f.cv, - source, + df <- data.frame(xx, f, f.se, # sigma, na_sigma, f.cv, + # f.cv.point = f.cv, + source, source.se, stringsAsFactors = FALSE) - df$f.cv.point[source!="regr"] <- 0 + #df$f.cv.point[source!="regres"] <- 0 P <- ggplot(df, aes(x = xx, y = f, colour = source)) + + geom_errorbar(aes(ymin=f-f.se, ymax=f+f.se), colour="black", width=.1) + xlab(names(dimnames(x$Triangle))[2L]) + # ylab("cv(f-1)") + geom_line(aes(group = 1), na.rm = TRUE) + @@ -196,140 +230,135 @@ plot.mackcl.f <- function(x) { ggtitle("f estimates") P } -plot.MackCL.f <- function(x) { -# require(ggplot2) +plot.mackcl.sigma <- function(x) { + sigma <- x$sigma + n <- length(x$f) + if (length(sigma) < n) sigma <- c(sigma, NA) smmry <- suppressWarnings(lapply(x$Models, summary)) - f <- sapply(smmry, function(x) x$coef["x","Estimate"]) - n <- length(f) - f.se <- x$f.se #sapply(smmry, function(x) x$coef["x","Std. Error"]) - sigma <- sapply(smmry, function(x) x$sigma) - nobs <- as.character(sapply(x$Models, nobs)) - nasigma <- is.na(sigma) - xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f, f.se, sigma, nasigma, nobs, - label = nobs, - stringsAsFactors = FALSE) - P <- ggplot(df, aes_(x=~xx, y=~f, label = ~label)) + - geom_errorbar(aes(ymin=f-f.se, ymax=f+f.se), colour="black", width=.1) + - xlab(names(dimnames(x$Triangle))[1L]) + - geom_line(aes(colour = nasigma[1], group = 1)) + - geom_point(aes(colour = nasigma)) + - ggtitle("f estimates") - P <- P + theme(legend.position="none") - P -} -plot.MackCL.f1 <- function(x) { -# require(ggplot2) - smmry <- suppressWarnings(lapply(x$Models, summary)) - f1 <- sapply(smmry, function(x) x$coef["x","Estimate"]) - 1 - n <- length(f1) - f.se <- x$f.se #sapply(smmry, function(x) x$coef["x","Std. Error"]) - sigma <- sapply(smmry, function(x) x$sigma) - nobs <- as.character(sapply(x$Models, nobs)) - nasigma <- is.na(sigma) + sigmaregr <- sapply(smmry, function(x) x$sigma) + if (length(sigmaregr) < n) sigmaregr <- + c(sigmaregr, rep(NA, n - length(sigmaregr))) + ndx <- sigma != sigmaregr + ndx[is.na(ndx)] <- TRUE + src <- factor(c("regres", "log-linear", "Mack", "input", "NA"), + levels = c("regres", "log-linear", "Mack", "input", "NA")) + source <- rep(src[1L], n) + if (x$est.sigma[1] %in% "log-linear") source[ndx] <- src[2L] + else + if (x$est.sigma[1] %in% "Mack") source[ndx] <- src[3L] + else source[ndx] <- src[4L] + source[n] <- src[ifelse(is.null(x$tail.sigma), 5L, 2L)] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f1, f.se, sigma, nasigma, nobs, - label = nobs, + sigmaNoNAs <- sigma + + sigmaNoNAs[is.na(sigma)] <- 0 + df <- data.frame(xx, sigma, sigmaNoNAs, + source, stringsAsFactors = FALSE) - P <- ggplot(df, aes_(x=~xx, y=~f1, label = ~label)) + - geom_errorbar(aes(ymin=f1-f.se, ymax=f1+f.se), colour="black", width=.1) + - xlab(names(dimnames(x$Triangle))[1L]) + - geom_line(aes(colour = nasigma[1], group = 1)) + - geom_point(aes(colour = nasigma)) + - ggtitle("f-1 estimates") - P <- P + theme(legend.position="none") - P -} -plot.MackCL.sigma <- function(x) { -# require(ggplot2) - smmry <- suppressWarnings(lapply(x$Models, summary)) - #smmry <- lapply(x$Models, summary) - f <- sapply(smmry, function(x) x$coef["x","Estimate"]) - n <- length(f) - f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) - sigma <- sapply(smmry, function(x) x$sigma) - #nobs <- rep(">1", n) - imputed <- is.na(sigma) - nasigma <- is.na(sigma) - #nobs[nasigma] <- "T" - sigma[nasigma] <- x$sigma[imputed] - # df <- sapply(smmry, function(x) x$df[2L]) - xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, sigma, imputed, stringsAsFactors = FALSE) - P <- ggplot(df, aes(x=xx, y=sigma, colour = imputed)) + + P <- ggplot(df, aes(x = xx, y = sigma, colour = source)) + xlab(names(dimnames(x$Triangle))[2L]) + - geom_line(aes(colour = imputed[1], group = 1)) + - geom_point(aes(colour = imputed)) + - ggtitle("sigma estimates") - if (all(!nasigma)) P <- P + theme(legend.position="none") + geom_line(aes(colour = source, group = 1), na.rm = TRUE) + + geom_point(aes(y=sigmaNoNAs)) + + ggtitle("sigma estimates") P } -plot.MackCL.f.se <- function(x) { -# require(ggplot2) +plot.mackcl.f.se <- function(x) { + f.se <- x$f.se + n <- length(x$f) + if (length(f.se) < n) f.se <- c(f.se, NA) smmry <- suppressWarnings(lapply(x$Models, summary)) - f <- sapply(smmry, function(x) x$coef["x","Estimate"]) - n <- length(f) - f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) - f.cv <- f.se / (f-1) - sigma <- sapply(smmry, function(x) x$sigma) - imputed <- is.na(sigma) - sigma[imputed] <- x$sigma[imputed] - f.se[imputed] <- x$f.se[imputed] - #isna <- is.na(f.cv) - #sigma[isna] <- 0 + f.seregr <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + if (length(f.seregr) < n) f.seregr <- + c(f.seregr, rep(NA, n - length(f.seregr))) + ndx <- f.se != f.seregr + ndx[is.na(ndx)] <- TRUE + src <- factor(c("regres", "log-linear", "Mack", "input", "NA"), + levels = c("regres", "log-linear", "Mack", "input", "NA")) + source <- rep(src[1L], n) + if (x$est.sigma[1] %in% "log-linear") source[ndx] <- src[2L] + else + if (x$est.sigma[1] %in% "Mack") source[ndx] <- src[3L] + else source[ndx] <- src[4L] + source[n] <- src[ifelse(is.null(x$tail.f.se), 5L, 2L)] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f, f.se, sigma, imputed, f.cv, stringsAsFactors = FALSE) - P <- ggplot(df, aes(x=xx, y=f.se, colour = imputed)) + + f.seNoNAs <- f.se + + f.seNoNAs[is.na(f.se)] <- 0 + df <- data.frame(xx, f.se, f.seNoNAs, + source, + stringsAsFactors = FALSE) + P <- ggplot(df, aes(x = xx, y = f.se, colour = source)) + xlab(names(dimnames(x$Triangle))[2L]) + - geom_line(aes(colour = imputed[1], group = 1), na.rm = TRUE) + - geom_point(aes(colour = imputed), na.rm = TRUE) + + geom_line(aes(colour = source, group = 1), na.rm = TRUE) + + geom_point(aes(y=f.seNoNAs)) + ggtitle("f.se estimates") - if (all(!imputed)) P <- P + theme(legend.position="none") P } -plot.MackCL.f.cv <- function(x) { -# require(ggplot2) - smmry <- suppressWarnings(lapply(x$Models, summary)) - f <- sapply(smmry, function(x) x$coef["x","Estimate"]) +plot.mackcl.f1.cv <- function(x) { + f <- x$f n <- length(f) - f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) - sigma <- sapply(smmry, function(x) x$sigma) - imputed <- is.na(sigma) - sigma[imputed] <- x$sigma[imputed] - f.se[imputed] <- x$f.se[imputed] - f.cv <- f.se / (f-1) + f.se <- x$f.se + if (length(f.se) < n) f.se <- c(f.se, NA) + f1.cv <- f.se/ (f - 1) + smmry <- suppressWarnings(lapply(x$Models, summary)) + f.seregr <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + if (length(f.seregr) < n) f.seregr <- + c(f.seregr, rep(NA, n - length(f.seregr))) + ndx <- f.se != f.seregr + ndx[is.na(ndx)] <- TRUE + src <- factor(c("regres", "log-linear", "Mack", "input", "NA", "f=1"), + levels = c("regres", "log-linear", "Mack", "input", "NA", "f=1")) + source <- rep(src[1L], n) + if (x$est.sigma[1] %in% "log-linear") source[ndx] <- src[2L] + else + if (x$est.sigma[1] %in% "Mack") source[ndx] <- src[3L] + else source[ndx] <- src[4L] + source[n] <- src[ifelse(is.null(x$tail.f.se), 5L, 2L)] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f, f.se, sigma, imputed, f.cv, stringsAsFactors = FALSE) - P <- ggplot(df, aes(x=xx, y=f.cv, colour = imputed)) + + f1.cvNoNAs <- f1.cv + f1.cvNoNAs[is.na(f.se)] <- 0 + df <- data.frame(xx, f1.cv, f1.cvNoNAs, + source, + stringsAsFactors = FALSE) + P <- ggplot(df, aes(x = xx, y = f1.cv, colour = source)) + xlab(names(dimnames(x$Triangle))[2L]) + - geom_line(aes(colour = imputed[1], group = 1), na.rm = TRUE) + - geom_point(aes(colour = imputed), na.rm = TRUE) + - ggtitle("f.cv estimates") - if (all(!imputed)) P <- P + theme(legend.position="none") + ylab("cv(f-1)") + + geom_line(aes(colour = source, group = 1), na.rm = TRUE) + + geom_point(aes(y=f1.cvNoNAs)) + + ggtitle("cv(f-1) estimates") P } plot.mackcl.f.cv <- function(x) { - smmry <- suppressWarnings(lapply(x$Models, summary)) - f <- sapply(smmry, function(x) x$coef["x","Estimate"]) + f <- x$f n <- length(f) - f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) - f.cv <- f.se / (f-1) - sigma <- sapply(smmry, function(x) x$sigma) - na_sigma <- is.na(sigma) - est_source <- rep("regr", n) - est_source[na_sigma] <- "sigma=NA" - est_source[f==1] <- "f=1" + f.se <- x$f.se + if (length(f.se) < n) f.se <- c(f.se, NA) + f.cv <- f.se/ f + smmry <- suppressWarnings(lapply(x$Models, summary)) + f.seregr <- sapply(smmry, function(x) x$coef["x","Std. Error"]) + if (length(f.seregr) < n) f.seregr <- + c(f.seregr, rep(NA, n - length(f.seregr))) + ndx <- f.se != f.seregr + ndx[is.na(ndx)] <- TRUE + src <- factor(c("regres", "log-linear", "Mack", "input", "NA", "f=1"), + levels = c("regres", "log-linear", "Mack", "input", "NA", "f=1")) + source <- rep(src[1L], n) + if (x$est.sigma[1] %in% "log-linear") source[ndx] <- src[2L] + else + if (x$est.sigma[1] %in% "Mack") source[ndx] <- src[3L] + else source[ndx] <- src[4L] + source[n] <- src[ifelse(is.null(x$tail.f.se), 5L, 2L)] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f, f.se, sigma, na_sigma, f.cv, - f.cv.point = f.cv, - est_source, + f.cvNoNAs <- f.cv + f.cvNoNAs[is.na(f.se)] <- 0 + df <- data.frame(xx, f.cv, f.cvNoNAs, + source, stringsAsFactors = FALSE) - df$f.cv.point[est_source!="regr"] <- 0 - P <- ggplot(df, aes(x=xx, y=f.cv, colour = est_source)) + + P <- ggplot(df, aes(x = xx, y = f.cv, colour = source)) + xlab(names(dimnames(x$Triangle))[2L]) + - ylab("cv(f-1)") + - geom_line(aes(group = 1), na.rm = TRUE) + - geom_point(aes_(y=~f.cv.point, colour = ~est_source), na.rm = TRUE) + - ggtitle("cv(f-1) estimates") + ylab("cv(f)") + + geom_line(aes(colour = source, group = 1), na.rm = TRUE) + + geom_point(aes(y=f.cvNoNAs)) + + ggtitle("cv(f) estimates") P } diff --git a/man/plotParms.Rd b/man/plotParms.Rd index 63cf763d..b5445640 100644 --- a/man/plotParms.Rd +++ b/man/plotParms.Rd @@ -1,6 +1,6 @@ \name{plotParms} \alias{plotParms} -%\alias{plotParms.MackChainLadder} +\alias{plotParms.MackChainLadder} \alias{plotParms.ChainLadder} \alias{plotParms.default} \title{ @@ -18,6 +18,7 @@ ChainLadder and MackChainLadder. \usage{ plotParms(x, \dots) \method{plotParms}{ChainLadder}(x, title, \dots) +\method{plotParms}{MackChainLadder}(x, title, \dots) \method{plotParms}{default}(x, \dots) } @@ -34,15 +35,16 @@ defaults to something the class author deems appropriate. TBD } \value{ -In the case of class ChainLadder, +In the case of class ChainLadder or MackChainLadder, list of class arrangelist returned by gridExtra::marrangeGrob. In all other cases, a stop error is executed at this time. } \author{ -Dan Murphy for class ChainLadder. +dmm } \examples{ plotParms(chainladder(GenIns)) +plotParms(MackChainLadder(GenIns)) } \keyword{ models } From fa0ef081689a5d3b50dc993d3c6fc00938a55518 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Thu, 20 Oct 2016 16:15:00 -0700 Subject: [PATCH 16/29] fix close paren, eliminate commented lines --- R/plotParms.R | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/R/plotParms.R b/R/plotParms.R index 5267ae7d..2e1024e5 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -193,16 +193,11 @@ plotParms.MackChainLadder <- function(x, title, ...) { } plot.mackcl.f <- function(x) { smmry <- suppressWarnings(lapply(x$Models, summary)) - #f <- sapply(smmry, function(x) x$coef["x","Estimate"]) f <- x$f n <- length(f) #f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) f.se <- x$f.se - if (length(f.se < n)) f.se <- c(f.se, NA) - #f.se[is.na(f.se)] <- 0 -# f.cv <- f.se / (f-1) -# sigma <- sapply(smmry, function(x) x$sigma) -# na_sigma <- is.na(sigma) + if (length(f.se) < n) f.se <- c(f.se, NA) # set the display order src <- factor(c("regres", "est'd", "default", "input", "NA"), levels = c("regres", "est'd", "default", "input", "NA")) @@ -213,20 +208,15 @@ plot.mackcl.f <- function(x) { source.se <- rep(src[1L], n) source.se[is.na(f.se)] <- src[5L] f.se[is.na(f.se)] <- 0 -# source[f==1] <- "f=1" xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) df <- data.frame(xx, f, f.se, # sigma, na_sigma, f.cv, - # f.cv.point = f.cv, source, source.se, stringsAsFactors = FALSE) - #df$f.cv.point[source!="regres"] <- 0 P <- ggplot(df, aes(x = xx, y = f, colour = source)) + geom_errorbar(aes(ymin=f-f.se, ymax=f+f.se), colour="black", width=.1) + xlab(names(dimnames(x$Triangle))[2L]) + -# ylab("cv(f-1)") + geom_line(aes(group = 1), na.rm = TRUE) + geom_point() + -# geom_point(aes_(y=~f.cv.point, colour = ~source), na.rm = TRUE) + ggtitle("f estimates") P } @@ -247,7 +237,7 @@ plot.mackcl.sigma <- function(x) { else if (x$est.sigma[1] %in% "Mack") source[ndx] <- src[3L] else source[ndx] <- src[4L] - source[n] <- src[ifelse(is.null(x$tail.sigma), 5L, 2L)] + source[n] <- src[ifelse(is.null(x$tail.sigma.input), 5L, 2L)] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) sigmaNoNAs <- sigma @@ -279,7 +269,7 @@ plot.mackcl.f.se <- function(x) { else if (x$est.sigma[1] %in% "Mack") source[ndx] <- src[3L] else source[ndx] <- src[4L] - source[n] <- src[ifelse(is.null(x$tail.f.se), 5L, 2L)] + source[n] <- src[ifelse(is.null(x$tail.se.input), 5L, 2L)] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) f.seNoNAs <- f.se From e1898626fe0b8d539123a40fac9419b944b3c1c6 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Thu, 20 Oct 2016 16:15:22 -0700 Subject: [PATCH 17/29] Need to save more MackChainLadder input parameters --- R/MackChainLadderFunctions.R | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/R/MackChainLadderFunctions.R b/R/MackChainLadderFunctions.R index 90f789a4..4279251c 100755 --- a/R/MackChainLadderFunctions.R +++ b/R/MackChainLadderFunctions.R @@ -21,7 +21,9 @@ MackChainLadder <- function( ## tail=list(f=FALSE, f.se=NULL, sigma=NULL, F.se=NULL) ## tail.input <- tail - # 2013-02-25 Parameter risk recursive formula may have a third term per + tail.se.input <- tail.se + tail.sigma.input <- tail.sigma + # 2013-02-25 Parameter risk recursive formula may have a third term per # Murphy and BBMW if (! mse.method %in% c("Mack", "Independence")) stop("mse.method must be 'Mack' or 'Independence'") if (! est.sigma[1] %in% c("Mack", "log-linear")) { @@ -128,8 +130,8 @@ MackChainLadder <- function( output[["TriangleName"]] <- TriangleName output$est.sigma <- est.sigma output$tail <- tail.input - output$tail.se <- tail.se - output$tail.sigma <- tail.sigma + output$tail.se <- tail.se.input + output$tail.sigma <- tail.sigma.input output$mse.method <- mse.method class(output) <- c("MackChainLadder", "TriangleModel", "list") return(output) From 3f072b83852fd3732e9d21b8f582e9d7e6d0b602 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Sun, 23 Oct 2016 11:47:44 -0700 Subject: [PATCH 18/29] Save arguments --- R/MackChainLadderFunctions.R | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/R/MackChainLadderFunctions.R b/R/MackChainLadderFunctions.R index 4279251c..be1131a5 100755 --- a/R/MackChainLadderFunctions.R +++ b/R/MackChainLadderFunctions.R @@ -23,6 +23,7 @@ MackChainLadder <- function( tail.input <- tail tail.se.input <- tail.se tail.sigma.input <- tail.sigma + mse.method.input <- mse.method # 2013-02-25 Parameter risk recursive formula may have a third term per # Murphy and BBMW if (! mse.method %in% c("Mack", "Independence")) stop("mse.method must be 'Mack' or 'Independence'") @@ -128,11 +129,12 @@ MackChainLadder <- function( output[["Total.ParameterRisk"]] <- attr(Total.SE, "paramrisk") output[["tail"]] <- tail output[["TriangleName"]] <- TriangleName - output$est.sigma <- est.sigma - output$tail <- tail.input - output$tail.se <- tail.se.input - output$tail.sigma <- tail.sigma.input - output$mse.method <- mse.method + output[["est.sigma"]] <- est.sigma + output[["tail.input"]] <- tail.input + output[["tail.se.input"]] <- tail.se.input + output[["tail.sigma.input"]] <- tail.sigma.input + output[["mse.method"]] <- mse.method + output[["mse.method.input"]] <- mse.method.input class(output) <- c("MackChainLadder", "TriangleModel", "list") return(output) } From 9bf5eb1d1eb11e73c43040056837bbdeba93cff6 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Sun, 23 Oct 2016 14:42:29 -0700 Subject: [PATCH 19/29] Close to final draft Six plots each. 'lm' r.t. 'regres', and other tweaks. Cleaned up code to be more consistent, extensible. --- R/plotParms.R | 362 +++++++++++++++++++++++++++-------------------- man/plotParms.Rd | 22 ++- 2 files changed, 228 insertions(+), 156 deletions(-) diff --git a/R/plotParms.R b/R/plotParms.R index 2e1024e5..08812602 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -11,199 +11,228 @@ #library(ggplot2) #library(grid) #library(gridExtra) -plotParms <- function(x, ...) UseMethod("plotParms") +# In case need for aes_: see exchange and final solution at link below +# http://stackoverflow.com/questions/9439256/ +# how-can-i-handle-r-cmd-check-no-visible-binding-for- +# global-variable-notes-when + +plotParms <- function(x, which, ncol, nrow, title, ...) UseMethod("plotParms") plotParms.default <- function(x, ...){ stop("No 'plotParms' method exists for objects of class ", class(x)) } -plotParms.ChainLadder <- function(x, title, ...) { - p1 <- plot.cl.f(x) + theme(axis.title.y=element_blank()) - p2 <- plot.cl.f.se(x) + theme(axis.title.y=element_blank()) - p3 <- plot.cl.f1.cv(x) + theme(axis.title.y=element_blank()) - p4 <- plot.cl.sigma(x) + theme(axis.title.y=element_blank()) - if (missing(title)) title <- paste0("ChainLadder(", +plotParms.ChainLadder <- function(x, which = c(1L, 3L, 4L, 6L), + ncol = min(2L, length(which)), + nrow = ceiling(length(which) / ncol), + title, ...) { + grobs <- lapply(which, function(i) + switch(i, + plot.cl.f(x) + theme(axis.title.y=element_blank()), + plot.cl.f1(x) + theme(axis.title.y=element_blank()), + plot.cl.sigma(x) + theme(axis.title.y=element_blank()), + plot.cl.f.se(x) + theme(axis.title.y=element_blank()), + plot.cl.f.cv(x) + theme(axis.title.y=element_blank()), + plot.cl.f1.cv(x) + theme(axis.title.y=element_blank()) + ) + ) + if (missing(title)) title <- paste0("chainladder(", x$TriangleName, ") parameter estimates") - - marrangeGrob(grobs=list(p1, p2, p3, p4), ncol = 2, nrow = 2, - top = title) + + marrangeGrob(grobs = grobs, ncol = ncol, nrow = nrow, top = title, ...) } plot.cl.f <- function(x) { -# require(ggplot2) + n <- length(x$Models) smmry <- suppressWarnings(lapply(x$Models, summary)) f <- sapply(smmry, function(x) x$coef["x","Estimate"]) - n <- length(f) f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) - sigma <- sapply(smmry, function(x) x$sigma) - nobs <- as.character(sapply(x$Models, nobs)) - na_sigma <- is.na(sigma) + legend_captions <- c("lm", "NA") + src <- factor(legend_captions, levels = legend_captions) + source <- rep(src[1L], n) + source[is.na(f.se)] <- src[2L] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f, f.se, sigma, na_sigma, nobs, - label = nobs, + df <- data.frame(xx, f.se, + source, stringsAsFactors = FALSE) - df$f.se[na_sigma] <- 0 - # Need for aes_: see exchange at link (wrapped) below - # and final solution - # http://stackoverflow.com/questions/9439256/ - # how-can-i-handle-r-cmd-check-no-visible-binding-for- - # global-variable-notes-when - P <- ggplot(df, aes_(x=~xx, y=~f, label = ~label)) + - geom_errorbar(aes(ymin=f-f.se, ymax=f+f.se), colour="black", width=.1) + - xlab(names(dimnames(x$Triangle))[1L]) + - geom_line(aes(colour = na_sigma, group = 1)) + - geom_point(aes(colour = na_sigma)) + - ggtitle("f estimates") - if (all(!na_sigma)) P <- P + theme(legend.position="none") + P <- ggplot(df, aes(x = xx, y = f, colour = source)) + + geom_errorbar(aes(ymin=f-f.se, ymax=f+f.se), colour="black", width=.1, na.rm = TRUE) + + xlab(names(dimnames(x$Triangle))[2L]) + + geom_line(aes(group = 1), na.rm = TRUE) + + geom_point() + + ggtitle("f estimates") P } plot.cl.f1 <- function(x) { -# require(ggplot2) + n <- length(x$Models) smmry <- suppressWarnings(lapply(x$Models, summary)) - f1 <- sapply(smmry, function(x) x$coef["x","Estimate"]) - 1 - n <- length(f1) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) - 1 f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) - sigma <- sapply(smmry, function(x) x$sigma) - nobs <- as.character(sapply(x$Models, nobs)) - na_sigma <- is.na(sigma) + legend_captions <- c("lm", "NA") + src <- factor(legend_captions, levels = legend_captions) + source <- rep(src[1L], n) + source[is.na(f.se)] <- src[2L] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f1, f.se, sigma, na_sigma, nobs, - label = nobs, + df <- data.frame(xx, f.se, + source, stringsAsFactors = FALSE) - df$f.se[na_sigma] <- 0 - P <- ggplot(df, aes_(x=~xx, y=~f1, label = ~label)) + - geom_errorbar(aes(ymin=f1-f.se, ymax=f1+f.se), colour="black", width=.1) + + P <- ggplot(df, aes(x = xx, y = f, colour = source)) + + geom_errorbar(aes(ymin=f-f.se, ymax=f+f.se), colour="black", width=.1, na.rm = TRUE) + xlab(names(dimnames(x$Triangle))[2L]) + - geom_line(aes(colour = na_sigma, group = 1)) + - geom_point(aes(colour = na_sigma)) + - ggtitle("f-1 estimates") - if (all(!na_sigma)) P <- P + theme(legend.position="none") + geom_line(aes(group = 1), na.rm = TRUE) + + geom_point() + + ggtitle("f-1 estimates") P } plot.cl.sigma <- function(x) { -# require(ggplot2) + # require(ggplot2) + n <- length(x$Models) smmry <- suppressWarnings(lapply(x$Models, summary)) - f <- sapply(smmry, function(x) x$coef["x","Estimate"]) - n <- length(f) - f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) sigma <- sapply(smmry, function(x) x$sigma) - nobs <- as.character(sapply(x$Models, nobs)) - na_sigma <- is.na(sigma) + legend_captions <- c("lm", "NA") + src <- factor(legend_captions, levels = legend_captions) + source <- rep(src[1L], n) + source[is.na(sigma)] <- src[2L] + sigmaNoNAs <- sigma + sigmaNoNAs[is.na(sigma)] <- 0 xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f.se, sigma, na_sigma, nobs, - sigmapoint = sigma, - label = nobs, + df <- data.frame(xx, sigma, sigmaNoNAs, + source, stringsAsFactors = FALSE) - df$sigmapoint[na_sigma] <- 0 - P <- ggplot(df, aes_(x=~xx, y=~sigma, label = ~label)) + + P <- ggplot(df, aes(x = xx, y = sigma, colour = source)) + xlab(names(dimnames(x$Triangle))[2L]) + - geom_line(aes(colour = na_sigma, group = 1), na.rm = TRUE) + - geom_point(aes_(y = ~sigmapoint, colour = ~na_sigma)) + - ggtitle("sigma estimates") - if (all(!na_sigma)) P <- P + theme(legend.position="none") + geom_line(aes(colour = source, group = 1), na.rm = TRUE) + + geom_point(aes(y=sigmaNoNAs)) + + ggtitle("sigma estimates") P } plot.cl.f.se <- function(x) { -# require(ggplot2) + # require(ggplot2) + n <- length(x$Models) smmry <- suppressWarnings(lapply(x$Models, summary)) - f <- sapply(smmry, function(x) x$coef["x","Estimate"]) - n <- length(f) f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) - sigma <- sapply(smmry, function(x) x$sigma) - na_sigma <- is.na(sigma) - #isna <- is.na(f.cv) - #sigma[isna] <- 0 + legend_captions <- c("lm", "NA") + src <- factor(legend_captions, levels = legend_captions) + source <- rep(src[1L], n) + source[is.na(f.se)] <- src[2L] + f.seNoNAs <- f.se + f.seNoNAs[is.na(f.se)] <- 0 xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f, f.se, sigma, na_sigma, - f.se.point = f.se, + df <- data.frame(xx, f.se, f.seNoNAs, + source, stringsAsFactors = FALSE) - df$f.se.point[na_sigma] <- 0 - P <- ggplot(df, aes(x=xx, y=f.se, colour = na_sigma)) + + P <- ggplot(df, aes(x = xx, y = f.se, colour = source)) + xlab(names(dimnames(x$Triangle))[2L]) + - geom_line(aes(colour = na_sigma, group = 1), na.rm = TRUE) + - geom_point(aes_(y = ~f.se.point, colour = ~na_sigma), na.rm = TRUE) + + geom_line(aes(colour = source, group = 1), na.rm = TRUE) + + geom_point(aes(y = f.seNoNAs)) + ggtitle("f.se estimates") - if (all(!na_sigma)) P <- P + theme(legend.position="none") P } plot.cl.f.cv <- function(x) { - # require(ggplot2) + n <- length(x$Models) smmry <- suppressWarnings(lapply(x$Models, summary)) f <- sapply(smmry, function(x) x$coef["x","Estimate"]) - n <- length(f) f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) f.cv <- f.se / f - sigma <- sapply(smmry, function(x) x$sigma) - na_sigma <- is.na(sigma) - est_source <- rep("regres", n) - est_source[na_sigma] <- "sigma=NA" - est_source[f==1] <- "f=1" + legend_captions <- c("lm", "NA") + src <- factor(legend_captions, levels = legend_captions) + source <- rep(src[1L], n) + source[is.na(f.cv)] <- src[2L] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f, f.se, sigma, na_sigma, f.cv, - f.cv.point = f.cv, - est_source, + df <- data.frame(xx, f.cv, + source, stringsAsFactors = FALSE) - df$f.cv.point[est_source!="regres"] <- 0 - P <- ggplot(df, aes(x=xx, y=f.cv, colour = est_source)) + + P <- ggplot(df, aes(x = xx, y = f.cv, colour = source)) + xlab(names(dimnames(x$Triangle))[2L]) + ylab("cv(f)") + geom_line(aes(group = 1), na.rm = TRUE) + - geom_point(aes_(y=~f.cv.point, colour = ~est_source), na.rm = TRUE) + + geom_point(na.rm = TRUE) + ggtitle("cv(f) estimates") P } plot.cl.f1.cv <- function(x) { -# require(ggplot2) + n <- length(x$Models) smmry <- suppressWarnings(lapply(x$Models, summary)) - f <- sapply(smmry, function(x) x$coef["x","Estimate"]) - n <- length(f) + f <- sapply(smmry, function(x) x$coef["x","Estimate"]) - 1 f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) - f.cv <- f.se / (f-1) - sigma <- sapply(smmry, function(x) x$sigma) - na_sigma <- is.na(sigma) - est_source <- rep("regres", n) - est_source[na_sigma] <- "sigma=NA" - est_source[f==1] <- "f=1" + f.cv <- f.se / f + legend_captions <- c("lm", "NA") + src <- factor(legend_captions, levels = legend_captions) + source <- rep(src[1L], n) + source[is.na(f.cv)] <- src[2L] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) - df <- data.frame(xx, f, f.se, sigma, na_sigma, f.cv, - f.cv.point = f.cv, - est_source, + df <- data.frame(xx, f.cv, + source, stringsAsFactors = FALSE) - df$f.cv.point[est_source!="regres"] <- 0 - P <- ggplot(df, aes(x=xx, y=f.cv, colour = est_source)) + + P <- ggplot(df, aes(x = xx, y = f.cv, colour = source)) + xlab(names(dimnames(x$Triangle))[2L]) + - ylab("cv(f-1)") + + ylab("cv(f)") + geom_line(aes(group = 1), na.rm = TRUE) + - geom_point(aes_(y=~f.cv.point, colour = ~est_source), na.rm = TRUE) + + geom_point(na.rm = TRUE) + ggtitle("cv(f-1) estimates") P } # Now MackCL -plotParms.MackChainLadder <- function(x, title, ...) { - p1 <- plot.mackcl.f(x) + theme(axis.title.y=element_blank()) - p2 <- plot.mackcl.f.se(x) + theme(axis.title.y=element_blank()) - p3 <- plot.mackcl.f1.cv(x) + theme(axis.title.y=element_blank()) - p4 <- plot.mackcl.sigma(x) + theme(axis.title.y=element_blank()) +plotParms.MackChainLadder <- function(x, which = c(1L, 3L, 4L, 6L), + ncol = min(2L, length(which)), + nrow = ceiling(length(which) / ncol), + title, ...) { + grobs <- lapply(which, function(i) + switch(i, + plot.mackcl.f(x) + theme(axis.title.y=element_blank()), + plot.mackcl.f1(x) + theme(axis.title.y=element_blank()), + plot.mackcl.sigma(x) + theme(axis.title.y=element_blank()), + plot.mackcl.f.se(x) + theme(axis.title.y=element_blank()), + plot.mackcl.f.cv(x) + theme(axis.title.y=element_blank()), + plot.mackcl.f1.cv(x) + theme(axis.title.y=element_blank()) + ) + ) if (missing(title)) title <- paste0("MackChainLadder(", x$TriangleName, ") parameter estimates") - marrangeGrob(grobs=list(p1, p2, p3, p4), ncol = 2, nrow = 2, - top = title) + marrangeGrob(grobs = grobs, ncol = ncol, nrow = nrow, top = title, ...) } plot.mackcl.f <- function(x) { smmry <- suppressWarnings(lapply(x$Models, summary)) f <- x$f n <- length(f) - #f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) f.se <- x$f.se if (length(f.se) < n) f.se <- c(f.se, NA) - # set the display order - src <- factor(c("regres", "est'd", "default", "input", "NA"), - levels = c("regres", "est'd", "default", "input", "NA")) + # set display order + legend_captions <- c("lm", "log-lin", "default", "input", "NA") + src <- factor(legend_captions, levels = legend_captions) + source <- rep(src[1L], n) + source[n] <- src[ifelse(is.logical(x$tail.input), + ifelse(x$tail.input, 2L, 3L), + 4L)] + source.se <- rep(src[1L], n) + source.se[is.na(f.se)] <- src[5L] + f.se[is.na(f.se)] <- 0 + xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) + df <- data.frame(xx, f, f.se, # sigma, na_sigma, f.cv, + source, source.se, + stringsAsFactors = FALSE) + P <- ggplot(df, aes(x = xx, y = f, colour = source)) + + geom_errorbar(aes(ymin=f-f.se, ymax=f+f.se), colour="black", width=.1) + + xlab(names(dimnames(x$Triangle))[2L]) + + geom_line(aes(group = 1), na.rm = TRUE) + + geom_point() + + ggtitle("f estimates") + P +} +plot.mackcl.f1 <- function(x) { + smmry <- suppressWarnings(lapply(x$Models, summary)) + f <- x$f - 1 + n <- length(f) + f.se <- x$f.se + if (length(f.se) < n) f.se <- c(f.se, NA) + # set display order + legend_captions <- c("lm", "log-lin", "default", "input", "NA") + src <- factor(legend_captions, levels = legend_captions) source <- rep(src[1L], n) - source[n] <- src[ifelse(is.logical(x$tail), - ifelse(x$tail, 2L, 3L), + source[n] <- src[ifelse(is.logical(x$tail.input), + ifelse(x$tail.input, 2L, 3L), 4L)] source.se <- rep(src[1L], n) source.se[is.na(f.se)] <- src[5L] @@ -228,16 +257,25 @@ plot.mackcl.sigma <- function(x) { sigmaregr <- sapply(smmry, function(x) x$sigma) if (length(sigmaregr) < n) sigmaregr <- c(sigmaregr, rep(NA, n - length(sigmaregr))) - ndx <- sigma != sigmaregr - ndx[is.na(ndx)] <- TRUE - src <- factor(c("regres", "log-linear", "Mack", "input", "NA"), - levels = c("regres", "log-linear", "Mack", "input", "NA")) + notregr <- sigma != sigmaregr + notregr[is.na(notregr)] <- TRUE + # set display order + legend_captions <- + c("lm", "log-lin", "Mack", "input", "input-x", "NA") + src <- factor(legend_captions, levels = legend_captions) source <- rep(src[1L], n) - if (x$est.sigma[1] %in% "log-linear") source[ndx] <- src[2L] + # For periods with insufficient data to estimate sigma, + # MackChainLadder has ways to inpute a value + if (x$est.sigma[1] %in% "log-linear") source[notregr] <- src[2L] else - if (x$est.sigma[1] %in% "Mack") source[ndx] <- src[3L] - else source[ndx] <- src[4L] - source[n] <- src[ifelse(is.null(x$tail.sigma.input), 5L, 2L)] + if (x$est.sigma[1] %in% "Mack") source[notregr] <- src[3L] + else source[notregr] <- src[4L] + # tail + if (is.null(x$tail.sigma.input)){ + if (x$f[n] > 1) source[n] <- src[2L] + else source[n] <- src[6L] + } else if (!x$tail.input) source[n] <- src[5L] + else source[n] <- src[4L] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) sigmaNoNAs <- sigma @@ -256,20 +294,39 @@ plot.mackcl.f.se <- function(x) { f.se <- x$f.se n <- length(x$f) if (length(f.se) < n) f.se <- c(f.se, NA) + sigma <- x$sigma + if (length(sigma) < n) sigma <- c(sigma, NA) smmry <- suppressWarnings(lapply(x$Models, summary)) f.seregr <- sapply(smmry, function(x) x$coef["x","Std. Error"]) if (length(f.seregr) < n) f.seregr <- c(f.seregr, rep(NA, n - length(f.seregr))) - ndx <- f.se != f.seregr - ndx[is.na(ndx)] <- TRUE - src <- factor(c("regres", "log-linear", "Mack", "input", "NA"), - levels = c("regres", "log-linear", "Mack", "input", "NA")) + notregr <- f.se != f.seregr + notregr[is.na(notregr)] <- TRUE + # set display order + legend_captions <- + c("lm", "log-lin", "calc", "Mack", "input", "input-x", "NA") + src <- factor(legend_captions, levels = legend_captions) source <- rep(src[1L], n) - if (x$est.sigma[1] %in% "log-linear") source[ndx] <- src[2L] - else - if (x$est.sigma[1] %in% "Mack") source[ndx] <- src[3L] - else source[ndx] <- src[4L] - source[n] <- src[ifelse(is.null(x$tail.se.input), 5L, 2L)] + # Currently, f.se (o/t tail) can get a value in two ways: + # As a result of the regression (notregr = FALSE) or as a result of + # a calculation based on an imputed sigma and f (notregr = TRUE). + source[notregr] <- src[3L] + # tail.se can get a value in two ways: input or estimated (log-linear) + # input: If argument tail=FALSE, then the user does not want a tail + # in the model, so although tail.se was provided, it will + # be ignored -- "input-x" + # estimated: + # It will be estimated when the tail > 1.000. + # Here, we cannot take the tail from x$tail b/c + # in MackChainLadder when argument tail = TRUE the output value + # named "tail" is the 'lm' object used to estimate it (the tail). + # Therefore, take actual tail value from last f to see if > unity. + if (is.null(x$tail.se.input)) { # tail.se not provided + if (x$f[n] > 1) source[n] <- src[2L] # tail.se est'd via log-linear + else source[n] <- src[7L] + } else if (!x$tail.input) source[n] <- src[6L] # tail not est'd so + # input tail.se ignored + else source[n] <- src[5L] # tail estimated therefore input tail.se used xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) f.seNoNAs <- f.se @@ -289,21 +346,22 @@ plot.mackcl.f1.cv <- function(x) { n <- length(f) f.se <- x$f.se if (length(f.se) < n) f.se <- c(f.se, NA) + sigma <- x$sigma + if (length(sigma) < n) sigma <- c(sigma, NA) f1.cv <- f.se/ (f - 1) smmry <- suppressWarnings(lapply(x$Models, summary)) f.seregr <- sapply(smmry, function(x) x$coef["x","Std. Error"]) if (length(f.seregr) < n) f.seregr <- c(f.seregr, rep(NA, n - length(f.seregr))) - ndx <- f.se != f.seregr - ndx[is.na(ndx)] <- TRUE - src <- factor(c("regres", "log-linear", "Mack", "input", "NA", "f=1"), - levels = c("regres", "log-linear", "Mack", "input", "NA", "f=1")) + notregr <- f.se != f.seregr + notregr[is.na(notregr)] <- TRUE + # set display order + legend_captions <- c("calc", "NA") + src <- factor(legend_captions, levels = legend_captions) + # Currently, the cv is always the result of a calculation. + # Only exception (NA) is in the tail when argument tail=FALSE source <- rep(src[1L], n) - if (x$est.sigma[1] %in% "log-linear") source[ndx] <- src[2L] - else - if (x$est.sigma[1] %in% "Mack") source[ndx] <- src[3L] - else source[ndx] <- src[4L] - source[n] <- src[ifelse(is.null(x$tail.f.se), 5L, 2L)] + if (is.logical(x$tail.input)) if (!x$tail.input) source[n] <- src[2L] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) f1.cvNoNAs <- f1.cv f1.cvNoNAs[is.na(f.se)] <- 0 @@ -323,21 +381,23 @@ plot.mackcl.f.cv <- function(x) { n <- length(f) f.se <- x$f.se if (length(f.se) < n) f.se <- c(f.se, NA) + sigma <- x$sigma + if (length(sigma) < n) sigma <- c(sigma, NA) f.cv <- f.se/ f smmry <- suppressWarnings(lapply(x$Models, summary)) f.seregr <- sapply(smmry, function(x) x$coef["x","Std. Error"]) if (length(f.seregr) < n) f.seregr <- c(f.seregr, rep(NA, n - length(f.seregr))) - ndx <- f.se != f.seregr - ndx[is.na(ndx)] <- TRUE - src <- factor(c("regres", "log-linear", "Mack", "input", "NA", "f=1"), - levels = c("regres", "log-linear", "Mack", "input", "NA", "f=1")) + notregr <- f.se != f.seregr + notregr[is.na(notregr)] <- TRUE + + # set display order + legend_captions <- c("calc", "NA") + src <- factor(legend_captions, levels = legend_captions) + # Currently, the cv is always the result of a calculation. + # Only exception (NA) is in the tail when argument tail=FALSE source <- rep(src[1L], n) - if (x$est.sigma[1] %in% "log-linear") source[ndx] <- src[2L] - else - if (x$est.sigma[1] %in% "Mack") source[ndx] <- src[3L] - else source[ndx] <- src[4L] - source[n] <- src[ifelse(is.null(x$tail.f.se), 5L, 2L)] + if (is.logical(x$tail.input)) if (!x$tail.input) source[n] <- src[2L] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) f.cvNoNAs <- f.cv f.cvNoNAs[is.na(f.se)] <- 0 diff --git a/man/plotParms.Rd b/man/plotParms.Rd index b5445640..e7c9ee98 100644 --- a/man/plotParms.Rd +++ b/man/plotParms.Rd @@ -16,9 +16,9 @@ ChainLadder and MackChainLadder. } \usage{ -plotParms(x, \dots) -\method{plotParms}{ChainLadder}(x, title, \dots) -\method{plotParms}{MackChainLadder}(x, title, \dots) +plotParms(x, which, ncol, nrow, title, \dots) +\method{plotParms}{ChainLadder}(x, which = c(1, 3, 4, 6), ncol, nrow, title, \dots) +\method{plotParms}{MackChainLadder}(x, which = c(1, 3, 4, 6), ncol, nrow, title, \dots) \method{plotParms}{default}(x, \dots) } @@ -26,13 +26,25 @@ plotParms(x, \dots) \arguments{ \item{x}{object whose parameters are to be visualized} + \item{which}{if a subset of the plots is required, + specify a subset of the numbers 1:6} + \item{ncol}{number of columns in the resulting plot} + \item{nrow}{number of rows in the resulting plot} \item{title}{optional; character holding title of the plot; defaults to something the class author deems appropriate. } - \item{\dots}{unused at this time} + \item{\dots}{arguments passed to other methods} } \details{ -TBD +Currently six plots are available +\itemize{ + \item{1}{estimated link ratios f} + \item{2}{estimated link ratios f less unity} + \item{3}{estimated sigma values} + \item{4}{estimated standard error of the link ratio f.se} + \item{5}{coefficient of variation of the link ratio} + \item{6}{coefficient of variation of the link ratio less unity} +} } \value{ In the case of class ChainLadder or MackChainLadder, From 1b22df6becf90f4d6496c5e92186cc7a48f39927 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Mon, 24 Oct 2016 09:23:59 -0700 Subject: [PATCH 20/29] Edits --- man/plotParms.Rd | 26 ++++---- vignettes/plotParms.Rmd | 128 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 12 deletions(-) create mode 100644 vignettes/plotParms.Rmd diff --git a/man/plotParms.Rd b/man/plotParms.Rd index e7c9ee98..e964dddd 100644 --- a/man/plotParms.Rd +++ b/man/plotParms.Rd @@ -10,7 +10,8 @@ Plot the estimated parameters of a model \encoding{UTF-8} \description{ -Methods to visualize the estimated parameters. +Generic function for visualizing the estimated parameters +of a model in the ChainLadder package. S3 methods currently exist for objects of class ChainLadder and MackChainLadder. } @@ -36,21 +37,22 @@ defaults to something the class author deems appropriate. \item{\dots}{arguments passed to other methods} } \details{ -Currently six plots are available -\itemize{ - \item{1}{estimated link ratios f} - \item{2}{estimated link ratios f less unity} - \item{3}{estimated sigma values} - \item{4}{estimated standard error of the link ratio f.se} - \item{5}{coefficient of variation of the link ratio} - \item{6}{coefficient of variation of the link ratio less unity} +Currently six plots are available for +\code{chainladder} and \code{MackChainLadder}: +\enumerate{ + \item {estimated link ratios f} + \item {estimated link ratios f less unity} + \item {estimated sigma values} + \item {estimated standard error of the link ratio f.se} + \item {coefficient of variation of the link ratio} + \item {coefficient of variation of the link ratio less unity} } } \value{ In the case of class ChainLadder or MackChainLadder, -list of class arrangelist returned by -gridExtra::marrangeGrob. -In all other cases, a stop error is executed at this time. +list of class \code{arrangelist} returned by +\code{gridExtra::marrangeGrob}. +In all other cases, a \code{stop} error is executed at this time. } \author{ dmm diff --git a/vignettes/plotParms.Rmd b/vignettes/plotParms.Rmd new file mode 100644 index 00000000..f8b3feff --- /dev/null +++ b/vignettes/plotParms.Rmd @@ -0,0 +1,128 @@ +--- +title: "plotParms" +author: "Dan Murphy" +date: "October 24, 2016" +output: html_document +--- + +```{r setup, include=FALSE} +knitr::opts_chunk$set(echo = TRUE) +``` + +## Description + +*plotParms* is a generic function in the *ChainLadder* package +that plots various parameters estimated by models in the package. +Currently two models are supported: + +* chainladder +* MackChainLadder + +For those models, six plots can be rendered by *ggplot*: + +1. estimated link ratios **f** +1. estimated link ratios **f** less unity +1. estimated **sigma** values +1. estimated standard error of the link ratio **f.se** +1. coefficient of variation of the link ratio +1. coefficient of variation of the link ratio less unity + +By default the four plots 1, 3, 4, and 6 are displayed in a 2x2 grid +(using *gridExtra::marrangeGrob*). +Any other selection is displayed using two columns in left-to-right order, +unless only one plot is requested. +See section **Arguments** below. + +## Details + +### chainladder + +The chainladder function uses R's **lm** function to estimate +average age-to-age factors for a given actuarial *Triangle*. +In particular, when a development period has only one observation +there is insufficient data for **lm** to estimate the **sigma** +parameter of that period's regression model. +(This often occurs in the last period of a *summarized triangle*.) +In that case, +the value of the **sigma** parameter +(and dependent parameters) +is technically **NA**. +**plotParms** indicates that fact with: + +* a broken line at that point +* a point value at zero (for lack of a better choice) +* a legend entry indicating that the source of the parameter is **NA** + +For the **GenIns** Triangle in *ChainLadder*, +here is a plot of the weighted average link ratios, +the standard error of the residuals, +the standard error of the estimated link ratios, +and the coefficient of variation of the link ratios less unity: +```{r echo=FALSE} +suppressPackageStartupMessages(library(ChainLadder)) +``` +```{r} +plotParms(chainladder(GenIns)) +``` + +Like *ChainLadder*, +*plotParms* borrows the notation of *Mack*. +The legend indicates the source of the parameter's value: + +* "lm": results from the regression model +* NA: not available +* "calc": the coefficient of variation is always a calculated value +(cv(f) = f/f.se) + +### MackChainLadder + +*ChainLadder's* **MackChainLadder** model uses +**chainladder** for the purpose of estimating parameters +and adds capabilities for two situations: + +* sigma = NA +* a tail + +#### sigma = NA + +When *Triangle* has insufficient data to estimate **sigma**, +*MackChainLadder* has two methods for imputing a value: + +* log-linear regression (the default) +* the method of *Mack* + +Here is the default plot of the parameters of the +*MackChainLadder* model of the **GenIns** dataset: + +```{r} +plotParms(MackChainLadder(GenIns)) +``` + +Observations: + +* In contrast to the nine parameters estimated by *chainladder* above, +values for ten parameters are shown because *MackChainLadder* provides +for a **tail** argument, whose default value is unity. + +* The nineth **sigma** parameter is no longer NA (as with *chainladder* above) +but is estimated using log-linear regression ("log-lin"), +as *MackChainLadder* will do by default for any situation in which +**lm**'s estimated **sigma* is NA. +Refer to the **est.sigma** argument of *MackChainLadder*. +The tenth **sigma** parameter, not available by default, +can be provided by the user or can be estimated +by *MackChainLadder* (see below). +Refer to the **tail.sigma** argument of *MackChainLadder*. + +* When a non-tail **sigma** value is estimated ("imputed"), +the corresponding **f.se** is always calculated based on the +values in **Triangle** and the model's **alpha** argument. +So indicated in the legend for the nineth value. +As with **tail.sigma**, the **tail.se** value is not available +by default but can be provided or estimate by *MackChainLadder*. + +* In contrast to the *chainladder* method above +the source of the coefficient of variation parameters are indicated +as being "calculated". +The exception is when the **sigma** parameter is not available. + From 855a556b0017f78badd1782047a4f6b8a8416ba5 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Mon, 24 Oct 2016 10:20:37 -0700 Subject: [PATCH 21/29] Change lm to calc for chainladder cv estimates --- R/plotParms.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/plotParms.R b/R/plotParms.R index 08812602..5365c4e7 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -133,7 +133,7 @@ plot.cl.f.cv <- function(x) { f <- sapply(smmry, function(x) x$coef["x","Estimate"]) f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) f.cv <- f.se / f - legend_captions <- c("lm", "NA") + legend_captions <- c("calc", "NA") src <- factor(legend_captions, levels = legend_captions) source <- rep(src[1L], n) source[is.na(f.cv)] <- src[2L] @@ -155,7 +155,7 @@ plot.cl.f1.cv <- function(x) { f <- sapply(smmry, function(x) x$coef["x","Estimate"]) - 1 f.se <- sapply(smmry, function(x) x$coef["x","Std. Error"]) f.cv <- f.se / f - legend_captions <- c("lm", "NA") + legend_captions <- c("calc", "NA") src <- factor(legend_captions, levels = legend_captions) source <- rep(src[1L], n) source[is.na(f.cv)] <- src[2L] From 190e9b6e9e738d31304a32cdd19baa7486a8dabf Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Mon, 24 Oct 2016 10:27:09 -0700 Subject: [PATCH 22/29] Add "call" to chainladder output list Utilized by plotParms.ChainLadder --- R/ChainLadder.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/ChainLadder.R b/R/ChainLadder.R index 26ff7770..d5ba4041 100644 --- a/R/ChainLadder.R +++ b/R/ChainLadder.R @@ -31,6 +31,7 @@ chainladder <- function(Triangle, weights=1, output <- list(Models=myModel, Triangle=Triangle, delta=delta, weights=weights, TriangleName = TriangleName) + output[["call"]] <- match.call(expand.dots = FALSE) class(output) <- c("ChainLadder", "TriangleModel", class(output)) return(output) } From 1ffc2d1790eca6db8f08151ffd84192acb70f928 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Tue, 25 Oct 2016 06:11:06 -0700 Subject: [PATCH 23/29] New default title Shows the method's call --- R/plotParms.R | 18 +++++++++--------- man/plotParms.Rd | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/R/plotParms.R b/R/plotParms.R index 5365c4e7..a5b38b03 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -24,7 +24,7 @@ plotParms.default <- function(x, ...){ plotParms.ChainLadder <- function(x, which = c(1L, 3L, 4L, 6L), ncol = min(2L, length(which)), nrow = ceiling(length(which) / ncol), - title, ...) { + title = deparse(x$call), ...) { grobs <- lapply(which, function(i) switch(i, plot.cl.f(x) + theme(axis.title.y=element_blank()), @@ -35,9 +35,9 @@ plotParms.ChainLadder <- function(x, which = c(1L, 3L, 4L, 6L), plot.cl.f1.cv(x) + theme(axis.title.y=element_blank()) ) ) - if (missing(title)) title <- paste0("chainladder(", - x$TriangleName, - ") parameter estimates") +# if (missing(title)) title <- paste0("chainladder(", +# x$TriangleName, +# ") parameter estimates") marrangeGrob(grobs = grobs, ncol = ncol, nrow = nrow, top = title, ...) } @@ -176,7 +176,7 @@ plot.cl.f1.cv <- function(x) { plotParms.MackChainLadder <- function(x, which = c(1L, 3L, 4L, 6L), ncol = min(2L, length(which)), nrow = ceiling(length(which) / ncol), - title, ...) { + title = deparse(x$call), ...) { grobs <- lapply(which, function(i) switch(i, plot.mackcl.f(x) + theme(axis.title.y=element_blank()), @@ -187,9 +187,9 @@ plotParms.MackChainLadder <- function(x, which = c(1L, 3L, 4L, 6L), plot.mackcl.f1.cv(x) + theme(axis.title.y=element_blank()) ) ) - if (missing(title)) title <- paste0("MackChainLadder(", - x$TriangleName, - ") parameter estimates") +# if (missing(title)) title <- paste0("MackChainLadder(", +# x$TriangleName, +# ") parameter estimates") marrangeGrob(grobs = grobs, ncol = ncol, nrow = nrow, top = title, ...) } @@ -246,7 +246,7 @@ plot.mackcl.f1 <- function(x) { xlab(names(dimnames(x$Triangle))[2L]) + geom_line(aes(group = 1), na.rm = TRUE) + geom_point() + - ggtitle("f estimates") + ggtitle("f-1 estimates") P } plot.mackcl.sigma <- function(x) { diff --git a/man/plotParms.Rd b/man/plotParms.Rd index e964dddd..8b76c7db 100644 --- a/man/plotParms.Rd +++ b/man/plotParms.Rd @@ -32,7 +32,7 @@ plotParms(x, which, ncol, nrow, title, \dots) \item{ncol}{number of columns in the resulting plot} \item{nrow}{number of rows in the resulting plot} \item{title}{optional; character holding title of the plot; -defaults to something the class author deems appropriate. +defaults to method call. } \item{\dots}{arguments passed to other methods} } From e5758fef611cf6f27326a261b5803f2c17c9428e Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Tue, 25 Oct 2016 06:11:13 -0700 Subject: [PATCH 24/29] edits --- vignettes/plotParms.Rmd | 139 ++++++++++++++++++++++++++++++++-------- 1 file changed, 112 insertions(+), 27 deletions(-) diff --git a/vignettes/plotParms.Rmd b/vignettes/plotParms.Rmd index f8b3feff..1df1961a 100644 --- a/vignettes/plotParms.Rmd +++ b/vignettes/plotParms.Rmd @@ -2,7 +2,7 @@ title: "plotParms" author: "Dan Murphy" date: "October 24, 2016" -output: html_document +output: pdf_document --- ```{r setup, include=FALSE} @@ -23,15 +23,17 @@ For those models, six plots can be rendered by *ggplot*: 1. estimated link ratios **f** 1. estimated link ratios **f** less unity 1. estimated **sigma** values -1. estimated standard error of the link ratio **f.se** -1. coefficient of variation of the link ratio -1. coefficient of variation of the link ratio less unity +1. estimated standard error of the link ratios **f.se** +1. coefficient of variation of the link ratios +1. coefficient of variation of the link ratios less unity -By default the four plots 1, 3, 4, and 6 are displayed in a 2x2 grid +By default, +plots 1, 3, 4, and 6 are displayed in a 2x2 grid (using *gridExtra::marrangeGrob*). -Any other selection is displayed using two columns in left-to-right order, +Any other selection is displayed in two columns, unless only one plot is requested. -See section **Arguments** below. +Some flexibility is provided. +See **Arguments** section below. ## Details @@ -54,31 +56,31 @@ is technically **NA**. * a legend entry indicating that the source of the parameter is **NA** For the **GenIns** Triangle in *ChainLadder*, -here is a plot of the weighted average link ratios, +Figure 1 below is a plot of the weighted average link ratios, the standard error of the residuals, the standard error of the estimated link ratios, and the coefficient of variation of the link ratios less unity: ```{r echo=FALSE} suppressPackageStartupMessages(library(ChainLadder)) ``` -```{r} +```{r, fig.cap="chainladder(GenIns)"} plotParms(chainladder(GenIns)) ``` -Like *ChainLadder*, -*plotParms* borrows the notation of *Mack*. +Both the *chainladder* function and +*plotParms* borrow the notation of *Mack*. The legend indicates the source of the parameter's value: * "lm": results from the regression model * NA: not available * "calc": the coefficient of variation is always a calculated value -(cv(f) = f/f.se) +(cv(f) = f/f.se) or NA ### MackChainLadder -*ChainLadder's* **MackChainLadder** model uses -**chainladder** for the purpose of estimating parameters -and adds capabilities for two situations: +*ChainLadder's* **MackChainLadder** model leans on +**chainladder** to estimate parameters +and extends that method's capabilities for two situations: * sigma = NA * a tail @@ -86,15 +88,43 @@ and adds capabilities for two situations: #### sigma = NA When *Triangle* has insufficient data to estimate **sigma**, -*MackChainLadder* has two methods for imputing a value: +*MackChainLadder* has two methods for estimating ("imputing") a value: * log-linear regression (the default) * the method of *Mack* -Here is the default plot of the parameters of the -*MackChainLadder* model of the **GenIns** dataset: - -```{r} +#### tail + +For a 10x10 triangle, +**chainladder** generates nine factors. +In contrast, +**MackChainLadder** generates ten factors because +that method *always includes a tail factor.* +The default tail value is 1.000. +The user can provide a tail, +e.g., with **tail = 1.10**, +or can request MackChainLadder estimate a tail by specifying +**tail = TRUE**. +**sigma** and **se** tail parameters are determined by arguments +**tail.sigma** and **tail.se**. +Here also the user can provide values for those tail parameters +or can request MackChainLadder estimate their values by +specifying NULL's for those arguments. +Refer to the MackChainLadder documentation for more details. + +Figure 2 below is the default plot of the parameters of the +*MackChainLadder* model of the **GenIns** dataset. +Ten factors are plotted. +The NA value of sigma for the ninth link ratio +in Figure 1 above is replaced with a value imputed via log-linear regression +(via default argument **est.sigma = "log-linear"**). +The associated **f.se** +and **cv** values may now be calculated. +The default unity tail value is shown, +but MackChainLadder assumes a unity value is deterministic +so therefore does not estimate **tail.sigma** and **tail.se** values. + +```{r, fig.cap="MackChainLadder(GenIns)"} plotParms(MackChainLadder(GenIns)) ``` @@ -104,25 +134,80 @@ Observations: values for ten parameters are shown because *MackChainLadder* provides for a **tail** argument, whose default value is unity. -* The nineth **sigma** parameter is no longer NA (as with *chainladder* above) +* The ninth **sigma** parameter is no longer NA (as with *chainladder* above) but is estimated using log-linear regression ("log-lin"), -as *MackChainLadder* will do by default for any situation in which -**lm**'s estimated **sigma* is NA. +as *MackChainLadder* will do by default for any such situation. Refer to the **est.sigma** argument of *MackChainLadder*. The tenth **sigma** parameter, not available by default, can be provided by the user or can be estimated -by *MackChainLadder* (see below). +by *MackChainLadder* (see Example 3 below). Refer to the **tail.sigma** argument of *MackChainLadder*. * When a non-tail **sigma** value is estimated ("imputed"), the corresponding **f.se** is always calculated based on the -values in **Triangle** and the model's **alpha** argument. -So indicated in the legend for the nineth value. +values in *Triangle* and the model's **alpha** argument; +so indicated in the legend for the ninth value. As with **tail.sigma**, the **tail.se** value is not available -by default but can be provided or estimate by *MackChainLadder*. +by default but can be provided or estimated by *MackChainLadder*. * In contrast to the *chainladder* method above the source of the coefficient of variation parameters are indicated as being "calculated". The exception is when the **sigma** parameter is not available. +## Arguments + +*plotParms* for the two methods in this document is called as follows: + +``` +plotParms(x, which, ncol, nrow, title) +``` + +* x + + a *chainladder* or *MackChainLadder* object + + no default +* which + + a subset of integers 1 through 6 + + default: 1, 3, 4, 6 -- see list in **Description** section above + + follows in the tradition of ChainLadder::plot.glmReserve + by Wayne Zhang as well as stats::plot.lm +* ncol + + number of columns in the multi-plot output + + default: either 2, or 1 if only one plot is requested +* nrow + + number of rows in the multi-plot output + + default: sufficient number to display all plots on one page + given the number of plots selected and the **ncol** value +* title + + overall title to display at the top of the output page + + default: method's call + +## Last Example + +Here we use the Mack Method to estimate the chain-ladder projection +of the GenIns *Triangle* data: + +* The method used to impute **sigma* and **f.se** values is that +recommended by T. Mack +* The mse.method = "Mack" argument (the default, but here specified +explicitly) +determines that the recursive formulas reproduce Mack's +closed form formula. + +We also ask that the tail be estimated, +as well as the associated **sigma** and **se** +parameters, +by log-linear extrapolation of the link ratios, +**sigma**s and **f.se**'s. +See **?MackChainLadder*. +We also ask for all six of the plots to be displayed +and specify our own title. + +Notice that this is the first example where all **cv** parameter values +are calculated. + +```{r, fig.cap="Mack Method on GenIns"} +x <- MackChainLadder(GenIns, est.sigma = "Mack", mse.method = "Mack", + tail = TRUE, tail.sigma = NULL, tail.se = NULL) +plotParms(x, which = 1:6, title = "Mack Method on GenIns: Estimated Parameters") +``` \ No newline at end of file From 4705832ccb734245de526b93b2b15532c93444c3 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Tue, 25 Oct 2016 09:57:10 -0700 Subject: [PATCH 25/29] final draft edits version sent to markus --- vignettes/plotParms.Rmd | 153 ++++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 85 deletions(-) diff --git a/vignettes/plotParms.Rmd b/vignettes/plotParms.Rmd index 1df1961a..35ad5f6a 100644 --- a/vignettes/plotParms.Rmd +++ b/vignettes/plotParms.Rmd @@ -18,7 +18,8 @@ Currently two models are supported: * chainladder * MackChainLadder -For those models, six plots can be rendered by *ggplot*: +For those models, plots of six parameters +are available to be rendered by *ggplot*: 1. estimated link ratios **f** 1. estimated link ratios **f** less unity @@ -30,32 +31,30 @@ For those models, six plots can be rendered by *ggplot*: By default, plots 1, 3, 4, and 6 are displayed in a 2x2 grid (using *gridExtra::marrangeGrob*). -Any other selection is displayed in two columns, -unless only one plot is requested. -Some flexibility is provided. -See **Arguments** section below. +Some display flexibility is enabled; +see **Arguments** section below. ## Details ### chainladder -The chainladder function uses R's **lm** function to estimate +The *chainladder* function uses *lm* to estimate average age-to-age factors for a given actuarial *Triangle*. In particular, when a development period has only one observation -there is insufficient data for **lm** to estimate the **sigma** -parameter of that period's regression model. -(This often occurs in the last period of a *summarized triangle*.) +there is insufficient data for *lm* to estimate the **sigma** +parameter of that period's regression model +(as often occurs in the last period of a *summarized triangle*). In that case, the value of the **sigma** parameter (and dependent parameters) -is technically **NA**. -**plotParms** indicates that fact with: +is technically **NA** and +*plotParms* indicates such with: * a broken line at that point -* a point value at zero (for lack of a better choice) +* a point value at zero (for want of a better choice) * a legend entry indicating that the source of the parameter is **NA** -For the **GenIns** Triangle in *ChainLadder*, +For the **GenIns** triangle in *ChainLadder*, Figure 1 below is a plot of the weighted average link ratios, the standard error of the residuals, the standard error of the estimated link ratios, @@ -68,18 +67,21 @@ plotParms(chainladder(GenIns)) ``` Both the *chainladder* function and -*plotParms* borrow the notation of *Mack*. +*plotParms* borrow the *f* notation of Mack^[Thomas Mack. +Distribution-free calculation of the standard error of +chain ladder reserve estimates. +Astin Bulletin. Vol. 23. No 2. 1993. pp.213:225.]. The legend indicates the source of the parameter's value: -* "lm": results from the regression model +* lm: produced by the underlying regression * NA: not available -* "calc": the coefficient of variation is always a calculated value +* calc: the coefficient of variation is always a calculated value (cv(f) = f/f.se) or NA ### MackChainLadder -*ChainLadder's* **MackChainLadder** model leans on -**chainladder** to estimate parameters +The *ChainLadder* package's *MackChainLadder* model uses +*chainladder* to estimate parameters and extends that method's capabilities for two situations: * sigma = NA @@ -87,7 +89,8 @@ and extends that method's capabilities for two situations: #### sigma = NA -When *Triangle* has insufficient data to estimate **sigma**, +When *Triangle* has insufficient data to estimate **sigma** +for a given development period, *MackChainLadder* has two methods for estimating ("imputing") a value: * log-linear regression (the default) @@ -96,68 +99,39 @@ When *Triangle* has insufficient data to estimate **sigma**, #### tail For a 10x10 triangle, -**chainladder** generates nine factors. +*chainladder* generates nine factors. In contrast, -**MackChainLadder** generates ten factors because -that method *always includes a tail factor.* -The default tail value is 1.000. +*MackChainLadder* generates 10 factors because +*that method always includes a tail factor* +(default value is 1.000). The user can provide a tail, e.g., with **tail = 1.10**, -or can request MackChainLadder estimate a tail by specifying +or can request *MackChainLadder* estimate a tail by specifying **tail = TRUE**. **sigma** and **se** tail parameters are determined by arguments -**tail.sigma** and **tail.se**. -Here also the user can provide values for those tail parameters -or can request MackChainLadder estimate their values by -specifying NULL's for those arguments. -Refer to the MackChainLadder documentation for more details. +**tail.sigma** and **tail.se** +which the user can provide explicitly. +If not provided *MackChainLadder* can estimate their values. +Refer to the *MackChainLadder* documentation for more information. Figure 2 below is the default plot of the parameters of the -*MackChainLadder* model of the **GenIns** dataset. +*MackChainLadder* model of the **GenIns** triangle. Ten factors are plotted. -The NA value of sigma for the ninth link ratio -in Figure 1 above is replaced with a value imputed via log-linear regression -(via default argument **est.sigma = "log-linear"**). +The NA value of **sigma** for the ninth link ratio +in Figure 1 above is replaced with a value imputed via log-linear regression. The associated **f.se** and **cv** values may now be calculated. -The default unity tail value is shown, -but MackChainLadder assumes a unity value is deterministic -so therefore does not estimate **tail.sigma** and **tail.se** values. +The default unity tail value is shown but, +since a unity value is assumed to be deterministic, +**tail.sigma** and **tail.se** values are not available. ```{r, fig.cap="MackChainLadder(GenIns)"} plotParms(MackChainLadder(GenIns)) ``` -Observations: - -* In contrast to the nine parameters estimated by *chainladder* above, -values for ten parameters are shown because *MackChainLadder* provides -for a **tail** argument, whose default value is unity. - -* The ninth **sigma** parameter is no longer NA (as with *chainladder* above) -but is estimated using log-linear regression ("log-lin"), -as *MackChainLadder* will do by default for any such situation. -Refer to the **est.sigma** argument of *MackChainLadder*. -The tenth **sigma** parameter, not available by default, -can be provided by the user or can be estimated -by *MackChainLadder* (see Example 3 below). -Refer to the **tail.sigma** argument of *MackChainLadder*. - -* When a non-tail **sigma** value is estimated ("imputed"), -the corresponding **f.se** is always calculated based on the -values in *Triangle* and the model's **alpha** argument; -so indicated in the legend for the ninth value. -As with **tail.sigma**, the **tail.se** value is not available -by default but can be provided or estimated by *MackChainLadder*. - -* In contrast to the *chainladder* method above -the source of the coefficient of variation parameters are indicated -as being "calculated". -The exception is when the **sigma** parameter is not available. - ## Arguments -*plotParms* for the two methods in this document is called as follows: +*plotParms* for the two methods in this document is invoked as follows: ``` plotParms(x, which, ncol, nrow, title) @@ -169,8 +143,8 @@ plotParms(x, which, ncol, nrow, title) * which + a subset of integers 1 through 6 + default: 1, 3, 4, 6 -- see list in **Description** section above - + follows in the tradition of ChainLadder::plot.glmReserve - by Wayne Zhang as well as stats::plot.lm + + follows in the tradition of *ChainLadder::plot.glmReserve* + by Wayne Zhang as well as *stats::plot.lm* * ncol + number of columns in the multi-plot output + default: either 2, or 1 if only one plot is requested @@ -182,29 +156,38 @@ plotParms(x, which, ncol, nrow, title) + overall title to display at the top of the output page + default: method's call -## Last Example +## Final Example -Here we use the Mack Method to estimate the chain-ladder projection -of the GenIns *Triangle* data: +In this last example +we implement the *Mack Method* on the **GenIns** triangle +by specifying two key arguments: -* The method used to impute **sigma* and **f.se** values is that -recommended by T. Mack -* The mse.method = "Mack" argument (the default, but here specified +* mse.method = "Mack" (the default, but here specified explicitly) -determines that the recursive formulas reproduce Mack's -closed form formula. - -We also ask that the tail be estimated, -as well as the associated **sigma** and **se** -parameters, -by log-linear extrapolation of the link ratios, -**sigma**s and **f.se**'s. -See **?MackChainLadder*. -We also ask for all six of the plots to be displayed -and specify our own title. - -Notice that this is the first example where all **cv** parameter values +tells *MackChainLadder*'s recursion steps to duplicate Mack's +closed form formula +* est.sigma = "Mack" (not the default) +tells *MackChainLadder* to use Mack's +heuristic formula for imputing **sigma** values +when not available from a *chainladder* regression + +We also ask for a tail and associated uncertainty parameters +to be estimated: +**tail = TRUE**, **tail.sigma = NULL**, and **tail.se = NULL**. + +Finally, +we tell *plotParms* to display all six plots +and specify our own more succinct title +because the default +is too wide to fit in the display. + +Notice that in this example all **cv** parameter values are calculated. +Also, by comparing **cv(f-1)~9~** points in Figures 2 and 3, +the difference between +**mse.method = "log-linear"** (Figure 2) +and **mse.method = "Mack"** (Figure 3) +does not appear to be significant for this triangle. ```{r, fig.cap="Mack Method on GenIns"} x <- MackChainLadder(GenIns, est.sigma = "Mack", mse.method = "Mack", From b7bcb7540e92d8cf8a225db0c342d39d3ba66e01 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Thu, 27 Oct 2016 18:05:03 -0700 Subject: [PATCH 26/29] NA for f depends on f, not f.se --- R/plotParms.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/plotParms.R b/R/plotParms.R index a5b38b03..50a1d6ee 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -49,7 +49,7 @@ plot.cl.f <- function(x) { legend_captions <- c("lm", "NA") src <- factor(legend_captions, levels = legend_captions) source <- rep(src[1L], n) - source[is.na(f.se)] <- src[2L] + source[is.na(f)] <- src[2L] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) df <- data.frame(xx, f.se, source, From 085dda389adf5f5cd57e2fae7aabc558ba705394 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Thu, 27 Oct 2016 18:08:06 -0700 Subject: [PATCH 27/29] Same for f-1 --- R/plotParms.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/plotParms.R b/R/plotParms.R index 50a1d6ee..1a954fcf 100644 --- a/R/plotParms.R +++ b/R/plotParms.R @@ -70,7 +70,7 @@ plot.cl.f1 <- function(x) { legend_captions <- c("lm", "NA") src <- factor(legend_captions, levels = legend_captions) source <- rep(src[1L], n) - source[is.na(f.se)] <- src[2L] + source[is.na(f)] <- src[2L] xx <- factor(colnames(x$Triangle)[1:n], levels = colnames(x$Triangle)[1:n]) df <- data.frame(xx, f.se, source, From 48d1b20c2eb905deda00f9d6308953d6b3b06c1e Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Sun, 12 Mar 2017 12:57:13 -0700 Subject: [PATCH 28/29] Edited, updated date --- vignettes/plotParms.Rmd | 99 ++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 40 deletions(-) diff --git a/vignettes/plotParms.Rmd b/vignettes/plotParms.Rmd index 35ad5f6a..5c73be1a 100644 --- a/vignettes/plotParms.Rmd +++ b/vignettes/plotParms.Rmd @@ -1,8 +1,10 @@ --- title: "plotParms" author: "Dan Murphy" -date: "October 24, 2016" -output: pdf_document +date: "March 12, 2017" +output: + pdf_document: default + html_document: default --- ```{r setup, include=FALSE} @@ -13,13 +15,18 @@ knitr::opts_chunk$set(echo = TRUE) *plotParms* is a generic function in the *ChainLadder* package that plots various parameters estimated by models in the package. +The goal is to provide at a glance information about the +maginitude and potential variability of the parameter, +as well as its source -- +was it estimated, specified, NA, ... . + Currently two models are supported: * chainladder * MackChainLadder For those models, plots of six parameters -are available to be rendered by *ggplot*: +are available to be rendered by *ggplot2*: 1. estimated link ratios **f** 1. estimated link ratios **f** less unity @@ -38,27 +45,24 @@ see **Arguments** section below. ### chainladder -The *chainladder* function uses *lm* to estimate -average age-to-age factors for a given actuarial *Triangle*. -In particular, when a development period has only one observation +Recall that the *chainladder* function uses *lm* to estimate +average age-to-age factors for the +given actuarial *Triangle* argument. +Therefore when a development period has only one observation -- +as often occurs in the tail of a *summarized triangle* -- there is insufficient data for *lm* to estimate the **sigma** -parameter of that period's regression model -(as often occurs in the last period of a *summarized triangle*). -In that case, -the value of the **sigma** parameter -(and dependent parameters) -is technically **NA** and +parameter of that period's regression model. +When the **sigma** estimate +is technically **NA**, *plotParms* indicates such with: * a broken line at that point * a point value at zero (for want of a better choice) -* a legend entry indicating that the source of the parameter is **NA** +* a color-coded legend entry indicating +that the source of the parameter is **NA** -For the **GenIns** triangle in *ChainLadder*, -Figure 1 below is a plot of the weighted average link ratios, -the standard error of the residuals, -the standard error of the estimated link ratios, -and the coefficient of variation of the link ratios less unity: +For example, Figure 1 below shows the default **plotParms** +of the **chainladder** call for the **GenIns** triangle. ```{r echo=FALSE} suppressPackageStartupMessages(library(ChainLadder)) ``` @@ -75,8 +79,8 @@ The legend indicates the source of the parameter's value: * lm: produced by the underlying regression * NA: not available -* calc: the coefficient of variation is always a calculated value -(cv(f) = f/f.se) or NA +* calc: the coefficient of variation is a calculated value +(cv(f) = f/f.se) or **NA** ### MackChainLadder @@ -98,29 +102,37 @@ for a given development period, #### tail -For a 10x10 triangle, -*chainladder* generates nine factors. +Suppose your triangle is 10x10. +In that case there are (typically) nine link ratio factors +to select, +and *chainladder* will generate nine such averages +depending on the value of the **weights** and **delta** parameters. In contrast, *MackChainLadder* generates 10 factors because -*that method always includes a tail factor* -(default value is 1.000). -The user can provide a tail, -e.g., with **tail = 1.10**, -or can request *MackChainLadder* estimate a tail by specifying -**tail = TRUE**. -**sigma** and **se** tail parameters are determined by arguments -**tail.sigma** and **tail.se** -which the user can provide explicitly. -If not provided *MackChainLadder* can estimate their values. -Refer to the *MackChainLadder* documentation for more information. - +*that ChainLadder method always includes a tail factor* + +* by default the tail value is 1.000, or +* the user can provide a tail (e.g., with **tail = 1.10**), or +* the user can ask *MackChainLadder* to estimate a tail +by specifying **tail = TRUE**. + +**sigma** and **se** tail parameters are determined by +*MackChainLadder* arguments +**tail.sigma** and **tail.se**. +If the user does not explicitly provide those arguments +*MackChainLadder* will estimate their values. +(Refer to the *MackChainLadder* documentation for more information.) +**plotParms** will graph their value and their source. + +For example, Figure 2 below is the default plot of the parameters of the -*MackChainLadder* model of the **GenIns** triangle. +*MackChainLadder* model for the **GenIns** triangle. Ten factors are plotted. -The NA value of **sigma** for the ninth link ratio -in Figure 1 above is replaced with a value imputed via log-linear regression. +The **NA** value of **sigma** for the ninth link ratio +in Figure 1 above is replaced with a value +imputed via log-linear regression (the default). The associated **f.se** -and **cv** values may now be calculated. +and **cv** values may now be calculated and are also no longer **NA**. The default unity tail value is shown but, since a unity value is assumed to be deterministic, **tail.sigma** and **tail.se** values are not available. @@ -129,7 +141,7 @@ since a unity value is assumed to be deterministic, plotParms(MackChainLadder(GenIns)) ``` -## Arguments +## plotPaarms Arguments *plotParms* for the two methods in this document is invoked as follows: @@ -193,4 +205,11 @@ does not appear to be significant for this triangle. x <- MackChainLadder(GenIns, est.sigma = "Mack", mse.method = "Mack", tail = TRUE, tail.sigma = NULL, tail.se = NULL) plotParms(x, which = 1:6, title = "Mack Method on GenIns: Estimated Parameters") -``` \ No newline at end of file +``` + +## Conclusion + +Let the author(s) know if you have any problems with **plotParms** +as described in this article, +or if you wish to see a method implemented +for other **ChainLadder** models. \ No newline at end of file From 4c918fc05a5671fb6ddf8b1b6ce4bf422d79b5db Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Sun, 12 Mar 2017 19:32:56 -0700 Subject: [PATCH 29/29] final edits for the day --- vignettes/plotParms.Rmd | 98 +++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/vignettes/plotParms.Rmd b/vignettes/plotParms.Rmd index 5c73be1a..9faefb94 100644 --- a/vignettes/plotParms.Rmd +++ b/vignettes/plotParms.Rmd @@ -13,12 +13,13 @@ knitr::opts_chunk$set(echo = TRUE) ## Description -*plotParms* is a generic function in the *ChainLadder* package -that plots various parameters estimated by models in the package. -The goal is to provide at a glance information about the +*plotParms* is a generic^[S3 generic] +function in the *ChainLadder* package +that plots key parameters estimated by models in the package. +The goal is to -- at a glance -- get information about the maginitude and potential variability of the parameter, -as well as its source -- -was it estimated, specified, NA, ... . +as well as its source: +estimated, specified, NA, etc. Currently two models are supported: @@ -28,8 +29,10 @@ Currently two models are supported: For those models, plots of six parameters are available to be rendered by *ggplot2*: -1. estimated link ratios **f** -1. estimated link ratios **f** less unity +1. estimated link ratios **f**, +including one-standard-error "error bars" +1. estimated link ratios **f** less unity, +including one-standard-error "error bars" 1. estimated **sigma** values 1. estimated standard error of the link ratios **f.se** 1. coefficient of variation of the link ratios @@ -39,17 +42,17 @@ By default, plots 1, 3, 4, and 6 are displayed in a 2x2 grid (using *gridExtra::marrangeGrob*). Some display flexibility is enabled; -see **Arguments** section below. +see **plotParms Arguments** section below. -## Details +## Model-Specific Details ### chainladder -Recall that the *chainladder* function uses *lm* to estimate +*chainladder* uses *lm* to estimate average age-to-age factors for the given actuarial *Triangle* argument. Therefore when a development period has only one observation -- -as often occurs in the tail of a *summarized triangle* -- +as can often occur in the tail -- there is insufficient data for *lm* to estimate the **sigma** parameter of that period's regression model. When the **sigma** estimate @@ -61,8 +64,9 @@ is technically **NA**, * a color-coded legend entry indicating that the source of the parameter is **NA** -For example, Figure 1 below shows the default **plotParms** -of the **chainladder** call for the **GenIns** triangle. +For example, Figure 1 below shows the default *plotParms* +of the *chainladder* call for the **GenIns** triangle. + ```{r echo=FALSE} suppressPackageStartupMessages(library(ChainLadder)) ``` @@ -84,9 +88,9 @@ The legend indicates the source of the parameter's value: ### MackChainLadder -The *ChainLadder* package's *MackChainLadder* model uses -*chainladder* to estimate parameters -and extends that method's capabilities for two situations: +*MackChainLadder* uses +*chainladder* to estimate most parameters, +and extends the latter's capabilities in two situations: * sigma = NA * a tail @@ -100,40 +104,44 @@ for a given development period, * log-linear regression (the default) * the method of *Mack* +*plotParms*' legend indicates which method is used. + #### tail Suppose your triangle is 10x10. In that case there are (typically) nine link ratio factors to select, and *chainladder* will generate nine such averages -depending on the value of the **weights** and **delta** parameters. +depending on the value of arguments **weights** and **delta**. In contrast, *MackChainLadder* generates 10 factors because -*that ChainLadder method always includes a tail factor* +*that method always includes a tail factor* as follows: -* by default the tail value is 1.000, or -* the user can provide a tail (e.g., with **tail = 1.10**), or -* the user can ask *MackChainLadder* to estimate a tail +* By default the tail value is 1.000, or +* The user can provide a tail (e.g., with **tail = 1.10**), or +* The user can ask *MackChainLadder* to estimate a tail by specifying **tail = TRUE**. -**sigma** and **se** tail parameters are determined by +The **sigma** and **se** parameters for the tail are determined by *MackChainLadder* arguments **tail.sigma** and **tail.se**. If the user does not explicitly provide those arguments *MackChainLadder* will estimate their values. (Refer to the *MackChainLadder* documentation for more information.) -**plotParms** will graph their value and their source. +*plotParms* will graph their value and their source. For example, Figure 2 below is the default plot of the parameters of the *MackChainLadder* model for the **GenIns** triangle. -Ten factors are plotted. +Ten factors are plotted versus only nine in Figure 1. The **NA** value of **sigma** for the ninth link ratio -in Figure 1 above is replaced with a value +in Figure 1 is replaced with a value imputed via log-linear regression (the default). The associated **f.se** and **cv** values may now be calculated and are also no longer **NA**. -The default unity tail value is shown but, +The default unity tail value +(the tenth factor) +is shown but, since a unity value is assumed to be deterministic, **tail.sigma** and **tail.se** values are not available. @@ -141,7 +149,7 @@ since a unity value is assumed to be deterministic, plotParms(MackChainLadder(GenIns)) ``` -## plotPaarms Arguments +## plotParms Arguments *plotParms* for the two methods in this document is invoked as follows: @@ -184,32 +192,38 @@ heuristic formula for imputing **sigma** values when not available from a *chainladder* regression We also ask for a tail and associated uncertainty parameters -to be estimated: -**tail = TRUE**, **tail.sigma = NULL**, and **tail.se = NULL**. +to be estimated via + +* tail = TRUE, +* tail.sigma = NULL, and +* tail.se = NULL. Finally, we tell *plotParms* to display all six plots and specify our own more succinct title -because the default +because the call is too wide to fit in the display. -Notice that in this example all **cv** parameter values -are calculated. -Also, by comparing **cv(f-1)~9~** points in Figures 2 and 3, -the difference between -**mse.method = "log-linear"** (Figure 2) -and **mse.method = "Mack"** (Figure 3) -does not appear to be significant for this triangle. - ```{r, fig.cap="Mack Method on GenIns"} x <- MackChainLadder(GenIns, est.sigma = "Mack", mse.method = "Mack", tail = TRUE, tail.sigma = NULL, tail.se = NULL) plotParms(x, which = 1:6, title = "Mack Method on GenIns: Estimated Parameters") ``` +Here all **cv** parameter values +are calculated. + +Also of note: +by comparing **cv(f-1)~9~** points in Figures 2 and 3, +the difference between +**mse.method = "log-linear"** (Figure 2) +and **mse.method = "Mack"** (Figure 3) +does not appear to be significant for this triangle. + ## Conclusion -Let the author(s) know if you have any problems with **plotParms** -as described in this article, -or if you wish to see a method implemented -for other **ChainLadder** models. \ No newline at end of file +Let the author(s) know if you have any problems with plotParms +or wish to see an implementation +for another ChainLadder model. + +Cheers. \ No newline at end of file