The Society of Actuaries (SOA) provides an extensive online database called ‘Mortality and Other Rate Tables’ (‘MORT’) at https://mort.soa.org/. This database contains mortality, lapse, and valuation tables that cover a variety of product types and nations. Users of the database can download any tables in ‘Excel’, ‘CSV’, or ‘XML’ formats. This package provides convenience functions that read ‘XML’ formats from the database and return R objects.
The mortSOA package can be installed from CRAN with:
install.packages("mortSOA")You can install the development version of mortSOA from GitHub with:
# install.packages("pak")
pak::pak("mattheaphy/mortSOA")The mortSOA package comes with a data frame that
contains an inventory of available tables on mort.soa.org.
This data set is not automatically refreshed and was last updated on
2026-01-24.
library(mortSOA)
library(tibble)
table_inventory
#> # A tibble: 3,034 × 6
#> table_id name description layout usage nation
#> <int> <chr> <chr> <chr> <chr> <chr>
#> 1 1 1941 CSO Basic Table, ANB "1941 Comm… Aggre… CSO … Unite…
#> 2 2 1941 CSO Experience Table, ANB "1941 Comm… Aggre… CSO … Unite…
#> 3 3 1941 CSO Table with Davis’ Extensio… "1941 Comm… Aggre… CSO … Unite…
#> 4 4 1941 CSO Table with Davis’ Extensio… "1941 Comm… Aggre… CSO … Unite…
#> 5 5 1958 CSO - Male, ANB "1958 Comm… Aggre… CSO … Unite…
#> 6 6 1958 CSO- Female, ANB "1958 Comm… Aggre… CSO … Unite…
#> 7 7 1958 CSO - Male, ALB "1958 Comm… Aggre… CSO … Unite…
#> 8 8 1958 CSO - Female, ALB "1958 Comm… Aggre… CSO … Unite…
#> 9 9 1958 CET - Male, ANB "1958 Comm… Aggre… CSO … Unite…
#> 10 10 1958 CET - Female, ANB "1958 Comm… Aggre… CSO … Unite…
#> # ℹ 3,024 more rowsThe table inventory is provided as a quick reference to look up table
identification numbers used by mort.soa.org. The
filter_inventory() function is provided to assist with
searching the inventory.
Let’s assume that we are interested in the 2012 IAM Basic table.
filter_inventory("2012", "IAM Basic")
#> # A tibble: 2 × 6
#> table_id name description layout usage nation
#> <int> <chr> <chr> <chr> <chr> <chr>
#> 1 2581 2012 IAM Basic Table – Male, ANB 2012 Individu… Aggre… Annu… Unite…
#> 2 2582 2012 IAM Basic Table – Female, ANB 2012 Individu… Aggre… Annu… Unite…The read_mort_soa() function is used to obtain data from
mort.soa.org. This function requires a table identification
number (table_id). Continuing with the prior example, let’s
look up table 2582, the 2012 IAM Basic Tables for female lives.
iam_2012_f <- read_mort_soa(2582)
iam_2012_f[[1]]
#> # A tibble: 121 × 2
#> age qx
#> <dbl> <dbl>
#> 1 0 0.00180
#> 2 1 0.00045
#> 3 2 0.000287
#> 4 3 0.000199
#> 5 4 0.000152
#> 6 5 0.000139
#> 7 6 0.00013
#> 8 7 0.000122
#> 9 8 0.000105
#> 10 9 0.000098
#> # ℹ 111 more rowsThis function returns a list of any tables (converted to data frames)
found under the given table_id. Since 2012 IAM basic is an
ultimate table there is only one data frame in the list.
The list includes additional metadata attributes that can be
inspected using the attr() or attributes()
functions.
attributes(iam_2012_f)
#> $name
#> [1] "2012 IAM Basic Table – Female, ANB"
#>
#> $table_id
#> [1] "2582"
#>
#> $description
#> [1] "2012 Individual Annuity Mortality Basic Table – Female. Basis: Age Nearest Birthday. Minimum Age: 0. Maximum Age: 120"
#>
#> $usage
#> [1] "Annuitant Mortality"
#>
#> $layout
#> [1] "Aggregate"
#>
#> $nation
#> [1] "United States of America"
#>
#> $sub_descriptions
#> [1] "2012 Individual Annuity Mortality Basic Table – Female. Basis: Age Nearest Birthday. Minimum Age: 0. Maximum Age: 120"Many tables in mort.soa.org have a select and ultimate
structure. For these tables, the list returned by
read_mort_soa() will include two elements. The first
element is a two-dimensional table with mortality rates varying by issue
age and policy duration. The second element is an ultimate mortality
table varying by attained age only.
Example using the 2015 VBT Non-Smoker ALB table
(table_id = 3269)
vbt <- read_mort_soa(3269)Select table
vbt[[1]]
#> # A tibble: 1,950 × 3
#> age duration qx
#> <dbl> <dbl> <dbl>
#> 1 18 1 0.00066
#> 2 18 2 0.00069
#> 3 18 3 0.00071
#> 4 18 4 0.00071
#> 5 18 5 0.00069
#> 6 18 6 0.00069
#> 7 18 7 0.00068
#> 8 18 8 0.00066
#> 9 18 9 0.00057
#> 10 18 10 0.00052
#> # ℹ 1,940 more rowsUltimate table
vbt[[2]]
#> # A tibble: 103 × 2
#> age qx
#> <dbl> <dbl>
#> 1 18 0.00066
#> 2 19 0.00069
#> 3 20 0.00071
#> 4 21 0.00071
#> 5 22 0.00069
#> 6 23 0.00069
#> 7 24 0.00068
#> 8 25 0.00066
#> 9 26 0.00057
#> 10 27 0.00052
#> # ℹ 93 more rowsThe mortSOA package and its authors are not affiliated with the
Society of Actuaries, which owns and operates mort.soa.org.
Review the terms of use at https://mort.soa.org/TermsOfUse.aspx for more
information.