# Introduction

Joinpoint regression is commonly used in epidemiology to identify changes in temporal trends. The joinpointR package provides tools to fit joinpoint regression models, estimate annual percentage changes, and present results.

## Joinpoint regression models by group

The function `model_jp()`allows to fit joinpoint regression models with a log-response by levels of one or more categorical variable(s). For the examples, we are going to use a simulated dataset with the HIV rates by sex in five regions

    # Load required packages
    library(dplyr)
    library(tidyr)
    library(ggplot2)
    library(joinpointR)

    # Load example data
    data(hiv_data)

### Stepwise joinpoint regression by sex

    mod1 <- model_jp(
      data = hiv_data,
      value = hiv_rate,
      time = year,
      group = "sex",
      k = 3,
      min_dist = 3,
      step = TRUE,
      test = TRUE
    )
    #> Model: Female | Joinpoint(s): no significant joinpoints detected
    #> Model: Male | Joinpoint(s): no significant joinpoints detected

    # Show the model output
    mod1
    #> $Female
    #>
    #> Call:
    #> segmented::selgmented(olm = stats::lm(formula = log(hiv_rate) ~
    #>     year), Kmax = 3)
    #>
    #> Coefficients:
    #> (Intercept)     .jp_time
    #>    37.81573     -0.01648
    #>
    #>
    #> $Male
    #>
    #> Call:
    #> segmented::selgmented(olm = stats::lm(formula = log(hiv_rate) ~
    #>     year), Kmax = 3)
    #>
    #> Coefficients:
    #> (Intercept)     .jp_time
    #>    35.25705     -0.01516

### Fixed number of joinpoints by sex

    mod2 <- model_jp(
      data = hiv_data,
      value = hiv_rate,
      time = year,
      group = "sex",
      k = 1,
      min_dist = 3,
      step = FALSE,
      test = FALSE
    )
    #> Model: Female | Joinpoint(s): 2020
    #> Model: Male | Joinpoint(s): 2019

    # Show the model output
    mod2
    #> $Female
    #> Call: segmented::segmented(obj = stats::lm(formula = log(hiv_rate) ~
    #>     year), seg.Z = ~year, npsi = 1)
    #>
    #> Coefficients of the linear terms:
    #> (Intercept)     .jp_time  U1..jp_time
    #>    54.61669     -0.02482      0.02718
    #>
    #> Estimated Break-Point(s):
    #> psi1..jp_time
    #>          2020
    #>
    #> $Male
    #> Call: segmented::segmented(obj = stats::lm(formula = log(hiv_rate) ~
    #>     year), seg.Z = ~year, npsi = 1)
    #>
    #> Coefficients of the linear terms:
    #> (Intercept)     .jp_time  U1..jp_time
    #>    51.39025     -0.02318      0.02431
    #>
    #> Estimated Break-Point(s):
    #> psi1..jp_time
    #>          2019

### Stepwise joinpoint regression models by sex and region

    mod3 <- model_jp(
      data = hiv_data,
      value = hiv_rate,
      time = year,
      group = c("region", "sex"),
      step = TRUE
    )
    #> Model: Central_Female | Joinpoint(s): 2019
    #> Model: Central_Male | Joinpoint(s): 2013.7; 2019.0
    #> Model: East_Female | Joinpoint(s): 2014.8; 2019.1
    #> Model: East_Male | Joinpoint(s): 2014.4; 2019.0
    #> Model: North_Female | Joinpoint(s): 2015.4; 2019.0
    #> Model: North_Male | Joinpoint(s): 2014.9; 2019.1
    #> Model: South_Female | Joinpoint(s): 2019
    #> Model: South_Male | Joinpoint(s): 2019
    #> Model: West_Female | Joinpoint(s): 2017.9; 2019.4
    #> Model: West_Male | Joinpoint(s): 2019

## Annual percentage change (APC)

The function `get_apc()` provides the annual percentage change and its 95% confidence interval for models with significant joinpoints (`class: "segmented" "lm"`)

    get_apc(mod2)
    #>    model segment   APC CI_low CI_upp
    #> 1 Female       1 -2.5%  -3.6%  -1.3%
    #> 2 Female       2  0.2%  -2.3%   2.8%
    #> 3   Male       1 -2.3%  -3.3%  -1.3%
    #> 4   Male       2  0.1%  -2.1%   2.4%

The function returns empty rows when no significant joinpoints are detected (`class = "lm"`).

    get_apc(mod1, digits = 1)
    #> # A tibble: 2 × 5
    #>   model  segment APC   CI_low CI_upp
    #>   <chr>  <chr>   <chr> <chr>  <chr>
    #> 1 Female <NA>    <NA>  <NA>   <NA>
    #> 2 Male   <NA>    <NA>  <NA>   <NA>

