Skip to content

Commit

Permalink
Merge pull request #9 from MindTheGap-ERC/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
NiklasHohmann authored Jul 21, 2024
2 parents c536d6d + 834201c commit bbf1130
Show file tree
Hide file tree
Showing 19 changed files with 274 additions and 174 deletions.
12 changes: 11 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@ Version: 0.0.0.9000
Authors@R:
person("Niklas", "Hohmann", , "[email protected]", role = c("aut", "cre"),
comment = c(ORCID = "0000-0003-1559-1838"))
Description: Models for stratigraphic paleobiology, including niche modeling and age-depth modeling.
Description: The fossil record is a joint expression of ecological, taphonomic,
evolutionary, and stratigraphic processes (Holland and Patzkowsky, 2012).
This package allowing to simulate biological processes in the time domain
(e.g., trait evolution, fossil abundance), and examine how their expression
in the rock record (stratigraphic domain) is influenced based on
age-depth models, ecological niche models, and taphonomic effects.
Functions simulating common processes used in modeling trait evolution or
event type data such as first/last occurrences are provided and can be used
standalone or as part of a pipeline. The package comes with example
data sets and tutorials in several vignettes, which can be used as a
template to set up one's own simulation.
License: Apache License (>= 2)
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
Expand Down
5 changes: 3 additions & 2 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Generated by roxygen2: do not edit by hand

