Control Polygon Reduction

Implementation of the Control Polygon Reduction and Control Net Reduction methods for finding parsimonious B-spline regression models.

Project Status: Active – The project has reached a stable, usable state and is being actively developed. Build Status Coverage Status CRAN_Status_Badge

An R package for implementing the Control Polygon Reduction model selection method. When we are tasked with modeling the functional relationship between a response and a continuous predictor, i.e., y = f(x), CPR allows for quick and efficient searching of a large model space to find B-spline estimates of the function f(x).

CPR extends to multiple dimensions and allows one to find good locations for knots in a tensor product of B-splines.

Learn More About CPR.

This model selection method was developed as part of Peter DeWitt's PhD dissertation work.


There is one vignette included with the package, for now. Additional details will be added to this vignette.

vignette('cpr-pkg', package = 'cpr')

Additional vignettes may also be authored soon.

Related Publications:

  • The CPR method was presented at the 28th International Biometric Conference held July 2016, in Victoria, British Columbia, Canada. The abstract, paper, and talk had the title: "Parsimonious B-splines Regression Models via Control Polygon Reduction." A bibtex entry for the abstract:
  author       = {DeWitt, Peter E. and Carlson, Nichole E. and Samantha MaWhinney},
  title        = {Parsimonious B-spline Regression Models via Control Polygon Reduction},
  booktitle    = {Abstracts for the XXVIIIth International Biometric Conference},
  month        = {July},
  year         = {2016},
  organization = {International Biometric Society},
  address      = {Victoria, British Columbia},
  url          = {},
  isbn         = {978-0-9821919-4-1}

Awards: The presentation of the work earned Peter DeWitt two awards:

  1. "Best Student Oral Presentation" from the International Biometric Society (IBS).
  2. "Distinguished Oral Presentation" as part of the student paper competition hosted by the Western North American Region (WNAR) of the IBs.

Installing CPR

Options for installing CPR:

  1. Install from the Comprehensive R Archive Network (CRAN)
# within R
install.packages("cpr", repos = "")
  1. Install the developmental version from github. This will require you to have devtools installed, and, if you are using Windows, you'll need Rtools installed as well.
install_github("dewittpe/cpr", build_vignettes = TRUE)
  1. Clone the repo and use GNU make
make install
  1. Go to the release page and down load the tar.gz file of the version you want to install.
  • Install from the command line
R CMD INSTALL cpr_<version>.tar.gz
  • Within R
install.packages(<path_to_file>, repos = NULL, type="source")

Other Notes:

The cpr package provides 3D graphics via the rgl package. If you are get an error, or rather message, of the form:

  font family "sans" not found, using "bitmap"

Then there is an easy fix. You need to get the FreeType 2 font engine.

On Debian, you can get the library via:

apt-get install libfreetype6-dev

Once the FreeType 2 font engine has been installed on your computer you must reinstall the rgl package.



New Features

  • plot.cpr_cn suports rgl and plot3D graphics

Version 0.2.2