## Average annual percent change (AAPC)

The function `get_aapc()` allows users to estimate the global trend even when no significant joinpoints were detected.

    get_aapc(mod1, digits = 1, show_ci = TRUE)
    #> # A tibble: 2 × 2
    #>   model  AAPC
    #>   <chr>  <chr>
    #> 1 Female -1.6% (-2.2%; -1.1%)
    #> 2 Male   -1.5% (-2.0%; -1.0%)

You can choose to show significance stars instead of CI:

    get_aapc(mod1, digits = 1, show_ci = FALSE)
    #> # A tibble: 2 × 2
    #>   model  AAPC
    #>   <chr>  <chr>
    #> 1 Female -1.6% *
    #> 2 Male   -1.5% *

## Summary tables

### Results as a data frame

    summary_jp(mod1)
    #> # A tibble: 2 × 7
    #>   group     jp period APC   CI_low CI_upp AAPC
    #>   <chr>  <dbl> <chr>  <chr> <chr>  <chr>  <chr>
    #> 1 Female     0 <NA>   <NA>  <NA>   <NA>   -1.6% *
    #> 2 Male       0 <NA>   <NA>  <NA>   <NA>   -1.5% *

### HTML Tables

    # id: tab-2
    mod2 |>
      summary_jp(digits = 1) |>
      jp_to_ft()

Group | JP | Period | APC | CI | AAPC
--- | --- | --- | --- | --- | ---
Female | 1 | 2010-2020 | -2.5% | -3.6%; -1.3% | -1.5% *
1 | 2020-2025 | 0.2% | -2.3%; 2.8% |
Male | 1 | 2010-2019 | -2.3% | -3.3%; -1.3% | -1.4% *
1 | 2019-2025 | 0.1% | -2.1%; 2.4% |
* p < 0.05 JP: number of joinpoints; APC: annual percent change; CI: 95% confidence interval; AAPC: average annual percent change (95% CI).

### HTML Tables by two grouping variables

    mod3 |>
      summary_jp(digits = 1) |>
      jp_to_ft()

Group | Subgroup | JP | Period | APC | CI | AAPC
--- | --- | --- | --- | --- | --- | ---
Central | Female | 1 | 2010-2019 | -4.7% | -4.9%; -4.6% | -1.7% *
Female | 1 | 2019-2025 | 3.4% | 3.0%; 3.8% |
Male | 2 | 2010-2014 | -3.9% | -4.5%; -3.3% | -1.5% *
Male | 2 | 2014-2019 | -4.7% | -5.1%; -4.4% |
Male | 2 | 2019-2025 | 3.1% | 2.8%; 3.3% |
East | Female | 2 | 2010-2015 | -5.5% | -6.1%; -4.9% | -3.0% *
Female | 2 | 2015-2019 | -8.0% | -8.6%; -7.4% |
Female | 2 | 2019-2025 | 3.1% | 2.6%; 3.6% |
Male | 2 | 2010-2014 | -4.9% | -5.3%; -4.5% | -2.9% *
Male | 2 | 2014-2019 | -7.2% | -7.6%; -6.9% |
Male | 2 | 2019-2025 | 2.1% | 1.8%; 2.4% |
North | Female | 2 | 2010-2015 | -5.2% | -5.6%; -4.7% | -1.8% *
Female | 2 | 2015-2019 | -6.8% | -8.2%; -5.5% |
Female | 2 | 2019-2025 | 4.7% | 4.2%; 5.1% |
Male | 2 | 2010-2015 | -4.7% | -5.1%; -4.3% | -1.5% *
Male | 2 | 2015-2019 | -5.9% | -6.2%; -5.5% |
Male | 2 | 2019-2025 | 4.4% | 4.1%; 4.7% |
South | Female | 1 | 2010-2019 | 3.3% | 3.1%; 3.6% | 0.3% *
Female | 1 | 2019-2025 | -3.9% | -4.3%; -3.6% |
Male | 1 | 2010-2019 | 2.8% | 2.6%; 3.0% | 0.2% *
Male | 1 | 2019-2025 | -3.6% | -3.9%; -3.4% |
West | Female | 2 | 2010-2018 | 2.2% | 2.0%; 2.4% | -1.0% *
Female | 2 | 2018-2019 | 0.2% | -1.9%; 2.4% |
Female | 2 | 2019-2025 | -5.6% | -6.0%; -5.3% |
Male | 1 | 2010-2019 | 1.9% | 1.7%; 2.1% | -0.9% *
Male | 1 | 2019-2025 | -5.0% | -5.5%; -4.6% |
* p < 0.05 JP: number of joinpoints; APC: annual percent change; CI: 95% confidence interval; AAPC: average annual percent change (95% CI).