export(apply_niche_pref)
export(apply_niche)
export(apply_taphonomy)
export(cnd)
export(bounded_niche)
export(ornstein_uhlenbeck)
export(p3)
export(p3_var_rate)
export(random_walk)
export(rej_samp)
export(snd_niche)
export(stasis)
export(thin)
27 changes: 14 additions & 13 deletions R/apply_niche_pref.R → R/apply_niche.R
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
apply_niche_pref = function(x, niche_def, gc){
apply_niche = function(x, niche_def, gc){
#' @export
#'
#' @title apply niche preference
#' @title apply niche model to events
#'
#' @param x events, e.g. times/ages of fossil occurrences or their stratigraphic position.
#' @param niche_def function, specifying the niche along a gradient. Should return 0 when taxon is outside of niche, and 1 when fully inside niche. Values between 0 and 1 are interpreted as probabilities.
#' @param niche_def function, specifying the niche along a gradient. Should return 0 when taxon is outside of niche, and 1 when inside niche. Values between 0 and 1 are interpreted as collection probabilities.
#' @param gc function, stands for "gradient change". Specifies how the gradient changes, e.g. with time
#'
#' @description
#' Models niche preferences by removing events (fossil occurrences) when they are outside of a preferred niche using the function `thin`.
#' Combines the functions `niche_def` and `gc` ("gradient change") to determine how the taxons' preferred environment changes with time. This is done by composing `niche_def` and `gc`. The result is then used as a thinning on the events `x`.
#' Models niches by removing events (fossil occurrences) when they are outside of their niche using the function `thin`.
#' Combines the functions `niche_def` and `gc` ("gradient change") to determine how the taxons' collection probability changes with time/position. This is done by composing `niche_def` and `gc`. The result is then used as a thinning on the events `x`.
#'
#' @examples
#' \dontrun{
Expand All @@ -22,31 +22,32 @@ apply_niche_pref = function(x, niche_def, gc){
#' main = "gradient change with time")
#' # define niche
#' # preferred wd 10 m, tolerant to intermediate wd changes (standard deviation 10 m), non-terrestrial
#' niche_def = cnd(mean = 10, sd = 10, inc = 40, cut_neg = TRUE)
#' niche_def = snd_niche(opt = 10, tol = 10, cutoff_val = 0)
#' plot(seq(-1, 50, by = 0.5), niche_def(seq(-1, 50, by = 0.5)), type = "l",
#' xlab = "water depth", ylab = "preference", main = "Niche def")
#' xlab = "water depth", ylab = "collection probability", main = "Niche def")
#' # niche pref with time
#' plot(t, niche_def(gc(t)), type = "l", xlab = "time", ylab = "preference", main = "pref with time")
#' plot(t, niche_def(gc(t)), type = "l", xlab = "time",
#' ylab = "collection probability", main = "collection probability with time")
#'
#' ## simulate fossil occurrences
#' foss_occ = p3(rate = 100, from = 0, to = max(t))
#' # foss occ without niche pref
#' hist(foss_occ, xlab = "time")
#' foss_occ_niche = apply_niche_pref(foss_occ, niche_def, gc)
#' foss_occ_niche = apply_niche(foss_occ, niche_def, gc)
#' # fossil occurrences with niche preference
#' hist(foss_occ_niche, xlab = "time")
#'
#' # see also
#' vignette("event_data")
#' # for a longer example
#' # for a detailed example on niche modeling
#'
#' }
#'
#' @seealso [apply_taphonomy()] to model taphonomic effects based on the same principle, [thin()] for the underlying mathematical procedure.
#' @seealso [apply_taphonomy()] to model taphonomic effects based on the same principle, [thin()] for the underlying mathematical procedure. Basic niche models available are [bounded_niche()] and [snd_niche()]

# function that returns niche preference as a function of y (typically time)
# function that returns collection probability as a function of y (typically time)
change_in_niche = function(y) niche_def(gc(y))
# thin events based on niche preference
# thin events based on collection probability
r = thin(x, change_in_niche)
return(r)
}
6 changes: 3 additions & 3 deletions R/apply_taphonomy.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apply_taphonomy = function(x, pres_potential, ctc){
#' @export
#'
#' @title Model taphonomic effects
#' @title model taphonomic effects
#'
#' @param x events, e.g. times/ages of fossil occurrences or their stratigraphic position.
#' @param pres_potential function. Takes taphonomic conditions as input and returns the preservation potential (a number between 0 and 1)
Expand All @@ -11,13 +11,13 @@ apply_taphonomy = function(x, pres_potential, ctc){
#' Models taphonomy by combining the change in taphonomic conditions with the preservation potential as a function of taphonomic conditions to determine how preservation potential changes. This is then used to systematically remove (thin) the event data using `thin`.
#'
#'
#' @seealso [apply_niche_pref()] for modeling niche preferences based on the same principle, [thin()] for the underlying mathematical procedure.
#' @seealso [apply_niche()] for modeling niche preferences based on the same principle, [thin()] for the underlying mathematical procedure.
#'
#'

# function that returns preservation potential as a function of input (e.g. time or position)
change_pres_pot = function(y) pres_potential(ctc(y))
# thin events based on preservation potential
# thin events
r = thin(x, change_pres_pot)
return(r)
}
38 changes: 38 additions & 0 deletions R/bounded_niche.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
bounded_niche = function(g_min, g_max){
#' @export
#'
#' @title define niche from boundaries
#'
#' @param g_min lowest value of the gradient the taxon can tolerate
#' @param g_max highest value of the gradient the taxon can tolerate
#'
#' @seealso [snd_niche()] for an alternative niche model, [apply_niche()] for the function that uses the function returned
#'
#' @returns a function describing the niche for usage with `apply_niche`. The function returns 1 if the taxon is within its niche (the gradient is between `g_min` and `g_max`), and 0 otherwise
#'
#' @description
#' Defines a simple niche model where the niche defined is given by a lower limit (`g_min`) and an upper limie (`g_max`) of a gradient the taxon can tolerate
#'
#' @examples
#' \dontrun{
#' x = seq(0, 10, by = 0.2)
#' f = bounded_niche(2,5)
#' plot(x, f(x), type = "l",
#' xlab = "Gradient", ylab = "Observation probability",
#' main = "Observation probability of taxon")
#'
#' # see also
#' vignette("event_data")
#' # for details how to use this functionality
#' }
#'
if (g_max <= g_min){
stop("inconsistent boundaries, inputs must be ordered.")
}
f = function(x){
y = rep(0, length(x))
y[x <= g_max & x >= g_min ] = 1
return(y)
}
return(f)
}
45 changes: 0 additions & 45 deletions R/cnd.R

This file was deleted.

47 changes: 47 additions & 0 deletions R/snd_niche.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
snd_niche = function(opt, tol, prob_modifier = 1, cutoff_val = NULL){
#'
#' @export
#'
#' @title simple niche model
#'
#' @param opt optimum value, gradient value where collection probability is highest
#' @param tol tolerance to changes in gradient. For large values, collection probability drops off slower away from `opt`
#' @param prob_modifier collection probability modifier, collection probability at `opt`.
#' @param cutoff_val NULL or a number. If a number, all collection probabilities at gradient values below `cutoff_value` are set to 0. This can for example be used to model exclusively marine species when the gradient is water depth (see examples).
#'
#' @returns a function for usage with `apply_niche`.
#'
#' @examples
#' \dontrun{
#' # using water depth as niche
#' wd = seq(-3, 40, by = 0.5)
#' f = snd_niche(opt = 10, tol = 5)
#'
#' plot(wd, f(wd), xlab = "Water depth", ylab = "Prob. of collection")
#' # set cutoff value at to 0 to model non-terrestrial species.
#' f = snd_niche(opt = 10, tol = 5, cutoff_val = 0)
#' plot(wd, f(wd), xlab = "Water depth", ylab = "Prob. of collection")
#'
#' # see also
#' vignette("event_data")
#' #for examples how to use it for niche modeling
#' }
#'
#'
#' @seealso [apply_niche()] for usage of the returned function, [bounded_niche()] for another niche model
#' @description
#' Defines niche model based in the "Probability of collection" model by Holland and Patzkowsky (1999).
#' The collection probability follows the shape of a bell curve across a gradient, where `opt` determines the peak (mean) of the bell curve, and `tol` the standard deviation. "snd" stands for "scaled normal distribution", as the collection probability has the shape of the probability density of the normal distribution.
#' @references * Holland, Steven M. and Patzkowsky, Mark E. 1999. "Models for simulating the fossil record." Geology. https://doi.org/10.1130/0091-7613(1999)027%3C0491:MFSTFR%3E2.3.CO;2

fa = function(x){
f_inv = stats::dnorm(opt, opt, tol)
y = pmin(prob_modifier/f_inv * stats::dnorm(x, opt, tol), rep(1, length(x)))
if (!is.null(cutoff_val)){
y[x<= cutoff_val] = rep(0, length(y[x<=cutoff_val]))
}
return(y)
}

return(fa)
}
4 changes: 2 additions & 2 deletions R/thin.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ thin = function(x, thin){
#' @description
#' Thins a vector of events using the function thin, meaning the probability that the ith event in x is preserved is given by _thin(x(i))_. Values of
#' `thin` below 0 and above 1 are ignored.
#' Is used to model niche preferences in `apply_niche_pref` and taphonomic effects in `apply_taphonomy`.
#' Is used to model niche preferences in `apply_niche` and taphonomic effects in `apply_taphonomy`.
#'
#' @examples
#' \dontrun{
Expand All @@ -22,7 +22,7 @@ thin = function(x, thin){
#' hist(yy) # note how values of 5 * sin above 1 are not affecting the thinning
#' }
#'
#' @seealso [apply_niche_pref()] and [apply_taphonomy()] for use cases with biological meaning
#' @seealso [apply_niche()] and [apply_taphonomy()] for use cases with biological meaning

p = pmax(pmin(thin(x), rep(1, length(x))), rep(0, length(x))) # cut off at 0 and 1
ind = stats::rbinom(n = length(x), size = 1, prob = p) # determine if preserved or not
Expand Down
39 changes: 23 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,40 @@
# StratPal

<!-- badges: start -->

[![R-CMD-check](https://github.com/MindTheGap-ERC/StratPal/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/MindTheGap-ERC/StratPal/actions/workflows/R-CMD-check.yaml)

<!-- badges: end -->

R package for stratigraphic paleobiology modeling pipelines.

## Overview

The fossil record is a joint expression of ecological, taphonomic, evolutionary, and stratigraphic processes ([Holland and Patzkowsky, 2012](#References)). This package allowing to simulate biological processes in the time domain (e.g., trait evolution, fossil abundance), and examine how their expression in the rock record (stratigraphic domain) is influenced based on age-depth models, ecological niche models, and taphonomic effects. Functions simulating common processes used in modeling trait evolution or event type data such as first/last occurrences are provided and can be used standalone or as part of a pipeline. The package comes with example data sets and tutorials in several vignettes, which can be used as a template to set up one's own simulation.

## Authors

__Niklas Hohmann__
Utrecht University
email: n.h.hohmann [at] uu.nl
Web page: [uu.nl/staff/NHohmann](https://www.uu.nl/staff/NHHohmann)
**Niklas Hohmann**\
Utrecht University\
email: n.h.hohmann [at] uu.nl\
Web page: [uu.nl/staff/NHohmann](https://www.uu.nl/staff/NHHohmann)\
Orcid: [0000-0003-1559-1838](https://orcid.org/0000-0003-1559-1838)

## Requirements

R version >= 4.2
R version \>= 4.2

## Installation

To install the package, first install the _remotes_ package by running
To install the package, first install the *remotes* package by running

```R
``` r
install.packages("remotes")
```

in the R console. Then, run

```R
``` r
remotes::install_github(repo = "MindTheGap-ERC/StratPal",
build_vignettes = TRUE,
ref = "HEAD",
Expand All @@ -41,13 +47,13 @@ to install the latest stable version of the package.

Run

```R
``` r
library(StratPal)
```

to load the package. Use

```R
``` r
browseVignettes(package = "StratPal")
```

Expand All @@ -65,15 +71,16 @@ Apache 2.0, see LICENSE file for license text.

Copyright 2024 Netherlands eScience Center and Utrecht University

## References
## References {#References}

- Holland, Steven M. and Patzkowsky, Mark E. "Stratigraphic Paleobiology : Understanding the Distribution of Fossil Taxa in Time and Space."" The University of Chicago Press; 2012.

This package uses data from

* Identification of the mode of evolution in incomplete carbonate successions
Niklas Hohmann, Joël R Koelewijn, Peter Burgess, Emilia Jarochowska
bioRxiv 2023.12.18.572098; doi: [10.1101/2023.12.18.572098](https://doi.org/10.1101/2023.12.18.572098), published under a [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/) license.
- Hohmann, Niklas; Koelewijn, Joël R.; Burgess, Peter; Jarochowska, Emilia. 2024. "Identification of the mode of evolution in incomplete carbonate successions." BMC Ecology and Evolution, In Press. <https://doi.org/10.1101/2023.12.18.572098>.

- Hohmann, Niklas, Koelewijn, Joël R.; Burgess, Peter; Jarochowska, Emilia. 2023. "Identification of the Mode of Evolution in Incomplete Carbonate Successions - Supporting Data." Open Science Framework. <https://doi.org/10.17605/OSF.IO/ZBPWA>, published under the [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/) license.

## Funding information

Funded by the European Union (ERC, MindTheGap, StG project no 101041077). Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Research Council. Neither the European Union nor the granting authority can be held responsible for them.
![European Union and European Research Council logos](https://erc.europa.eu/sites/default/files/2023-06/LOGO_ERC-FLAG_FP.png)
Funded by the European Union (ERC, MindTheGap, StG project no 101041077). Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Research Council. Neither the European Union nor the granting authority can be held responsible for them. ![European Union and European Research Council logos](https://erc.europa.eu/sites/default/files/2023-06/LOGO_ERC-FLAG_FP.png)
2 changes: 1 addition & 1 deletion man/StratPal-package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit bbf1130

Please sign in to comment.