Loss triangle
triangle.RdA loss triangle with four axes, in chainladder-python's order: index
(segment, such as a line of business) x column (measure, such as paid
and incurred) x origin period x development age in months. Cells that
are not observed are NA; a zero is an observation.
Usage
triangle(
data,
origin,
development,
columns,
keys = NULL,
origin_grain = "Y",
development_grain = "Y",
cumulative = TRUE,
development_is_valuation = FALSE,
ptr = NULL
)Arguments
- data
A data.frame with one row per (keys, origin, development).
- origin
Name of the origin column: Date, POSIXct (any day in the origin period) or whole-number years.
- development
Name of the development column: ages in months (12, 24, ...), or valuation dates when
development_is_valuation = TRUE.- columns
Names of the value columns (numeric).
- keys
Names of the key columns, such as
c("lob", "state"), orNULLfor a single segment labelled"Total". Key values are stored as character and may not beNA; key names must differ from each other and fromcolumns.- origin_grain, development_grain
Length of an origin period and spacing of the development ages:
"M"(month),"Q"(quarter),"S"(semester) or"Y"(year). The development grain must divide the origin grain.- cumulative
Whether the values are cumulative (otherwise incremental).
- development_is_valuation
Whether
developmentholds valuation dates (Date, POSIXct, or whole-number years meaning December of that year) instead of ages.- ptr
A
Trianglepointer; used internally.
Details
Segments are named by key columns such as lob and state. A triangle
without keys has one segment, labelled "Total".
triangle() builds one from a long table, one row per (keys, origin,
development). Origins span every period from the earliest to the latest
row and ages every development period from the youngest to the oldest.
Rows with the same (keys, origin, development) are summed, and NA
values are missing. Incremental input (cumulative = FALSE) follows
chainladder-python: a missing row is a period without movement.
Read-only properties: x@shape (index, column, origin and development
lengths), x@keys (the key names), x@index (a data.frame with one
column per key and one row per segment; no columns without keys),
x@columns, x@origins (period labels such as "1981",
"2021Q3", "2021H2" or "2021-08"), x@development (ages in months),
x@valuation (the last day of the latest valuation month), x@origin_grain,
x@development_grain, x@is_cumulative and x@values (a 4-D array with
dimnames, whose index names join the key values with " / ").
as.data.frame() gives the long table back, with the key columns by
name.
Examples
long <- data.frame(
year = c(2020, 2020, 2020, 2021, 2021, 2022),
age = c(12, 24, 36, 12, 24, 12),
paid = c(100, 150, 165, 110, 170, 120)
)
tri <- triangle(long, origin = "year", development = "age", columns = "paid")
tri
#> Triangle: paid (cumulative, valuation 2022-12)
#> 12 24 36
#> 2020 100 150 165
#> 2021 110 170
#> 2022 120
tri@values[1, "paid", , ]
#> development
#> origin 12 24 36
#> 2020 100 150 165
#> 2021 110 170 NA
#> 2022 120 NA NA
tri@valuation
#> [1] "2022-12-31"
# Two lines of business as a key column.
by_lob <- data.frame(
lob = c("auto", "auto", "home"),
year = c(2020, 2020, 2020),
age = c(12, 24, 12),
paid = c(100, 150, 40)
)
tri <- triangle(by_lob, "year", "age", "paid", keys = "lob")
tri@keys
#> [1] "lob"
tri@index
#> lob
#> 1 auto
#> 2 home
as.data.frame(tri)
#> lob origin development paid
#> 1 auto 2020-01-01 12 100
#> 2 auto 2020-01-01 24 150
#> 3 home 2020-01-01 12 40