Mark-Recapture Distance Sampling

Animal abundance estimation via conventional, multiple covariate and mark-recapture distance sampling (CDS/MCDS/MRDS). Detection function fitting is performed via maximum likelihood. Also included are diagnostics and plotting for fitted detection functions. Abundance estimation is via a Horvitz-Thompson-like estimator.

Build Status CRAN (RStudio Mirror) Downloads CRAN Version Coverage Status

This package for R analyzes single or double observer distance sampling data for line or point sampling. It is used in program DISTANCE as one of the analysis engines. Supported double observer configurations include independent, trial and removal. All options in mrds are not yet fully supported via DISTANCE.

Getting mrds

The easiest way to ensure you have the latest version of mrds, is to install Hadley Wickham's devtools package:


then install mrds from github:



  • One can download a Windows package binary using the "Releases" tab in github. To install in R, from the R menu, use "Packages\Install from Local Zip file" and browse to location of downloaded zip.
  • Or, download package source files.
  • Finally the current stable version of mrds is available on CRAN, though this may be up to a month out of date due to CRAN policy.


The following are references for the methods used in the package.

Burt, M. L., D. L. Borchers, K. J. Jenking and T. A. Marques. (2014). "Using mark-recapture distance sampling methods on line transect surveys." Methods in Ecology and Evolution 5: 1180-1191.

Buckland, S. T., J. Laake, et al. (2010). "Double observer line transect methods: levels of independence." Biometrics 66: 169-177.

Borchers, D. L., J. L. Laake, et al. (2006). "Accommodating unmodeled heterogeneity in double-observer distance sampling surveys." Biometrics 62(2): 372-378.

Buckland, S. T., D. R. Anderson, et al., Eds. (2004). Advanced distance sampling: estimating abundance of biological populations. Oxford, UK; New York, Oxford University Press. (see chapter 6).


mrds 2.2.0

  • fixed bug in calculation of Kolmogorov-Smirnov p-values. Previous methods did not take into account that parameters of the detection function were estimated, so a new bootstrap-based approach has been implemented. As this is time-consuming, the Kolmogorov-Smirnov test is no longer performed by default (use ks=TRUE to get the test).
  • Encounter rate variance for point transects when points were not all sampled an equal number of times was incorrect. mrds now uses the P3 estimator from Fewster et al (2009) for point transect encounter rate variance.
  • Bug in predicting when left truncation is used. Previously if the distance column in the new data was set to zero and left truncation was > 0 predictions were discarded, this was particularly problematic for io, etc MRDS models. Thanks to Natalie Kelly for spotting this and suggesting a fix.
  • Add errors when "P3" is used as an encounter rate variance estimator with non-point transect data, throws a warning and switches to P3 for points when it's not specified.

mrds 2.1.18

  • fixed bug in parameter rescaling where scales were incorrectly entered as 1 due to an indexing bug
  • Quantile-quantile plots now use an aspect ratio of 1
  • Bug in half-normal integration code when no adjustments are used lead to likelohood being evaluated incorrectly for models with binned (grouped) distances. This only effected AIC comparisons between models and parameter estimates should have been the same. Thanks to Olivier Devineau for spotting this!
  • Fix bug where predict.ds() didn't work with uniform keys. Thanks to Jason Roberts for reporting this bug.
  • Correctly specify distbegin/distend for predictions with binned data, thanks to Jason Roberts for spotting this bug.
  • Let the user know that int.range was set in summary() results

mrds 2.1.17

  • fixed starting value bug for hazard-rate models when distances are binned. Thanks to Natalia Schroeder and Eric Rexstad for discovering this.
  • predict.ds now uses numerical integration to calculate integrals (rather than an approximation). Thanks to Eric Rexstad for spotting an issue with goodness of fit testing that highlighted this.
  • plot.ds() now accepts an xlab="" argument to change the x axis label. Thanks to Steve Ahlswede for suggesting this.