New Features

  • get_spline is an S3 method for getting a data.frame of interpolated values of a spline given a cpr_cp object. Later development will add methods for cpr_cn objects.
  • predict.cpr_cp and predict.cpr_cn methods added
  • matrix_rank added
  • update_bsplines and update_btensor methods added (#27)

Version 0.2.1

Documentation improvements.

New Features

  • influence_of and plot.cpr_influence_of provide a clean interface for users to explore the influence of a set of knots on a spline function. (#19)
  • color (TRUE/FALSE) option added to plot.cpr_bs.
  • plot.cpr_cn lets the user plot 2D surfaces for tensor product surfaces. The plots are for the whole surface if the input is a 2D tensor product, and is a 2D slice evaluated at a given value for other margins for 3+ dimensional tensor products.
  • is. a collection of is.cpr_cp, is.cpr_bs, ... functions added.
  • The dataset spdg has been added to the package.

Non-User Visible Changes

  • removed a redundant build_tensor definition

Version 0.2.0

This version has a fairly polished set of tools for b-splines, cpr, and cnr. This version seems to be in a good place for use in the three major papers

  1. Methods 1: uni-variable functions,
  2. Methods 2: multi-variable functions, and
  3. Software paper.

Continued development should be focused on bug fixes and minor enhancements.

New Features

  • Option to save fits in cnr (#8)
  • Option to define the number of polynomial coefficients to use in cnr (#10)
  • x-axis tick label options for plotting b-splines (#12)
  • added show_xi to cpr:::plot.cp and using ggplot2::geom_rug to show the location of the knots for each of the control polygons plotted.
  • summary for cpr_cn and cpr_cnr objects added.
  • plot method for cpr_cnr objects.
  • margin option in cnr allows the user to specify which marginals CNR will be applied to.
  • Using sec.axis option from ggplot2_2.2.0 for the plotting of the knot sequence and numeric values in plot.cpr_bs (#18)

Bug Fixes

  • from and to args for plot.cpr_cpr fixed (#14)
  • correct construction of missing iknots argument in btensor
  • keep is correctly handled in the cnr call.
  • show_xi correctly handled in the plot.cpr_cp call.

Non-User visible changes

  • non-exported function knot_expr created to help with plotting the knot locations in cpr:::plot.cpr_bs.

Version 0.1.1

New Features

  • plot.cpr_cp allows the user to suppress the plotting of the control polygon. When plotting multiple control polygons and splines, this option will make it easier to view the spline functions.

Non-visible changes:

  • Extended testing scripts.

Version 0.1.0

First version of univariable cpr methods ready for deployment

Big picture

cpr::cp and cpr::cpr have been used for the simulations which are aimed to be part of the first manuscript. Modifications might be needed, but hopefully the univariable methods are stable.

A lot of changes in the implementation and API have occurred from the 0.0.x series. The aim for version 0.2.0 will be to have a very similar API for cpr::cn and cpr::cnr as provided for the cpr::cp and cpr::cpr calls.

version 0.0.5

New Features

  • First and second derivatives of B-splines via bsplineD

Extended Documentation

  • Examples added to bsplines

End User non-visible changes:

  • Added the not-to-be-exported function generate_cp_data
  • Redesign of the deboor.cpp file so that the bsplines are accessible. The prior design only allowed access to the basis, the current design allows access to the generic B-splines.

version 0.0.3

Version 0.0.3 is the version of the package used to run the analysis and simulations presented in the paper submitted to the 28th International Biometrics Conference, Western North American Region (WNAR) of the Internal Biometric Society, Student paper competition. The conference will be held 10 - 16 July 2016 in Victoria, British Columbia, Canada.

Bug Fixes

  • Corrected the attr calls within cpr after adjusting the attributes being set on a cpr_cp.

  • plot.cpr_bs correctly displays the indices for the knot sequence.

End User Visible changes:

  • The knot insertion matrix W is accessible to the end user in a new way. Names of functions in boehem.cpp are cleaner.
  • plot.cpr_cpr allows user to select either control polygons or sums of squared residuals to be plotted.


  • Removed the background vignette... to much detail right now, too much time required to build and install the package.

End User non-visible changes:

  • Redundant definition of greville_sites removed.

version 0.0.2

new features

  • Added the function tensor for building tensor products of cpr::bsplines.
  • Added the function influence_weights to get the influence weights for each internal knot on each marginal of a tensor product.
  • is.cpr_bs added.
  • S3 methods for cp

Bug Fixes

  • trimmed quantile handles the use_unique option correctly
  • better handling of ... in cp() and cpr()


First usable version with the method based on the 'importance weight' of internal knots based on reversing the methods presented by Boehm (1980). Development of metrics and methods for parsing out the preferable models.

Version was the first stable version for fitting the exact data model.


  • The beginnings of the control-polygon vignette started (version

version 0.0.1

This version was based on the idea that using an angle to reduce the control polygon was a good idea. Further literature review and simulations showed otherwise. This version is marked for posterity and the cpp functions are going to be useful in the following versions as well.

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.


0.2.3 by Peter DeWitt, a year ago

Browse source code at

Authors: Peter DeWitt [aut, cre], Samantha MaWhinney [ths], Nichole Carlson [ths]

Documentation:   PDF Manual  

GPL (>= 2) license

Imports dplyr, ggplot2, lazyeval, lme4, magrittr, plot3D, Rcpp, rgl, tibble, tidyr

Suggests covr, geepack, knitr, Matrix, testthat, rmarkdown

Linking to Rcpp, RcppArmadillo

See at CRAN