# Short introduction to TLMoments

#### 2022-03-27

`TLMoments` is a set of functions whose main functionality is the calculation of trimmed L-moments (TL-moments) and resulting estimates of distribution parameters and quantiles.
One of the goals is to reduce computation time compared to existing implementations (in packages like `lmomco`, `Lmoments`, `Lmom`), therefore the core functions are written in C++ using `Rcpp` (see vignette “comparison of computation time” for speed comparisons). The package expands the combinations of trimmings that can be used to estimate distribution parameters in comparison to existing packages (which currently mainly support parameter estimation with L-moments). To ensure an easy usage, the package only contains a small set of functions. This vignette gives a short introduction to the most important ones and how to use them.

    library(TLMoments)
    sessionInfo()

    ## R version 4.1.2 (2021-11-01)
    ## Platform: x86_64-pc-linux-gnu (64-bit)
    ## Running under: Ubuntu 21.04
    ##
    ## Matrix products: default
    ## BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.9.0
    ## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.9.0
    ##
    ## locale:
    ##  [1] LC_CTYPE=de_DE.UTF-8       LC_NUMERIC=C
    ##  [3] LC_TIME=de_DE.UTF-8        LC_COLLATE=C
    ##  [5] LC_MONETARY=de_DE.UTF-8    LC_MESSAGES=de_DE.UTF-8
    ##  [7] LC_PAPER=de_DE.UTF-8       LC_NAME=C
    ##  [9] LC_ADDRESS=C               LC_TELEPHONE=C
    ## [11] LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C
    ##
    ## attached base packages:
    ## [1] stats     graphics  grDevices utils     datasets  methods   base
    ##
    ## other attached packages:
    ## [1] lmom_2.8          Lmoments_1.3-1    lmomco_2.3.7      TLMoments_0.7.5.3
    ## [5] Rcpp_1.0.7
    ##
    ## loaded via a namespace (and not attached):
    ##  [1] digest_0.6.29   MASS_7.3-55     magrittr_2.0.1  evaluate_0.14
    ##  [5] rlang_1.0.2     stringi_1.7.6   cli_3.1.0       rstudioapi_0.13
    ##  [9] goftest_1.2-3   rmarkdown_2.11  tools_4.1.2     stringr_1.4.0
    ## [13] xfun_0.29       yaml_2.2.1      fastmap_1.1.0   compiler_4.1.2
    ## [17] htmltools_0.5.2 evd_2.3-4       knitr_1.37

## Calculation of empirical TL-moments, parameter and quantile estimates

First we have a look at the basic functionality of calculating TL-moments and parameter and quantile estimates. Let assume we have a simple random data vector generated from a GEV distribution:

    xvec <- rgev(100, loc = 10, scale = 5, shape = .2)

TL-moments are calculated by the function `TLMoments` with arguments `leftrim`, `rightrim`, and `max.order` (generating an object of class `TLMoments`):

    TLMoments(xvec)

    ## $lambdas
    ##         L1         L2         L3         L4
    ## 13.3826607  3.7257087  0.9870101  0.7340864
    ##
    ## $ratios
    ##        T1        T2        T3        T4
    ##        NA 0.2783982 0.2649188 0.1970327

    TLMoments(xvec, leftrim = 0, rightrim = 1, max.order = 2)

    ## $lambdas
    ##       L1       L2
    ## 9.656952 2.054024
    ##
    ## $ratios
    ##       T1       T2
    ##       NA 0.212699

We can calculate parameter estimates by putting a `TLMoments`-object to the function `parameters` and specifying argument `distr`:

    tlm <- TLMoments(xvec)
    parameters(tlm, distr = "gev")

    ##       loc     scale     shape
    ## 9.9581721 4.6219480 0.1432724

    tlm <- TLMoments(xvec, rightrim = 1)
    parameters(tlm, distr = "gev")

    ##       loc     scale     shape
    ## 9.9666536 4.6303617 0.1385292

This generates an object of class `parameters`, which can be transmitted to `quantiles` to calculate quantile estimations:

    tlm <- TLMoments(xvec)
    quantiles(parameters(tlm, distr = "gev"), c(.9, .99, .999))

    ##      0.9     0.99    0.999
    ## 22.23170 40.05670 64.48409

    tlm <- TLMoments(xvec, rightrim = 1)
    quantiles(parameters(tlm, distr = "gev"), c(.9, .99, .999))

    ##      0.9     0.99    0.999
    ## 22.19364 39.75791 63.56389

## Summary functions