mrds 2.1.16

  • improved predict() method now does the Right Thing with factors
  • Fixed bug in scaling of histograms for point transect pdf plots and points on those plots. Thanks to Erics Howe and Rexstad for reporting these issues.
  • You can now set y axis limits when using plot.ds, defaults should be more sensible for pt+point models. Thanks to Eric Howe for the suggestion.
  • Fixed bug when setting initial values that threw many errors. Thanks to Laura Marshall for spotting this.

mrds 2.1.15

  • rescaling parameters were not correct, now fixed. Thanks to Laura Marshall for spotting this.
  • coefficients are called coefficients (not a mixture of coefficients and parameters) in summary() results
  • speed-up in models (thanks to Winston Chang's profvis, showing many unecessary calls to model.matrix)
  • plot.ds now has a pdf= option to plot the probability density function (for point transect models only)
  • assign.par, create.ddfobj and detfct are now exported, so it can be used by dsm (though shouldn't be used by anything else!)
  • fixed bug in left truncation where probability of detection was not calculated correctly. Thanks to Jason Roberts for pointing this out!

mrds 2.1.14

  • updated initialvalues calculation for hazard-rate -- now uses Beavers & Ramsay method to scale parameters for hazard-rate
  • automatic parameter rescaling for covariate models when covariates are poorly scaled. Now default for nlminb method
  • minor speed-up to logistic code when distance is a covariate

mrds 2.1.13

  • link to distance sampling Google Groups in help
  • duplicate non-convergence warning/error removed
  • warning of singular Hessian is now a warning()
  • re-wrote the debug output to be easier to read
  • dht now has an option (ci.width) to specify confidence interval width in output (thanks to David Pavlacky for the suggestion)
  • monotonicity now operates over left->right truncation for models that are left truncated and will fail with an error message if many integration intervals are used. Thanks to Tiago Marques for highlighting this issue.

mrds 2.1.12

  • \donttest{} examples are now \dontrun{}.

mrds 2.1.11

  • Bug in unif+cos(1) models when using monotonicity constraints and randomised starting points. Since the model only has 1 parameter, there is a bug in selecting columns in Rsolnp starting value code that makes the result be a vector, which then doesn't work with an apply later. Workaround of not using randomised starting values in mrds for that model. Thanks to Nathalie Cavada for finding this bug.

  • Fixed bug in pdot.dsr.integrate.logistic which was giving incorrect AIC values for FI models with binned data for points or lines.

  • Fixed issue where returned optimisation obejct got accessed without being checked to see if it's result was an error, causing problems when encapsulating ddf in other functions.

mrds 2.1.10

  • added testing directory to .Rbuildignore, tests are now not included in built packages and are not run on CRAN. For tests use the source packages on github.

mrds 2.1.9


  • removed test that failed on CRAN's testing

mrds 2.1.8


  • removed doeachint/cgftab code, which used a spline approximation to the effective strip width/effective area when a half-normal detection function was used. This has been replaced with exact calculation via the error function (erf).
  • tests updated accordingly
  • monotonically constrained models now use a bunch of random start points -- uses gosolnp() from Rsolnp
  • re-fitting by jiggling parameters refined to multiply by a uniform variable with limits set as the upper and lower bounds (+/-1) so jiggling can go either way, on approximately the same scale as the parameters
  • corrected documentation for predict methods, which incorrectly stated what is returned for point transect models. Thanks to Thibault Dieuleveut for spotting this.


  • fixed 2 bugs in create.varstructure; the first was for removal method which was being treated as a trial method. The second was when obs.table was not specified (Region and sample labels in dataframe for each obs) and there was dual observers. In that case it was doubling the number of observations.
  • fixed a bug in dht.deriv which had not been setup for removal; thanks to John Boulanger for noticing and reporting both of these bugs

mrds 2.1.7


  • Standardisation was being applied to detection functions (such that g(0)=1) when there were no adjustments (which is uneccesary) but also caused issues when using gamma detection functions as this should be calculated at g(apex) instead. Standardisation code has been removed for when there are no adjustments and the correct scaling used for the gamma when there are. Thanks to Thomas Doniol-Valcroze for alerting us to this bug.
  • Partial name-matching in dht was fixed. Produced warning but not error.


  • Tests for gamma detection functions
  • Observations are automatically ordered by object and observer fields (if included) in ddf as expected by double observer analysis. A erroneous error message can be created if they are not ordered correctly or worse. Thanks to Ainars Aunins for bringing this to our attention.
  • Added function create_document() which will run a shiny application interface to mrds and will create a knitr document from a template. The template currently is only for a single observer analysis and is behind on all of the features for the app which is fairly complete.

mrds 2.1.6


  • some key+adjustment models failed to converge due to bugs in the optimisation code (mainly unif+cosine models)


  • optimisation tips help page at ?"mrds-opt"

mrds 2.1.5


  • models with both adjustment terms and covariates are now allowed
  • mono.check function checks that a detection function is monotonic over its range (at the observed covariate combinations if covariates are included)

mrds 2.1.4-5


  • new testthat changes test locations etc, this has been sorted out.
  • which= argument in plot.* now sorts the which first, so plots will always be in order
  • plot.ds is now more friendly to par() users, thanks to Jason Roberts for the pointer


  • uniform+cosine detection functions were ignored when using monotonicity constraints, now they can be used together
  • mono.strict=TRUE didn't automatically turn on mono=TRUE, extra logic to correct this
  • montonicity constraints did not use standardised (g(x)/g(0) detection functions, so if g(x)>1 monotonicity constraints were voilated. Now standardised detection functions are used. Thanks to Len Thomas for noticing this bug.

mrds 2.1.4-3


  • did not work for new data (thanks to Len Thomas and Phil Hammond for pointing this out)


  • general documentation updates
  • simplication and re-structuring of internals

mrds 2.1.4-3


  • internal re-structuring of summary methods
  • more tests

mrds 2.1.4-2


  • plot.ds now has a new argument, if TRUE (default) it will create a new window for each plot.
  • general janitorial work inside plotting methods, removing and simplifying old code; (hopefully) no new features.

mrds 2.1.4-1


  • Warning now issued when truncation is set to the largest distance by default.

  • updated dht documentation

mrds 2.1.4


  • modified det.tables and plot.det.tables so it does not create and plot some tables depending on observer configuration (io,trial,removal).

  • to plot functions (other than plot.ds) added argument subtitle=TRUE (default). It can be either TRUE, FALSE. If TRUE it shows sub-titles for plot type. If FALSE, no subtitles are shown. With this argument it is possible to get subtitles without main title.

  • set iterlimit=1 in call to rem.glm from to prevent convergence issues in getting starting values.

  • created average.line.cond and it is now used in place of calcp.mrds which was computing average line for conditional detection function by weighting values by estimated population proportions for each covariate value. It is now weighted by sample proportions (mean value).

mrds 2.1.3-1


  • patched so if vc1=NA it will not fail

  • patched plot.ds to only issue when not using another graphics device so it plays nice with Distance.

mrds 2.1.3


  • patched bug in dht which was returning incorrect values in bysample for sample.area and Dhat.

  • patched code in so it would skip over variance component for p when key=unif and p=1.


  • modified code in and io and rem functions to adapt to changes in optimx

  • removed old depends statements to optimx and Rsolnp; uses import

mrds 2.1.2


  • fixed usage and example lines that were too long

mrds 2.1.1


  • for full independence methods, the calculation for the distance sampling component was for unbinned data only. Code has been added to compute this component correctly for binned data. This required changes to each of the routines and for the logistic integration routines.


  • Modified flpt.lnl code to set integrals to 1E-25 if <=0

  • In integrate.pdf a vector argument for the integration range is converted to matrix if of length 2.

  • ddf.gof will now use breaks set for binned data unless others are specified.


  • Added threshold detection functions ("th1" and "th2") which required some minor changes in other functions for summary/print.

  • Added xlab and ylab arguments to plot functions to over-ride default labels

mrds 2.1.0


  • Modified DESCRIPTION so only R 2.15 or greater is allowed. Needed for optimHess jll(12/10/2012)

mrds 2.0.9


  • New option plot=TRUE/FALSE in qqplot.ddf(), for when you only want the K-S and CvM test statistics, not plotting. dlm(11/13/2012)


  • Fixed problem when obs dataframe in call to dht (which links observations to samples and regions) contained fields also in observation dataframe. Now only fields needed from obs are selected before merge. dlm(11/13/2012)

mrds 2.0.8

  • Unchanged version sent out with Distance in summer 2012

mrds 2.0.7


  • Restructured likelihood/integration code for fitting ds models

  • Adjustment functions will now work with binned data. Code was added to assure that fields distbegin and distend are available if binned=TRUE and breaks are set as well.

  • Added argument adj.exp which if set to TRUE will use keyexp(adj) rather than keyadj to keep f(x)>0

  • Added following restrictions for adjustments: if uniform key, adj.scale must be "width"; if non-uniform key and adj.scale="width", doeachint set to TRUE because scale integration will not work.

  • Changed code in several functions so a uniform key with no adjustment functions could be used.

  • New option plot=TRUE/FALSE in qqplot.ddf(), for when you only want the K-S and CvM test statistics, not plotting.


  • Fixed inconsistencies in use and documentation of showit argument

  • Fixed a bug where groups were not recognised in dht() when the size column occurred in both model data and observation table. (Thanks to Darren Kidney for spotting this.)

mrds 2.0.6


  • Example code for binned point count data added to help for ddf

  • Modified and to use starting values from iterative offset glm to make optimization more robust

  • Added a restriction so no one attempts fitting adjustment functions with covariates.

  • Added some code to assure all of the necessary fields are available for binned data (binned=TRUE).


  • Patched create.ddfobj so that point counts with binned data would work properly

  • Patched ddf.ds such that stored data in object$data has detected=1

  • Patched to throw an error when optimx() does not converge

  • Patched and so inclusion of factor(observer) will work in formula

  • Patched dht, and covered.region.dht so it would handle 0 observations

  • Suppress package messages from optimx

  • Patched fpt.lnl, flt.lnl, print.ddf, model.description, summary.ds, print.summary.ds and, coef.trial, coef.rem,, plot.trial, and plot.rem to handle uniform key function.

mrds 2.0.5


  • First version submitted to CRAN


  • Fixed code in such that it uses sample size from detection model in Satterthwaite approximation rather than size of selected subset of observations.

  • Fixed coef functions so they would return parameter estimates for adjustment functions if any.

mrds 2.0.4


  • Changed flt.var to compute variance of average p correctly for point transects.

  • Numerous changes by dlm to optimization code

  • Changes to documentation to remove non-ASCII characters

mrds 2.0.3


  • Major rewrite to ddf and summary functions to handle adjustment functions


  • Changes to det.tables and gof functions to use include.lowest=TRUE in calls to cut function

  • Changed all usage of T and F to TRUE and FALSE

mrds 2.0.2

  • For changes in 2.0.2 and earlier see ONEWS

Reference manual

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


2.2.5 by Laura Marshall, 7 months ago

Report a bug at

Browse source code at

Authors: Jeff Laake <[email protected]> , David Borchers <[email protected]> , Len Thomas <[email protected]> , David Miller <[email protected]> and Jon Bishop

Documentation:   PDF Manual  

Task views: Analysis of Ecological and Environmental Data

GPL (>= 2) license

Imports optimx, mgcv, numDeriv, Rsolnp

Suggests testthat, covr

Imported by dsims.

Depended on by DSsim, Distance, dsm, mads.

See at CRAN