Change the table language to Spanish

    mod3 |>
      summary_jp(digits = 1) |>
      jp_to_ft(lan = "es")

Grupo | Subgrupo | JP | Periodo | APC | IC | AAPC
--- | --- | --- | --- | --- | --- | ---
Central | Female | 1 | 2010-2019 | -4,7% | -4,9%; -4,6% | -1,7% *
Female | 1 | 2019-2025 | 3,4% | 3,0%; 3,8% |
Male | 2 | 2010-2014 | -3,9% | -4,5%; -3,3% | -1,5% *
Male | 2 | 2014-2019 | -4,7% | -5,1%; -4,4% |
Male | 2 | 2019-2025 | 3,1% | 2,8%; 3,3% |
East | Female | 2 | 2010-2015 | -5,5% | -6,1%; -4,9% | -3,0% *
Female | 2 | 2015-2019 | -8,0% | -8,6%; -7,4% |
Female | 2 | 2019-2025 | 3,1% | 2,6%; 3,6% |
Male | 2 | 2010-2014 | -4,9% | -5,3%; -4,5% | -2,9% *
Male | 2 | 2014-2019 | -7,2% | -7,6%; -6,9% |
Male | 2 | 2019-2025 | 2,1% | 1,8%; 2,4% |
North | Female | 2 | 2010-2015 | -5,2% | -5,6%; -4,7% | -1,8% *
Female | 2 | 2015-2019 | -6,8% | -8,2%; -5,5% |
Female | 2 | 2019-2025 | 4,7% | 4,2%; 5,1% |
Male | 2 | 2010-2015 | -4,7% | -5,1%; -4,3% | -1,5% *
Male | 2 | 2015-2019 | -5,9% | -6,2%; -5,5% |
Male | 2 | 2019-2025 | 4,4% | 4,1%; 4,7% |
South | Female | 1 | 2010-2019 | 3,3% | 3,1%; 3,6% | 0,3% *
Female | 1 | 2019-2025 | -3,9% | -4,3%; -3,6% |
Male | 1 | 2010-2019 | 2,8% | 2,6%; 3,0% | 0,2% *
Male | 1 | 2019-2025 | -3,6% | -3,9%; -3,4% |
West | Female | 2 | 2010-2018 | 2,2% | 2,0%; 2,4% | -1,0% *
Female | 2 | 2018-2019 | 0,2% | -1,9%; 2,4% |
Female | 2 | 2019-2025 | -5,6% | -6,0%; -5,3% |
Male | 1 | 2010-2019 | 1,9% | 1,7%; 2,1% | -0,9% *
Male | 1 | 2019-2025 | -5,0% | -5,5%; -4,6% |
* p < 0,05 JP: cantidad de joinpoints; APC: cambio porcentual anual; IC: intervalo de confianza al 95%; AAPC: cambio porcentual anual promedio (IC 95%).

## Regression plots

Default plot

    gg_jpoint(mod1)

Stack plots

    gg_jpoint(mod1, facets = "none")
    #> Number of columns will be ignored when facets 'none' or 'grid'.

Two grouping variables

    gg_jpoint(mod3)

Split by region and sex

    gg_jpoint(mod3, facets = "grid")
    #> Number of columns will be ignored when facets 'none' or 'grid'.

Modify the size of data points

    gg_jpoint(mod3, facets = "grid", psize = 5)
    #> Number of columns will be ignored when facets 'none' or 'grid'.

Modify the transparency of data points

    gg_jpoint(mod3, facets = "grid", ptr = 1)
    #> Number of columns will be ignored when facets 'none' or 'grid'.

Hide data points

    gg_jpoint(mod3, facets = "grid", obs = FALSE)
    #> Number of columns will be ignored when facets 'none' or 'grid'.
    #> Data points will not be displayed.

Hide joinpoint(s) marker(s)

    gg_jpoint(mod3, facets = "grid", jp = FALSE)
    #> Number of columns will be ignored when facets 'none' or 'grid'.
    #> Joinpoint(s) position(s) will not be displayed.

Change the default colorblind-friendly palette

    gg_jpoint(mod3, facets = "grid", jp = FALSE, cbpal = "blue_fluoride")
    #> Number of columns will be ignored when facets 'none' or 'grid'.
    #> Joinpoint(s) position(s) will not be displayed.

Disable colorblind-friendly palettes

    gg_jpoint(mod3, facets = "grid", cb = FALSE)
    #> Number of columns will be ignored when facets 'none' or 'grid'.
    #> Colorblind-friendly palettes disabled, use `scale_color_`functions to set line and point colors.