Objects of type `TLMoments`, `parameters`, or `quantiles` (i.e. results from the functions of the same name) feature `summary`-functions, which give confidence intervals and an overview of the data.

    tlm <- TLMoments(rgev(100), leftrim = 0, rightrim = 1)

    summary(tlm)

    ## 1 data row(s) with n = 100.
    ## TL(0,1) calculated.
    ##
    ## Approximate 90% confidence interval of TL moments:
    ##            LCL  lambda_hat          UCL
    ## L1 -0.21050958 -0.04010728 0.1302950164
    ## L2  0.37054673  0.42541664 0.4802865562
    ## L3 -0.05313960 -0.02629817 0.0005432553
    ## L4  0.02758415  0.04608429 0.0645844198
    ## Approximate 90% confidence interval of TL moment ratios:
    ##             LCL      tau_hat           UCL
    ## T2 -55.56674228 -10.60696730 34.3528076796
    ## T3  -0.12264872  -0.06181745 -0.0009861685
    ## T4   0.05924541   0.10832742  0.1574094311

    summary(parameters(tlm, "gev"))

    ## 1 data row(s) with n = 100.
    ## TL(0,1) used to generate GEV parameters.
    ##
    ## Approximate 90% confidence interval of parameters:
    ##               LCL      param         UCL
    ## loc   -0.04498695  0.1456896  0.33636614
    ## scale  0.87132263  1.0022373  1.13315207
    ## shape -0.36898235 -0.2007409 -0.03249951

    summary(quantiles(parameters(tlm, "gev"), .99))

    ## 1 data row(s) with n = 100.
    ## TL(0,1) used to generate GEV parameters to calculate 0.99 quantile estimates.
    ##
    ## Approximate 90% confidence interval of quantiles:
    ##           LCL quantile     UCL
    ## 0.99 2.253144 3.155527 4.05791

The default confidence interval level is 90%, but it can be set using the argument `ci.level`. The argument `select` can be used to subset the results, which can be handy when analysing large data matrices.

    summary(tlm, ci.level = .95, select = 3:4)

    ## 1 data row(s) with n = 100.
    ## TL(0,1) calculated.
    ##
    ## Approximate 95% confidence interval of TL moments:
    ##            LCL  lambda_hat         UCL
    ## L3 -0.05828170 -0.02629817 0.005685361
    ## L4  0.02404002  0.04608429 0.068128555
    ## Approximate 95% confidence interval of TL moment ratios:
    ##           LCL   tau_hat       UCL
    ## T3 0.03584248 0.1083274 0.1808124
    ## T4 0.04984259 0.1083274 0.1668122

    summary(parameters(tlm, "gev"), select = "shape")

    ## 1 data row(s) with n = 100.
    ## TL(0,1) used to generate GEV parameters.
    ##
    ## Approximate 90% confidence interval of parameters:
    ##              LCL      param         UCL
    ## shape -0.3689824 -0.2007409 -0.03249951

At the moment, the summary functions do not work for data in lists or data.frames.

## Magrittr syntax

`TLMoments` is built to support the use in `magrittr` syntax. The nesting of functions can be written more readable as:

    library(magrittr)

    TLMoments(xvec, leftrim = 0, rightrim = 1) %>%
      parameters("gev") %>%
      quantiles(c(.99, .999)) %>%
      summary()

    ## 1 data row(s) with n = 100.
    ## TL(0,1) used to generate GEV parameters to calculate 0.99, 0.999 quantile estimates.
    ##
    ## Approximate 90% confidence interval of quantiles:
    ##            LCL quantile      UCL
    ## 0.99  27.55090 39.75791 51.96492
    ## 0.999 29.65424 63.56389 97.47354

In the following this syntax is used for a clearer presentation.

## Support for different data types

The functions `TLMoments`, `parameters`, and `quantiles` provide the main functionality of the package. In the code above we used single data vectors only, but the same functions can be used for data matrices, lists, and data.frames as well. To demonstrate this, let’s generate sample data of these four types:

    xmat <- matrix(rgev(100), nc = 4)
    xvec <- xmat[, 3]
    xlist <- lapply(1L:ncol(xmat), function(i) xmat[, i])
    xdat <- data.frame(station = rep(1:4, each = 25), hq = as.vector(xmat))

Note that the type of the dimensions `lambdas` and `ratios` returned by `TLMoments` matches the input type:

    TLMoments(xvec, leftrim = 0, rightrim = 1)

    ## $lambdas
    ##          L1          L2          L3          L4
    ##  0.03631499  0.39899946 -0.05375175  0.02462370
    ##
    ## $ratios
    ##          T1          T2          T3          T4
    ##          NA 10.98718297 -0.13471636  0.06171362

    TLMoments(xmat, leftrim = 0, rightrim = 1)

    ## $lambdas
    ##           [,1]         [,2]        [,3]        [,4]
    ## L1 -0.18608012 -0.230243027  0.03631499 -0.32978875
    ## L2  0.31601417  0.495922514  0.39899946  0.41675746
    ## L3  0.02435559  0.031014442 -0.05375175 -0.03767806
    ## L4  0.04527736  0.007043843  0.02462370  0.04164978
    ##
    ## $ratios
    ##           [,1]        [,2]        [,3]        [,4]
    ## T1          NA          NA          NA          NA
    ## T2 -1.69826937 -2.15390894 10.98718297 -1.26371033
    ## T3  0.07707121  0.06253889 -0.13471636 -0.09040765
    ## T4  0.14327637  0.01420352  0.06171362  0.09993769

    TLMoments(xlist, leftrim = 0, rightrim = 1)

    ## $lambdas
    ## $lambdas[[1]]
    ##          L1          L2          L3          L4
    ## -0.18608012  0.31601417  0.02435559  0.04527736
    ##
    ## $lambdas[[2]]
    ##           L1           L2           L3           L4
    ## -0.230243027  0.495922514  0.031014442  0.007043843
    ##
    ## $lambdas[[3]]
    ##          L1          L2          L3          L4
    ##  0.03631499  0.39899946 -0.05375175  0.02462370
    ##
    ## $lambdas[[4]]
    ##          L1          L2          L3          L4
    ## -0.32978875  0.41675746 -0.03767806  0.04164978
    ##
    ##
    ## $ratios
    ## $ratios[[1]]
    ##          T1          T2          T3          T4
    ##          NA -1.69826937  0.07707121  0.14327637
    ##
    ## $ratios[[2]]
    ##          T1          T2          T3          T4
    ##          NA -2.15390894  0.06253889  0.01420352
    ##
    ## $ratios[[3]]
    ##          T1          T2          T3          T4
    ##          NA 10.98718297 -0.13471636  0.06171362
    ##
    ## $ratios[[4]]
    ##          T1          T2          T3          T4
    ##          NA -1.26371033 -0.09040765  0.09993769

    TLMoments(xdat, hq ~ station, leftrim = 0, rightrim = 1)

    ## $lambdas
    ##   station          L1        L2          L3          L4
    ## 1       1 -0.18608012 0.3160142  0.02435559 0.045277362
    ## 2       2 -0.23024303 0.4959225  0.03101444 0.007043843
    ## 3       3  0.03631499 0.3989995 -0.05375175 0.024623702
    ## 4       4 -0.32978875 0.4167575 -0.03767806 0.041649778
    ##
    ## $ratios
    ##   station        T2          T3         T4
    ## 1       1 -1.698269  0.07707121 0.14327637
    ## 2       2 -2.153909  0.06253889 0.01420352
    ## 3       3 10.987183 -0.13471636 0.06171362
    ## 4       4 -1.263710 -0.09040765 0.09993769

This holds when parameter and quantile estimations are calculated:

    TLMoments(xvec, leftrim = 0, rightrim = 1) %>%
      parameters("gev")

    ##        loc      scale      shape
    ##  0.2716187  0.9327093 -0.3916404

    TLMoments(xmat, leftrim = 0, rightrim = 1) %>%
      parameters("gev")

    ##             [,1]        [,2]       [,3]       [,4]
    ## loc   -0.1354520 -0.13712395  0.2716187 -0.1229062
    ## scale  0.7143313  1.12937085  0.9327093  0.9814387
    ## shape  0.1274538  0.09509625 -0.3916404 -0.2739527

    TLMoments(xlist, leftrim = 0, rightrim = 1) %>%
      parameters("gev")

    ## [[1]]
    ##        loc      scale      shape
    ## -0.1354520  0.7143313  0.1274538
    ##
    ## [[2]]
    ##         loc       scale       shape
    ## -0.13712395  1.12937085  0.09509625
    ##
    ## [[3]]
    ##        loc      scale      shape
    ##  0.2716187  0.9327093 -0.3916404
    ##
    ## [[4]]
    ##        loc      scale      shape
    ## -0.1229062  0.9814387 -0.2739527

    TLMoments(xdat, hq ~ station, leftrim = 0, rightrim = 1) %>%
      parameters("gev")

    ##   station        loc     scale       shape
    ## 1       1 -0.1354520 0.7143313  0.12745382
    ## 2       2 -0.1371239 1.1293708  0.09509625
    ## 3       3  0.2716187 0.9327093 -0.39164040
    ## 4       4 -0.1229062 0.9814387 -0.27395273

    TLMoments(xvec, leftrim = 0, rightrim = 1) %>%
      parameters("gev") %>%
      quantiles(c(.99, .999))

    ##     0.99    0.999
    ## 2.260128 2.493935

    TLMoments(xmat, leftrim = 0, rightrim = 1) %>%
      parameters("gev") %>%
      quantiles(c(.99, .999))

    ##           [,1]      [,2]     [,3]     [,4]
    ## 0.99  4.333331  6.380038 2.260128 2.443638
    ## 0.999 7.776929 10.892373 2.493935 2.919611

    TLMoments(xlist, leftrim = 0, rightrim = 1) %>%
      parameters("gev") %>%
      quantiles(c(.99, .999))

    ## [[1]]
    ##     0.99    0.999
    ## 4.333331 7.776929
    ##
    ## [[2]]
    ##      0.99     0.999
    ##  6.380038 10.892373
    ##
    ## [[3]]
    ##     0.99    0.999
    ## 2.260128 2.493935
    ##
    ## [[4]]
    ##     0.99    0.999
    ## 2.443638 2.919611

    TLMoments(xdat, hq ~ station, leftrim = 0, rightrim = 1) %>%
      parameters("gev") %>%
      quantiles(c(.99, .999))

    ##   station     0.99     0.999
    ## 1       1 4.333331  7.776929
    ## 2       2 6.380038 10.892373
    ## 3       3 2.260128  2.493935
    ## 4       4 2.443638  2.919611

## Distributions

`TLMoments` offers distribution functions (cdf, pdf, quantile, random number generation) for the generalized extreme value distribution (`gev`), Gumbel distribution (`gum`), generalized Pareto distribution (`gpd`), and three-parameter lognormal distribution (`ln3`) in the common `p|d|q|r`-syntax. The parameter (and quantile) estimation functionality works for all of them, but more complex functionality like estimation of the covariance matrix of parameter or quantile estimators only works for GEV by now.

## TL-moment ratio diagram

Version 0.7.4 added functionality to plot TL-moment ratio diagrams of arbitrary trimming orders. Simply plot an object of `TLMoments`. Argument `distr` can be used to specify displayed theoretical distributions. Note that `ggplot2` is used. Therefore changes or additions have to be made by adding `ggplot2`-specific functions.

    data <- matrix(rgev(25 * 10, shape = .2), ncol = 10)
    plot(TLMoments(data))

    plot(TLMoments(data)) + ggplot2::theme_minimal()

    plot(TLMoments(data, rightrim = 1), distr = c("gev", "gpd", "exp", "gum"))

## Calculations using theoretical/given TL-moments and parameters

The functions `as.TLMoments` and `as.parameters` can be used to construct `TLMoments`- or `parameters`-objects of given values (not calculated from data). These objects can be used in the same way like before (to convert between TL-moments and their parameters or to calculate the corresponding quantiles):

    (tlm <- as.TLMoments(c(14.1, 4.3, 1.32)))

    ## $lambdas
    ##    L1    L2    L3
    ## 14.10  4.30  1.32
    ##
    ## $ratios
    ##        T1        T2        T3
    ##        NA 0.3049645 0.3069767

    parameters(tlm, distr = "gev")

    ##        loc      scale      shape
    ## 10.0134305  4.9448851  0.2034746

    quantiles(parameters(tlm, distr = "gev"), c(.9, .99, .999))

    ##      0.9     0.99    0.999
    ## 24.12668 47.67693 84.80024

    (param <- as.parameters(loc = 10, scale = 5, shape = .2, distr = "gev"))

    ##   loc scale shape
    ##  10.0   5.0   0.2

    quantiles(param, c(.9, .99, .999))

    ##      0.9     0.99    0.999
    ## 24.21069 47.73413 84.51684

    TLMoments(param)

    ## $lambdas
    ##         L1         L2         L3         L4
    ## 14.1057429  4.3279754  1.3204343  0.9436158
    ##
    ## $ratios
    ##        T1        T2        T3        T4
    ##        NA 0.3068236 0.3050928 0.2180271

    TLMoments(param, rightrim = 1)

    ## $lambdas
    ##        L1        L2        L3        L4
    ## 9.7777681 2.2556564 0.2512127 0.2553529
    ##
    ## $ratios
    ##        T1        T2        T3        T4
    ##        NA 0.2306924 0.1113701 0.1132056

Note, that we can simply use the `TLMoments`-function to calculate TL-moments corresponding to a `parameters`-object.