Title: | Lotka-Volterra Models for Gause's 'Struggle for Existence' |
---|---|
Description: | A collection of tools and data for analyzing the Gause microcosm experiments, and for fitting Lotka-Volterra models to time series data. Includes methods for fitting single-species logistic growth, and multi-species interaction models, e.g. of competition, predator/prey relationships, or mutualism. See documentation for individual functions for examples. In general, see the lv_optim() function for examples of how to fit parameter values in multi-species systems. Note that the general methods applied here, as well as the form of the differential equations that we use, are described in detail in the Quantitative Ecology textbook by Lehman et al., available at <http://hdl.handle.net/11299/204551>, and in Lina K. Mühlbauer, Maximilienne Schulze, W. Stanley Harpole, and Adam T. Clark. 'gauseR': Simple methods for fitting Lotka-Volterra models describing Gause's 'Struggle for Existence' in the journal Ecology and Evolution. |
Authors: | Adam Clark [aut, cre]
|
Maintainer: | Adam Clark <[email protected]> |
License: | GPL-3 |
Version: | 1.2 |
Built: | 2025-02-13 05:13:19 UTC |
Source: | https://github.com/adamtclark/gauser |
A dataset containing the abundance of Tribolium confusum, grown in monoculture with different quantities of food (flour). Gause's goal was to determine the influence of ecological factors on population growth.
gause_1931_AmN_f01
gause_1931_AmN_f01
A data frame with 18 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Tribolium confusum
Day of experiment
Number of Individuals
Treatments:16 and 64g flour per starting beetle pair
Gause (1931) The influence of ecological factors on the size of population. The American Naturalist 65:696, 70-76
A dataset containing the population size of Tribolium confusum at the upper asymptote, as a characteristic for the population beeing in equilibrium, under different quantities of food (flour). Gause's goal was to determine the influence of ecological factors on population growth.
gause_1931_AmN_f02
gause_1931_AmN_f02
A data frame with 4 rows and 5 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Tribolium confusum
Number of Individuals at population equlibrium
Treatments:16, 32, 64 and 128g flour per starting beetle pair
Gause (1931) The influence of ecological factors on the size of population. The American Naturalist 65:696, 70-76
A dataset containing the population size of Moina macrocopa at the upper asymptote, as a characteristic for the population beeing in equilibrium, under different temperatures. Gause's goal was to determine the influence of ecological factors on population growth.
gause_1931_AmN_f03
gause_1931_AmN_f03
A data frame with 3 rows and 5 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Tribolium confusum
Number of Individuals at population equlibrium
Treatments:20, 25 and 35 degrees Celcius
Gause (1931) The influence of ecological factors on the size of population. The American Naturalist 65:696, 70-76
A dataset containing the abundance of Saccharomyces cerevisiae, grown in different temperatures (5.7 to 41 degrees C). The Volume is measured in "Amount of yeast", which refers to a standardized index, based on the alcohol production per Unit of Yeast.
gause_1932_QR_t05
gause_1932_QR_t05
A data frame with 102 rows and 7 variables:
Paper from which data are drawn
Table number in paper
Number of series: 1,2 or 3
Name of Species: Saccharomyces cerevisiae
Hour of experiment
"Amount of Yeast" of Species
Treatments: Temperatures (5.7 to 41 degrees C)
Gause (1932) Ecology of Populations. The Quarterly Review of Biology 7, vol. 1, pp. 27-46
A dataset containing the abundances (number of cells) and volumes of Saccharomyces cerevisiae and Schizosaccharomyces kephir grown in monoculture and in mixture. The data for two experiments with differnet time periods is reported.
gause_1934_book_app_t01
gause_1934_book_app_t01
A data frame with 60 rows and 10 variables:
Paper from which data are drawn
Table number in paper
Number of experiment: 1 or 2
Name of Species: Saccharomyces cerevisiae and Schizosaccharomyces kephir
Day of experiment
Volume of yeast species in the mixture, estimated from counted cells
Number of Squares counted
Average Number of cells per Square
Total volume of yeast
Treatments: Monoculture and Mixture
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the alcohol production of Saccharomyces cerevisiae and Schizosaccharomyces kephir cultivated under anaerobic and aerobic conditions, in percent and per unit of yeast volume.
gause_1934_book_app_t02
gause_1934_book_app_t02
A data frame with 28 rows and 7 variables:
Paper from which data are drawn
Table number in paper
Name of Species: Saccharomyces cerevisiae, Schizosaccharomyces kephir
Hour of experiment
Alcohol production in percent
Alcohol production per unit of yeast volume
Treatments: Anaerobic and Aerobic
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the mean abundances of Paramecium caudatum and Paramecium aurelia, grown in mixture and monoculture. This dataset contains the mean abundances of three experiments. Note, that for day 20, single values are missing and only the mean is reported.
gause_1934_book_app_t03
gause_1934_book_app_t03
A data frame with 104 rows and 6 variables:
Paper from which data are drawn
Table number in paper
Name of Species: Paramecium caudatum and Paramecium aurelia
Day of experiment
Number of Individuals
Treatments: Monoculture and Mixture
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundance of Paramecium caudatum and Paramecium aurelia, grown in monoculture and in mixture on buffered medium with high wild bacteria concentration ("one loop" medium) and low wild bacteria concentration ("half loop" medium). The number of individuals is reported for monoculture and the number of individuals of the species in the mixture.
gause_1934_book_app_t04
gause_1934_book_app_t04
A data frame with 68 rows and 7 variables:
Paper from which data are drawn
Table number in paper
Name of Species: Paramecium caudatum and Paramecium aurelia
Day of experiment
Number of Individuals
Number of Individuals per Species in Mixture
Treatments: One Loop and Half Loop
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundances of Stylonychia pustulata grown in monoculture and mixture with P. aurelia and P. caudatum and the abundances of P. aurelia and P. caudautum in this mixtures on the medium of Osterhout. This dataset contains the raw data of three different experiments: Stylonychia pustulata grown in monoculture, in mixture with P.aurelia and in mixture wit P.caudatum. The abundances of three to five cultures per experiment and the calculated mean abundances of the experiments are reported. Note, that for day 20 - 25, single values are missing and only the mean is reported.
gause_1934_book_app_t05
gause_1934_book_app_t05
A data frame with 575 rows and 8 variables:
Paper from which data are drawn
Table number in paper
Day of experiment
Number of experiment: 1,2 or 3
Number of culture: 1,2,3,4,5 or Mean
Name of Species: Stylonychia pustulata, Paramecium caudatum and Paramecium aurelia
Number of Individuals
Treatments: Monoculture and Mixture P.aurelia and Mixture P.caudatum
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the growth in abundance of Paramecium caudatum over six days.
gause_1934_book_f04
gause_1934_book_f04
A data frame with 8 rows and 5 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Paramecium caudatum
Day of experiment
Number of Individuals
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the growth in volume of Saccharomyces cerevisiae under anaerobic conditions. The Volume is measured in "Amount of yeast", which refers to a standardized index, based on the alcohol production per Unit of Yeast.
gause_1934_book_f09
gause_1934_book_f09
A data frame with 9 rows and 5 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Saccharomyces cerevisiae
Hour of experiment
"Amount of Yeast" of Species
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundance of Saccharomyces cerevisiae cultivated in monoculture with a medium change in different time periods under anaerobic conditions. The Number of Individuals is measured in Number of cells per 1/250 mm3.
gause_1934_book_f10
gause_1934_book_f10
A data frame with 29 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Saccharomyces cerevisiae
Hour of experiment
Number of cells per 1/250 mm3
Treatments: medium change every 3, 12, 24 hours and control
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing yeast volume and alcohol concentration for two replicates of S. cerevisiae grown in monoculture.
gause_1934_book_f11
gause_1934_book_f11
A data frame with 11 rows and 7 variables:
Paper from which data are drawn
Figure number in paper
Species name
Experiment time in hours
Alcohol concentration, in percent
Yeast volume, listed in papers as 'amount'
Experiment replicate, under two 'somewhat different' growth medium concentrations
Huffaker (1958) Experimental Studies on Predation: Dispersion Factors and Predator-Prey Oscillations. Hilgardia 27: 343-83.
A dataset containing the growth in volume of Saccharomyces cerevisiae cultivated under anaerobic conditions with added alcohol.Gause measured the effect of alcohol on reaching a saturated population. The saturation is measured in percent of the satured population grown without additional alcohol.
gause_1934_book_f12
gause_1934_book_f12
A data frame with 6 rows and 5 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Saccharomyces cerevisiae
Additional alcohol in percent
Percentage of saturated population reached
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the the growth in volume of Saccharomyces cerevisiae and Schizosaccaromyces kephir cultivated in the mixed population (two series of experiments) under anaerobic conditions. Gause also measured the volume of the mixed population. The Volume is measured in "Amount of yeast", which refers to a standardized index, based on the alcohol production per Unit of Yeast.
gause_1934_book_f13
gause_1934_book_f13
A data frame with 47 rows and 5 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Saccharomyces cerevisiae, Schizosaccaromyces kephi and Mixed Population
Hour of experiment
"Amount of Yeast" of Species
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the the growth in volume of Saccharomyces cerevisiae cultivated separately and in the mixed population (two series of experiments) with Schizosaccaromyces kephir under anaerobic conditions. The Volume is measured in "Amount of yeast", which refers to a standardized index, based on the alcohol production per Unit of Yeast.
gause_1934_book_f14
gause_1934_book_f14
A data frame with 32 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Saccharomyces cerevisiae
Hour of experiment
"Amount of Yeast" of Species
Treatments: Monoculture and Mixture
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the the growth in volume of Schizosaccaromyces kephir cultivated separately and in the mixed population (two series of experiments) with Saccharomyces cerevisiae under anaerobic conditions. The Volume is measured in "Amount of yeast", which refers to a standardized index, based on the alcohol production per Unit of Yeast.
gause_1934_book_f15
gause_1934_book_f15
A data frame with 24 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Schizosaccaromyces kephir
Hour of experiment
"Amount of Yeast" of Species
Treatments: Monoculture and Mixture
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the the growth in volume of Schizosaccaromyces kephir cultivated separately and in the mixed population with Saccharomyces cerevisiae under aerobic conditions. The Volume is measured in "Amount of yeast", which refers to a standardized index, based on the alcohol production per Unit of Yeast.
gause_1934_book_f16
gause_1934_book_f16
A data frame with 27 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Schizosaccaromyces kephir, Saccharomyces cerevisiae and Total_Yeast
Hour of experiment
"Amount of Yeast" of Species
Treatments: Monoculture and Mixture
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundance of Paramecium caudatum and Stylonychia mytilis, grown in monoculture and in mixture on buffered medium without wild bacteria.
gause_1934_book_f18
gause_1934_book_f18
A data frame with 28 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Paramecium caudatum and Stylonychia mytilis
Day of experiment
Number of Individuals
Treatments: Monoculture and Mixture
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundance of Paramecium caudatum and Stylonychia mytilis, grown in monoculture and in mixture on buffered medium containing wild bacteria.
gause_1934_book_f19
gause_1934_book_f19
A data frame with 17 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Paramecium caudatum and Stylonychia mytilis
Day of experiment
Number of Individuals
Treatments: Monoculture and Mixture
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundances and the volume of Paramecium caudatum and Paramecium aurelia, to determine the differences in reaching the saturating population regarding Volume and Number of individuals. "Volume" refers to a standardized index, meant to make the abundances of species comparable based on their relative sizes.
gause_1934_book_f21
gause_1934_book_f21
A data frame with 87 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Paramecium caudatum and Paramecium aurelia
Day of experiment
"Volume" of Species
Number of Individuals
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundances of two Paramecium species grown in monoculture and mixture. Note, is for the same experiment as gause_1934_science_f02_03, except that data were digitized separately, and therefore have small variations. These might be useful for estimating observation error in the data digitization process. "Volume" refers to a standardized index, meant to make the abundances of species comparable based on their relative sizes.
gause_1934_book_f22
gause_1934_book_f22
A data frame with 72 rows and 4 variables:
Paper from which data are drawn
Figure number in paper
Day of experiment
Name of Species 1
Volume of Paramecium caudatum
Name of Species 2
Volume of Paramecium aurelia
Treatments: Pa and Pc moncultures, or mixture
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the volume of Paramecium caudatum and Paramecium aurelia, grown in monoculture on buffered medium with two different wild bacteria concentrations ("one" and "half loop"). "Volume" refers to a standardized index, meant to make the abundances of species comparable based on their relative sizes.
gause_1934_book_f23
gause_1934_book_f23
A data frame with 61 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Paramecium caudatum and Paramecium aurelia
Day of experiment
"Volume" of Species
Treatments: One Loop and Half Loop
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the volume of Paramecium caudatum and Paramecium aurelia, grown in monoculture and in mixture on buffered medium with low wild bacteria concentration ("half loop" medium). "Volume" refers to a standardized index, meant to make the abundances of species comparable based on their relative sizes.
gause_1934_book_f24
gause_1934_book_f24
A data frame with 56 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Paramecium caudatum and Paramecium aurelia
Day of experiment
"Volume" of Species
Treatments: Monoculture and Mixture
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the volume of Paramecium caudatum and Paramecium aurelia, grown in monoculture and in mixture on buffered medium with high wild bacteria concentration ("one loop" medium). "Volume" refers to a standardized index, meant to make the abundances of species comparable based on their relative sizes.
gause_1934_book_f25
gause_1934_book_f25
A data frame with 57 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Paramecium caudatum and Paramecium aurelia
Day of experiment
"Volume" of Species
Treatments: Monoculture and Mixture
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundances of Stylorzychia pustulata cultivated separately, and in the mixed populations with Paramecium caudatum and Paramecium aurelia and the abundances of P. caudatum and P. aurelia grown in mixture with S. pustulata.
gause_1934_book_f26
gause_1934_book_f26
A data frame with 104 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species:Paramecium caudatum, Paramecium aurelia and Stylorzychia pustulata
Day of experiment
Number of Individuals
Treatments: Monoculture and Mixture(with Species)
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundances of Paramecium caudatum and Didinium nasutum grown in mixture. Didinium was introduced at day two. "Individuals" refers to the number of individuals pro 0.5 c.c..
gause_1934_book_f28
gause_1934_book_f28
A data frame with 12 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Paramecium caudatum and Didinium nasutum
Day of experiment
Number of Individuals
Treatments: Monoculture and Mixture
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundances of Paramecium caudatum and Didinium nasutum grown in mixture. Didinium was introduced at different days. "Volume" refers to a standardized index, meant to make the abundances of species comparable based on their relative sizes.
gause_1934_book_f29
gause_1934_book_f29
A data frame with 62 rows and 7 variables:
Paper from which data are drawn
Figure number in paper
Name of Species: Didinium nasutum and Paramecium caudatum
Day of experiment
Volume of Didinium
Number of Individuals
Treatments: D. nasutum introduced after 0, 24, 36 and 48 hrs
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundances of Didinium nasutum and Paramecium caudatum grown in mixture on the medium of Osterhout.
gause_1934_book_f30
gause_1934_book_f30
A data frame with 16 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Day of experiment
Name of Species: Didinium nasutum and Paramecium caudatum
Number of Individuals
Treatment: Osterhout medium
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundances of Didinium nasutum and Paramecium caudatum grown in mixture on oat medium with sediment.
gause_1934_book_f31
gause_1934_book_f31
A data frame with 12 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Day of experiment
Name of Species: Didinium nasutum and Paramecium caudatum
Number of Individuals
Treatment: Oat medium
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundances of Paramecium caudatum and Didinium nasutum grown in mixture. Note, is for the same experiment as gause_1934_science_f01, except that data were digitized separately, and therefore have small variations. These might be useful for estimating observation error in the data digitization process.
gause_1934_book_f32
gause_1934_book_f32
A data frame with 17 rows and 8 variables:
Paper from which data are drawn
Figure number in paper
Day of experiment
Name of Prey Species
Number of Prey Individuals
Name of Predator Species
Number of Predator Individuals
Is immigration occurring in this time-step? (yes or no)
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundances of Paramecium bursaria and Schizosaccharomyces pombe grown in mixture.
gause_1934_book_f39.1
gause_1934_book_f39.1
A data frame with 36 rows and 5 variables:
Paper from which data are drawn
Figure number in paper
Day of experiment
Name of Species: Paramecium bursaria and Schizosaccharomyces pombe
Number of Individuals
Gause (1934) The Struggle for Existence. Dover Publications; Reprint edition.
A dataset containing the abundances of Paramecium caudatum and Didinium nasutum grown in mixture. Note, is for the same experiment as gause_1934_book_f32, except that data were digitized separately, and therefore have small variations. These might be useful for estimating observation error in the data digitization process.
gause_1934_science_f01
gause_1934_science_f01
A data frame with 17 rows and 3 variables:
Paper from which data are drawn
Figure number in paper
Day of experiment
Name of Prey Species
Number of Prey Individuals
Name of Predator Species
Number of Predator Individuals
Is immigration occurring in this time-step? (yes or no)
Gause (1934) Experimental Analysis of Vito Volterra's Mathematical Theory of the Struggle for Existence. Science 79:16-17.
A dataset containing the abundances of two Paramecium species grown in monoculture and mixture. Note, is for the same experiment as gause_book_1934_f22, except that data were digitized separately, and therefore have small variations. These might be useful for estimating observation error in the data digitization process. "Volume" refers to a standardized index, meant to make the abundances of species comparable based on their relative sizes.
gause_1934_science_f02_03
gause_1934_science_f02_03
A data frame with 63 rows and 4 variables:
Paper from which data are drawn
Figure number in paper
Day of experiment
Name of Species 1
Volume of Paramecium caudatum
Name of Species 2
Volume of Paramecium aurelia
Treatments: Pa and Pc moncultures, or mixture
Gause (1934) Experimental Analysis of Vito Volterra's Mathematical Theory of the Struggle for Existence. Science 79:16-17.
A dataset containing the abundance of Cheyletus eruditus and Aleuiroglyphus agilis, as apredator-prey system under different food conditions for the prey (wheat and millet). Gause's goal was to determine the influence of ecological factors on predator-prey dynamics. The number of individuals is reported as Individuals per 0.2 g prey food.
gause_1936_AnE_f01
gause_1936_AnE_f01
A data frame with 34 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Day of experiment
Name of Species: Cheyletus eruditus and Aleuiroglyphus agilis
Number of Individuals per 0.2 g
Treatments: Wheat, Millet, Wheat+Millet
Gause (1936) Further Studies of Interaction between Predators and Prey. Journal of Animal Ecology, vol. 5, pp. 1-18.
A dataset containing the abundance of Cheyletus eruditus and Aleuiroglyphus agilis, as apredator-prey system with an occasional immigration of the prey on the 63rd day. The number of individuals is reported as Individuals per 0.2 g prey food. Wheat flour was used as food.
gause_1936_AnE_f03.1
gause_1936_AnE_f03.1
A data frame with 22 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Day of experiment
Name of Species: Cheyletus eruditus and Aleuiroglyphus agilis
Number of Individuals per 0.2 g
Treatments: Immigration or NA
Gause (1936) Further Studies of Interaction between Predators and Prey. Journal of Animal Ecology, vol. 5, pp. 1-18.
A dataset containing the abundance of Cheyletus eruditus and Aleuiroglyphus agilis, as apredator-prey system with an artificial everyday immigration of predator and prey . The number of individuals is reported as Individuals per 0.2 g prey food. Wheat flour was used as food.
gause_1936_AnE_f03.3a
gause_1936_AnE_f03.3a
A data frame with 24 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Day of experiment
Name of Species: Cheyletus eruditus and Aleuiroglyphus agilis
Number of Individuals per 0.2 g
Treatment: Immigration
Gause (1936) Further Studies of Interaction between Predators and Prey. Journal of Animal Ecology, vol. 5, pp. 1-18.
A dataset containing the abundance of Cheyletus eruditus and Aleuiroglyphus agilis, as apredator-prey system with an artificial immigration of predator and prey every 8th day. The number of individuals is reported as Individuals per 0.2 g prey food. Wheat flour was used as food.
gause_1936_AnE_f03.3b
gause_1936_AnE_f03.3b
A data frame with 26 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Day of experiment
Name of Species: Cheyletus eruditus and Aleuiroglyphus agilis
Number of Individuals per 0.2 g
Treatment: Immigration
Gause (1936) Further Studies of Interaction between Predators and Prey. Journal of Animal Ecology, vol. 5, pp. 1-18.
A dataset containing the abundance of Cheyletus eruditus and Aleuiroglyphus agilis, as a predator-prey system on semoletta and wheat flour. A fraction at the beginning of each experiment shows the initial relation between predators and prey; e.g. 10/5 means 10 prey and 5 predators (reported in variable "Treatment"). Dataset includes age structured population abundances. The number of individuals is reported as Individuals per 0.2 g prey food. Wheat flour was used as food.
gause_1936_AnE_t02
gause_1936_AnE_t02
A data frame with 191 rows and 12 variables:
Paper from which data are drawn
Table number in paper
Day of experiment
Name of Species: Cheyletus eruditus and Aleuiroglyphus agilis
Number of all Individuals of Species per 0.2 g
Number of female individuals per 0.2 g
Number of male individuals per 0.2 g
Number of adult Individuals per 0.2 g
Number of hexapod larvae stage Individuals per 0.2 g
Number of octapod larvae stage Individuals per 0.2 g
Initial Number of prey/predator
Treatments: Wheat and Semoletta
Gause (1936) Further Studies of Interaction between Predators and Prey. Journal of Animal Ecology, vol. 5, pp. 1-18.
A dataset containing the abundance of Paramecium bursaria and Saccharomyces exiguus, as a predator-prey system. The primary difference among experimental replicates is the initial abundance of the two species. The number of individuals is reported as Individuals per 0.5 cm3 for Paramecium, and as number of individuals per 0.1 cm3 for Saccharomyces.
gause_1936_AnE_t03
gause_1936_AnE_t03
A data frame with 266 rows and 6 variables:
Paper from which data are drawn
Table number in paper
Experimental replicate number
Day of experiment
Name of Species: Cheyletus eruditus and Aleuiroglyphus agilis
Number of all Individuals of Species per 0.2 g
Gause (1936) Further Studies of Interaction between Predators and Prey. Journal of Animal Ecology, vol. 5, pp. 1-18.
Automatically runs routine for finding starting values and optimal parameter values for a Lotka-Volterra interaction system. Using the default functions, species dynamics follow the form dni/dt = ni * (ri + aii * ni + sum_j(aij * nj)) where ri are the elements of vector r, and aij are the elements of matrix A.
gause_wrapper( time, species, N_starting = NULL, r_starting = NULL, A_starting = NULL, doplot = TRUE, keeptimes = FALSE, parm_signs = NULL, doopt = TRUE, ... )
gause_wrapper( time, species, N_starting = NULL, r_starting = NULL, A_starting = NULL, doplot = TRUE, keeptimes = FALSE, parm_signs = NULL, doopt = TRUE, ... )
time |
Vector of time steps corresponding to observations in species data.frame. |
species |
A data.frame with one column per species to be fitted. Note - column names cannot include white spaces or non-standard special characters. |
N_starting |
Optional starting values for initial abundances. |
r_starting |
Optional starting values for species growth rates. If a value is set to zero, it #forces that parameter to zero in the fitting. Values of NA are ignored. Defaults to NULL (no starting values). |
A_starting |
Optional starting values for species interaction coefficients. If a value is set to zero, it #forces that parameter to zero in the fitting. Values of NA are ignored. Defaults to NULL (no starting values). |
doplot |
Logical. Should the resulting model be plotted? Defaults to TRUE. |
keeptimes |
Should predictions be given for the points in the "time" vector, or for a list of 100 evenly spaced time points? Defaults to FALSE. |
parm_signs |
Optional variable specifying signs for parameters. Defaults to NULL (automatically selected). |
doopt |
Should optimizer be used (if TRUE), or should the initial linearized estimates by applied (if FALSE)? Defaults to TRUE. |
... |
Optional additional arguments to be passed to ode and optim functions. |
A list with simulated time series (out), paramter estimates (parameter_intervals), optimizer output (optout), and raw data used for fitting (rawdata).
#load competition data data("gause_1934_science_f02_03") #subset out data from species grown in mixture mixturedat<-gause_1934_science_f02_03[gause_1934_science_f02_03$Treatment=="Mixture",] #extract time and species data time<-mixturedat$Day species<-data.frame(mixturedat$Volume_Species1, mixturedat$Volume_Species2) colnames(species)<-c("P_caudatum", "P_aurelia") #run wrapper gause_out<-gause_wrapper(time=time, species=species)
#load competition data data("gause_1934_science_f02_03") #subset out data from species grown in mixture mixturedat<-gause_1934_science_f02_03[gause_1934_science_f02_03$Treatment=="Mixture",] #extract time and species data time<-mixturedat$Day species<-data.frame(mixturedat$Volume_Species1, mixturedat$Volume_Species2) colnames(species)<-c("P_caudatum", "P_aurelia") #run wrapper gause_out<-gause_wrapper(time=time, species=species)
Calculates time-lagged observations for variable x, separated by treatment.
get_lag(x, time, tau = 1, treatment = NULL, mindt = 0, maxdt = Inf)
get_lag(x, time, tau = 1, treatment = NULL, mindt = 0, maxdt = Inf)
x |
The time series from which time lagged observations are desired (e.g. population sizes) |
time |
The time steps corresponding to each observation |
tau |
Number of time steps to use between lagged components - defaults to 1 |
treatment |
An optional vector of treatment conditions - time lags will only be computed separately within treatments - defaults to NULL (i.e. no treatments) |
mindt |
Minimum dt allowed between observations - defaults to 0 |
maxdt |
Maximum dt allowed between observations - defaults to Inf |
Returns a data.frame with 7 columns: x (unlagged time series data); laggedx (lagged time series data); xmid (average of time series and lagged time series values); dt (time lag between x and laggedx); time (time for observation x); laggedtime (time for observation laggedx); treatment (treatment for observation)
data(gause_1934_science_f02_03) lagged_data <- get_lag(x=gause_1934_science_f02_03$Volume_Species1, time = gause_1934_science_f02_03$Day, treatment = gause_1934_science_f02_03$Treatment)
data(gause_1934_science_f02_03) lagged_data <- get_lag(x=gause_1934_science_f02_03$Volume_Species1, time = gause_1934_science_f02_03$Day, treatment = gause_1934_science_f02_03$Treatment)
Calculates logistic growth for population based on formula Nt=K*(N0*exp(r*time))/(K+N0*(exp(r*time)-1)
get_logistic(time, N0, r, K)
get_logistic(time, N0, r, K)
time |
The time steps corresponding to each observation |
N0 |
Initial Population Size |
r |
Growth rate |
K |
Carying Capacity |
population size N for each time steps as a vector
# load Gause competition data data(gause_1934_science_f02_03) # extract monoculture data for P.c. Pcmono<-gause_1934_science_f02_03[gause_1934_science_f02_03$Treatment=="Pc",] # calculate lag and per-capita growth lagged_data_Pc <- get_lag(x=Pcmono$Volume_Species1, time = Pcmono$Day) Pcmono$dNNdt_Pc <- percap_growth(x=lagged_data_Pc$x, laggedx=lagged_data_Pc$laggedx, dt=lagged_data_Pc$dt) # fit linear model to get dNNdt ~ r + s*N mod_Pc<-lm(dNNdt_Pc~Volume_Species1, Pcmono) rsn_pars<-coef(mod_Pc) # transform into logistic growth parameters logistic_pars<-c(r=unname(rsn_pars["(Intercept)"]), K=unname(-rsn_pars["(Intercept)"]/rsn_pars["Volume_Species1"])) #fit with nls, using linear model estimates as starting values for parameters nls_mod<-nls(Volume_Species1~get_logistic(time = Day, N0, r, K), data=Pcmono, start=c(N0=unname(Pcmono$Volume_Species1[which.min(Pcmono$Day)]), r=unname(logistic_pars["r"]), K=unname(logistic_pars["K"]))) summary(nls_mod) # plot results plot(Volume_Species1~Day, Pcmono, type="b", ylab="P. caudatum Volume") timesq<-seq(0, 30, length=100) Ntest<-get_logistic(time = timesq, N0=coef(nls_mod)["N0"], r=coef(nls_mod)["r"], K=coef(nls_mod)["K"]) lines(timesq, Ntest, col="red")
# load Gause competition data data(gause_1934_science_f02_03) # extract monoculture data for P.c. Pcmono<-gause_1934_science_f02_03[gause_1934_science_f02_03$Treatment=="Pc",] # calculate lag and per-capita growth lagged_data_Pc <- get_lag(x=Pcmono$Volume_Species1, time = Pcmono$Day) Pcmono$dNNdt_Pc <- percap_growth(x=lagged_data_Pc$x, laggedx=lagged_data_Pc$laggedx, dt=lagged_data_Pc$dt) # fit linear model to get dNNdt ~ r + s*N mod_Pc<-lm(dNNdt_Pc~Volume_Species1, Pcmono) rsn_pars<-coef(mod_Pc) # transform into logistic growth parameters logistic_pars<-c(r=unname(rsn_pars["(Intercept)"]), K=unname(-rsn_pars["(Intercept)"]/rsn_pars["Volume_Species1"])) #fit with nls, using linear model estimates as starting values for parameters nls_mod<-nls(Volume_Species1~get_logistic(time = Day, N0, r, K), data=Pcmono, start=c(N0=unname(Pcmono$Volume_Species1[which.min(Pcmono$Day)]), r=unname(logistic_pars["r"]), K=unname(logistic_pars["K"]))) summary(nls_mod) # plot results plot(Volume_Species1~Day, Pcmono, type="b", ylab="P. caudatum Volume") timesq<-seq(0, 30, length=100) Ntest<-get_logistic(time = timesq, N0=coef(nls_mod)["N0"], r=coef(nls_mod)["r"], K=coef(nls_mod)["K"]) lines(timesq, Ntest, col="red")
A dataset containing the abundances mite species from some of the Huffaker experiments.
huffaker_1963
huffaker_1963
A data frame with 168 rows and 6 variables:
Paper from which data are drawn
Figure number in paper
Species name
Experiment week
Number of individuals
60 vs. 24-week experiments
Huffaker (1958) Experimental Studies on Predation: Dispersion Factors and Predator-Prey Oscillations. Hilgardia 27: 343-83.
Calculates dn/dt for n species in a Lokta-Volterra system, following the form: dni/dt = ni * (ri + aii * ni + sum_j(aij * nj)) Note that aii coefficients can be positive or negative, although positive coefficients risk having the system run to infinite population sizes, which will crash the function.
lv_interaction(time, n, parms)
lv_interaction(time, n, parms)
time |
The time steps corresponding to each observation - exists to interface with ode function, but should be left blank. |
n |
A vector of species abundances |
parms |
A vector of parameters - the first n elements should be the growth rates r1, r2, ... rn for all n species. The remaining terms should be the elements of the interaction matrix A, listed in the order a11, a12, ... a1n, a21, a22, ... a2n, ... an1, an2, ... ann. |
vector of growth rates for each species
# load data from competition experiment data(gause_1934_science_f02_03) # subset data to include just mixtures mixturedata<-gause_1934_science_f02_03[gause_1934_science_f02_03$Treatment=="Mixture",] # get time-lagged observations for each species Pc_lagged<-get_lag(x = mixturedata$Volume_Species1, time = mixturedata$Day) Pa_lagged<-get_lag(x = mixturedata$Volume_Species2, time = mixturedata$Day) # calculate per-capita growth rates Pc_dNNdt<-percap_growth(x = Pc_lagged$x, laggedx = Pc_lagged$laggedx, dt = Pc_lagged$dt) Pa_dNNdt<-percap_growth(x = Pa_lagged$x, laggedx = Pa_lagged$laggedx, dt = Pa_lagged$dt) # fit linear models to dNNdt, based on average # abundances between current and lagged time steps Pc_mod_dat<-data.frame(Pc_dNNdt=Pc_dNNdt, Pc=Pc_lagged$laggedx, Pa=Pa_lagged$laggedx) mod_comp_Pc<-lm(Pc_dNNdt~Pc+Pa, data=Pc_mod_dat) Pa_mod_dat<-data.frame(Pa_dNNdt=Pa_dNNdt, Pa=Pa_lagged$laggedx, Pc=Pc_lagged$laggedx) mod_comp_Pa<-lm(Pa_dNNdt~Pa+Pc, data=Pa_mod_dat) # model summaries summary(mod_comp_Pc) summary(mod_comp_Pa) # extract parameters # note - linear regressions give us dynamics in the form: # dni/nidt ~ (Intercept) + (n1_slope) * n1 + (n2_slope) n2 # and thus: # dni/dt = n1*((Intercept) + (n1_slope) * n1 + (n2_slope) n2) # growth rates r1 <- unname(coef(mod_comp_Pc)["(Intercept)"]) r2 <- unname(coef(mod_comp_Pa)["(Intercept)"]) # self-limitation a11 <- unname(coef(mod_comp_Pc)["Pc"]) a22 <- unname(coef(mod_comp_Pa)["Pa"]) # effect of Pa on Pc a12 <- unname(coef(mod_comp_Pc)["Pa"]) # effect of Pc on Pa a21 <- unname(coef(mod_comp_Pa)["Pc"]) # run ODE: # make paramter vector: parms <- c(r1, r2, a11, a12, a21, a22) initialN <- c(1, 1) out <- deSolve::ode(y=initialN, times=1:25, func=lv_interaction, parms=parms) matplot(out[,1], out[,-1], type="l", xlab="time", ylab="N", col=c("black","red"), lty=c(1,3), lwd=2, ylim=c(0, 150)) legend("topleft", c("Pc", "Pa"), col=c(1,2), lwd=2, lty=c(1,3)) # now, plot in points from data points(mixturedata$Day, mixturedata$Volume_Species1, col=1) points(mixturedata$Day, mixturedata$Volume_Species2, col=2)
# load data from competition experiment data(gause_1934_science_f02_03) # subset data to include just mixtures mixturedata<-gause_1934_science_f02_03[gause_1934_science_f02_03$Treatment=="Mixture",] # get time-lagged observations for each species Pc_lagged<-get_lag(x = mixturedata$Volume_Species1, time = mixturedata$Day) Pa_lagged<-get_lag(x = mixturedata$Volume_Species2, time = mixturedata$Day) # calculate per-capita growth rates Pc_dNNdt<-percap_growth(x = Pc_lagged$x, laggedx = Pc_lagged$laggedx, dt = Pc_lagged$dt) Pa_dNNdt<-percap_growth(x = Pa_lagged$x, laggedx = Pa_lagged$laggedx, dt = Pa_lagged$dt) # fit linear models to dNNdt, based on average # abundances between current and lagged time steps Pc_mod_dat<-data.frame(Pc_dNNdt=Pc_dNNdt, Pc=Pc_lagged$laggedx, Pa=Pa_lagged$laggedx) mod_comp_Pc<-lm(Pc_dNNdt~Pc+Pa, data=Pc_mod_dat) Pa_mod_dat<-data.frame(Pa_dNNdt=Pa_dNNdt, Pa=Pa_lagged$laggedx, Pc=Pc_lagged$laggedx) mod_comp_Pa<-lm(Pa_dNNdt~Pa+Pc, data=Pa_mod_dat) # model summaries summary(mod_comp_Pc) summary(mod_comp_Pa) # extract parameters # note - linear regressions give us dynamics in the form: # dni/nidt ~ (Intercept) + (n1_slope) * n1 + (n2_slope) n2 # and thus: # dni/dt = n1*((Intercept) + (n1_slope) * n1 + (n2_slope) n2) # growth rates r1 <- unname(coef(mod_comp_Pc)["(Intercept)"]) r2 <- unname(coef(mod_comp_Pa)["(Intercept)"]) # self-limitation a11 <- unname(coef(mod_comp_Pc)["Pc"]) a22 <- unname(coef(mod_comp_Pa)["Pa"]) # effect of Pa on Pc a12 <- unname(coef(mod_comp_Pc)["Pa"]) # effect of Pc on Pa a21 <- unname(coef(mod_comp_Pa)["Pc"]) # run ODE: # make paramter vector: parms <- c(r1, r2, a11, a12, a21, a22) initialN <- c(1, 1) out <- deSolve::ode(y=initialN, times=1:25, func=lv_interaction, parms=parms) matplot(out[,1], out[,-1], type="l", xlab="time", ylab="N", col=c("black","red"), lty=c(1,3), lwd=2, ylim=c(0, 150)) legend("topleft", c("Pc", "Pa"), col=c(1,2), lwd=2, lty=c(1,3)) # now, plot in points from data points(mixturedata$Day, mixturedata$Volume_Species1, col=1) points(mixturedata$Day, mixturedata$Volume_Species2, col=2)
Calculates dn/dt for n species in a Lokta-Volterra system, in log space, following the form: dlog(ni)/dt = (ri + aii * ni + sum_j(aij * nj)) This form can be helpful for optimization routines where species abundances are close to zero.
lv_interaction_log(time, n_log, parms)
lv_interaction_log(time, n_log, parms)
time |
The time steps corresponding to each observation - exists to interface with ode function, but should be left blank. |
n_log |
A vector of species abundances, in log space |
parms |
A vector of parameters - the first n elements should be the growth rates r1, r2, ... rn for all n species. The remaining terms should be the elements of the interaction matrix A, listed in the order a11, a12, ... a1n, a21, a22, ... a2n, ... an1, an2, ... ann. |
vector of growth rates for each species in log space
Identifies optimal parameter values for a Lotka-Volterra interaction system.
lv_optim( pars, opt_data, parm_signs, standardize = TRUE, odefun = lv_interaction_log )
lv_optim( pars, opt_data, parm_signs, standardize = TRUE, odefun = lv_interaction_log )
pars |
A vector of parameter values in log space to be optimized. Must include a logged starting abundance for each species, followed by the logged absolute values of the growth rates, followed by the logged absolute value of the elements of the interaction matrix. |
opt_data |
Abundance data for optimization. Must include one column labeled 'time' with time steps, and a column for each species abundance. |
parm_signs |
A vector that provides the desired sign of each parameter (i.e. -1 or 1). If value is zero, then the term is held at zero (but should be left out of the pars vector). |
standardize |
A logical, defaulting to TRUE - should error be calculated based on standardized values of outputs? Allows for more equal weighting of observed variabels. |
odefun |
The function to use to simulate the ODE - defaults to lv_interaction_log |
squared error between model fits for given parameter values, and observations
# load data from competition experiment data(gause_1934_book_f32) # keep all data - no separate treatments exist for this experiment predatorpreydata<-gause_1934_book_f32 # get time-lagged observations for each species prey_lagged<-get_lag(x = predatorpreydata$Individuals_Prey, time = predatorpreydata$Day) predator_lagged<-get_lag(x = predatorpreydata$Individuals_Predator, time = predatorpreydata$Day) # calculate per-capita growth rates prey_dNNdt<-percap_growth(x = prey_lagged$x, laggedx = prey_lagged$laggedx, dt = prey_lagged$dt) predator_dNNdt<-percap_growth(x = predator_lagged$x, laggedx = predator_lagged$laggedx, dt = predator_lagged$dt) # fit linear models to dNNdt, based on average # abundances between current and lagged time steps prey_mod_dat<-data.frame(prey_dNNdt=prey_dNNdt, prey=prey_lagged$laggedx, predator=predator_lagged$laggedx) mod_prey<-lm(prey_dNNdt~prey+predator, data=prey_mod_dat) predator_mod_dat<-data.frame(predator_dNNdt=predator_dNNdt, predator=predator_lagged$laggedx, prey=prey_lagged$laggedx) mod_predator<-lm(predator_dNNdt~predator+prey, data=predator_mod_dat) # model summaries summary(mod_prey) summary(mod_predator) # extract parameters # growth rates r1 <- unname(coef(mod_prey)["(Intercept)"]) r2 <- unname(coef(mod_predator)["(Intercept)"]) # self-limitation a11 <- unname(coef(mod_prey)["prey"]) a22 <- unname(coef(mod_predator)["predator"]) # effect of Pa on Pc a12 <- unname(coef(mod_prey)["predator"]) # effect of Pc on Pa a21 <- unname(coef(mod_predator)["prey"]) # run ODE: # make parameter vector: parms <- c(r1, r2, a11, a12, a21, a22) initialN <- c(4, 0.1) out <- deSolve::ode(y=initialN, times=seq(1, 17, length=100), func=lv_interaction, parms=parms) matplot(out[,1], out[,-1], type="l", xlab="time", ylab="N", col=c("black","red"), lty=c(1,3), lwd=2, ylim=c(0, 60)) legend("topright", c("Pc", "Dn"), col=c(1,2), lwd=2, lty=c(1,3)) # now, plot in points from data points(predatorpreydata$Day, predatorpreydata$Individuals_Predator , col=2) points(predatorpreydata$Day, predatorpreydata$Individuals_Prey, col=1) # uh-oh - This is a bad fit. This suggests that our linear model # approximation isn't very good. Instead, we should try optimizing # directly using the ode solver # Re-run using an optimizer # Data for the optimizer: # Must have a column with time steps labeled 'time', and # columns for each species in the community. opt_data<-data.frame(time=predatorpreydata$Day, Prey=predatorpreydata$Individuals_Prey, Predator=predatorpreydata$Individuals_Predator) # Save the signs of the parameters - # optimizer works in log space, so these # must be specified separately parm_signs<-sign(parms) # parameter vector for optimizer - # must be a vector with, first, the # starting abundances in log space, # and second, the parameter values, # again in log space pars<-c(log(initialN), log(abs(parms))) # run optimizer optout<-optim(par = pars, fn = lv_optim, hessian = TRUE, opt_data=opt_data, parm_signs=parm_signs) # extract parameter vector: parms <- exp(optout$par[-c(1:2)])*parm_signs initialN <- exp(optout$par[1:2]) out <- deSolve::ode(y=initialN, times=seq(1, 17, length=100), func=lv_interaction, parms=parms) matplot(out[,1], out[,-1], type="l", xlab="time", ylab="N", col=c("black","red"), lty=c(1,3), lwd=2, ylim=c(0, 60)) legend("topright", c("Pc", "Dn"), col=c(1,2), lwd=2, lty=c(1,3)) # now, plot in points from data points(predatorpreydata$Day, predatorpreydata$Individuals_Predator , col=2) points(predatorpreydata$Day, predatorpreydata$Individuals_Prey, col=1) # get rough estimate of confidence intervals fisher_info<-solve(-optout$hessian) optout$par_sd<-sqrt(abs(diag(fisher_info))) parm_signs_sp<-c(rep(1, ncol(opt_data)-1), parm_signs) parameter_intervals<-data.frame(lower_sd=exp(optout$par-optout$par_sd)*parm_signs_sp, mu=exp(optout$par)*parm_signs_sp, upper_sd=exp(optout$par+optout$par_sd)*parm_signs_sp) rownames(parameter_intervals)<-c("prey", "predator", "r1", "r2", "a11", "a12", "a21", "a22") parameter_intervals
# load data from competition experiment data(gause_1934_book_f32) # keep all data - no separate treatments exist for this experiment predatorpreydata<-gause_1934_book_f32 # get time-lagged observations for each species prey_lagged<-get_lag(x = predatorpreydata$Individuals_Prey, time = predatorpreydata$Day) predator_lagged<-get_lag(x = predatorpreydata$Individuals_Predator, time = predatorpreydata$Day) # calculate per-capita growth rates prey_dNNdt<-percap_growth(x = prey_lagged$x, laggedx = prey_lagged$laggedx, dt = prey_lagged$dt) predator_dNNdt<-percap_growth(x = predator_lagged$x, laggedx = predator_lagged$laggedx, dt = predator_lagged$dt) # fit linear models to dNNdt, based on average # abundances between current and lagged time steps prey_mod_dat<-data.frame(prey_dNNdt=prey_dNNdt, prey=prey_lagged$laggedx, predator=predator_lagged$laggedx) mod_prey<-lm(prey_dNNdt~prey+predator, data=prey_mod_dat) predator_mod_dat<-data.frame(predator_dNNdt=predator_dNNdt, predator=predator_lagged$laggedx, prey=prey_lagged$laggedx) mod_predator<-lm(predator_dNNdt~predator+prey, data=predator_mod_dat) # model summaries summary(mod_prey) summary(mod_predator) # extract parameters # growth rates r1 <- unname(coef(mod_prey)["(Intercept)"]) r2 <- unname(coef(mod_predator)["(Intercept)"]) # self-limitation a11 <- unname(coef(mod_prey)["prey"]) a22 <- unname(coef(mod_predator)["predator"]) # effect of Pa on Pc a12 <- unname(coef(mod_prey)["predator"]) # effect of Pc on Pa a21 <- unname(coef(mod_predator)["prey"]) # run ODE: # make parameter vector: parms <- c(r1, r2, a11, a12, a21, a22) initialN <- c(4, 0.1) out <- deSolve::ode(y=initialN, times=seq(1, 17, length=100), func=lv_interaction, parms=parms) matplot(out[,1], out[,-1], type="l", xlab="time", ylab="N", col=c("black","red"), lty=c(1,3), lwd=2, ylim=c(0, 60)) legend("topright", c("Pc", "Dn"), col=c(1,2), lwd=2, lty=c(1,3)) # now, plot in points from data points(predatorpreydata$Day, predatorpreydata$Individuals_Predator , col=2) points(predatorpreydata$Day, predatorpreydata$Individuals_Prey, col=1) # uh-oh - This is a bad fit. This suggests that our linear model # approximation isn't very good. Instead, we should try optimizing # directly using the ode solver # Re-run using an optimizer # Data for the optimizer: # Must have a column with time steps labeled 'time', and # columns for each species in the community. opt_data<-data.frame(time=predatorpreydata$Day, Prey=predatorpreydata$Individuals_Prey, Predator=predatorpreydata$Individuals_Predator) # Save the signs of the parameters - # optimizer works in log space, so these # must be specified separately parm_signs<-sign(parms) # parameter vector for optimizer - # must be a vector with, first, the # starting abundances in log space, # and second, the parameter values, # again in log space pars<-c(log(initialN), log(abs(parms))) # run optimizer optout<-optim(par = pars, fn = lv_optim, hessian = TRUE, opt_data=opt_data, parm_signs=parm_signs) # extract parameter vector: parms <- exp(optout$par[-c(1:2)])*parm_signs initialN <- exp(optout$par[1:2]) out <- deSolve::ode(y=initialN, times=seq(1, 17, length=100), func=lv_interaction, parms=parms) matplot(out[,1], out[,-1], type="l", xlab="time", ylab="N", col=c("black","red"), lty=c(1,3), lwd=2, ylim=c(0, 60)) legend("topright", c("Pc", "Dn"), col=c(1,2), lwd=2, lty=c(1,3)) # now, plot in points from data points(predatorpreydata$Day, predatorpreydata$Individuals_Predator , col=2) points(predatorpreydata$Day, predatorpreydata$Individuals_Prey, col=1) # get rough estimate of confidence intervals fisher_info<-solve(-optout$hessian) optout$par_sd<-sqrt(abs(diag(fisher_info))) parm_signs_sp<-c(rep(1, ncol(opt_data)-1), parm_signs) parameter_intervals<-data.frame(lower_sd=exp(optout$par-optout$par_sd)*parm_signs_sp, mu=exp(optout$par)*parm_signs_sp, upper_sd=exp(optout$par+optout$par_sd)*parm_signs_sp) rownames(parameter_intervals)<-c("prey", "predator", "r1", "r2", "a11", "a12", "a21", "a22") parameter_intervals
A dataset containing the abundances of wolves, moose, and fir trees from the Isle Royale study of McLaren et al.
mclaren_1994_f03
mclaren_1994_f03
A data frame with 140 rows and 7 variables:
Paper from which data are drawn
Figure number in paper
Year of measurements
Species name
Width of tree rings
Number of wolf or moose individuals
AET water availablility index
McLaren & Peterson (1994) Wolves, Moose, and Tree Rings on Isle Royale. Science 266:1555-1558.
Takes in paramter values in the form returned by the gause_wrapper function, and calculates expected abundances for all n species, returned as a single vector. This function is potentially useful in combination with other optimizer software, e.g. as might be used for hypothesis testing.
ode_prediction(pars_full, time, N)
ode_prediction(pars_full, time, N)
pars_full |
Initial Population Size |
time |
A vector of times. Must be repeated once per species. |
N |
Number of species. Can be either a number, or a vector the same length as time. |
a stacked vector with predicted abundances for all species
#load competition data data("gause_1934_science_f02_03") #subset out data from species grown in mixture mixturedat<-gause_1934_science_f02_03[gause_1934_science_f02_03$Treatment=="Mixture",] #extract time and species data time<-mixturedat$Day species<-data.frame(mixturedat$Volume_Species1, mixturedat$Volume_Species2) colnames(species)<-c("P_caudatum", "P_aurelia") #run wrapper gause_out<-gause_wrapper(time=time, species=species) # number of species N<-ncol(gause_out$rawdata)-1 # parameters pars_full<-c(gause_out$parameter_intervals$mu) # data.frame for optimization fittigdata<-data.frame(y=unlist(gause_out$rawdata[,-1]), time=gause_out$rawdata$time, N=N) yest<-ode_prediction(pars_full, time=fittigdata$time, N=fittigdata$N) plot(fittigdata$y, yest, xlab="observation", ylab="prediction") abline(a=0, b=1, lty=2) #example of how to apply function, using nls() mod<-nls(y~ode_prediction(pars_full, time, N), start = list(pars_full=pars_full), data=fittigdata) summary(mod)
#load competition data data("gause_1934_science_f02_03") #subset out data from species grown in mixture mixturedat<-gause_1934_science_f02_03[gause_1934_science_f02_03$Treatment=="Mixture",] #extract time and species data time<-mixturedat$Day species<-data.frame(mixturedat$Volume_Species1, mixturedat$Volume_Species2) colnames(species)<-c("P_caudatum", "P_aurelia") #run wrapper gause_out<-gause_wrapper(time=time, species=species) # number of species N<-ncol(gause_out$rawdata)-1 # parameters pars_full<-c(gause_out$parameter_intervals$mu) # data.frame for optimization fittigdata<-data.frame(y=unlist(gause_out$rawdata[,-1]), time=gause_out$rawdata$time, N=N) yest<-ode_prediction(pars_full, time=fittigdata$time, N=fittigdata$N) plot(fittigdata$y, yest, xlab="observation", ylab="prediction") abline(a=0, b=1, lty=2) #example of how to apply function, using nls() mod<-nls(y~ode_prediction(pars_full, time, N), start = list(pars_full=pars_full), data=fittigdata) summary(mod)
Calculates per-capita growth rate, using log ratios following the formula dN/Ndt = log(N(t)/N0)/dt.
percap_growth(x, laggedx, dt)
percap_growth(x, laggedx, dt)
x |
Abundance |
laggedx |
Lagged abundance |
dt |
Time lag between observations |
Per-capita growth rate
data(gause_1934_science_f02_03) lagged_data <- get_lag(x=gause_1934_science_f02_03$Volume_Species1, time = gause_1934_science_f02_03$Day, treatment = gause_1934_science_f02_03$Treatment) dNNdt <- percap_growth(x=lagged_data$x, laggedx=lagged_data$laggedx, dt=lagged_data$dt)
data(gause_1934_science_f02_03) lagged_data <- get_lag(x=gause_1934_science_f02_03$Volume_Species1, time = gause_1934_science_f02_03$Day, treatment = gause_1934_science_f02_03$Treatment) dNNdt <- percap_growth(x=lagged_data$x, laggedx=lagged_data$laggedx, dt=lagged_data$dt)
Tests goodness of fit for predictions vs. observations. This statistic can be though of in the same way as a classic "R2", except that it measures scatter around the 1-1 line, rather than around a fitted regresson line of observed vs. predicted values. Value close to 1 indicate a that predictions match observations closely. Values at or below zero indicate that predictions do not match observations any better than the grand mean taken across all observations.
test_goodness_of_fit(observed, predicted, bycolumn = FALSE, droptimecol = TRUE)
test_goodness_of_fit(observed, predicted, bycolumn = FALSE, droptimecol = TRUE)
observed |
A vector or matrix of observed values. |
predicted |
A vector or matrix of predicted values. |
bycolumn |
If TRUE, then separate values are calculated for each column in observed and predicted. |
droptimecol |
If TRUE, will automatically remove the column labeled "time" in the predicted variable. This is useful for dealing with the default output of the gause_wrapper function. Defaults to FALSE. |
#load competition data data("gause_1934_science_f02_03") #subset out data from species grown in mixture mixturedat<-gause_1934_science_f02_03[gause_1934_science_f02_03$Treatment=="Mixture",] #extract time and species data time<-mixturedat$Day species<-data.frame(mixturedat$Volume_Species1, mixturedat$Volume_Species2) colnames(species)<-c("P_caudatum", "P_aurelia") #run wrapper #note - keeptimes=TRUE is needed, so that predicted time steps match #observed time steps gause_out<-gause_wrapper(time=time, species=species, keeptimes = TRUE) #calculate goodness of fit test_goodness_of_fit(observed=species, predicted=gause_out) # > 0.9 for both time series - these are good fits!
#load competition data data("gause_1934_science_f02_03") #subset out data from species grown in mixture mixturedat<-gause_1934_science_f02_03[gause_1934_science_f02_03$Treatment=="Mixture",] #extract time and species data time<-mixturedat$Day species<-data.frame(mixturedat$Volume_Species1, mixturedat$Volume_Species2) colnames(species)<-c("P_caudatum", "P_aurelia") #run wrapper #note - keeptimes=TRUE is needed, so that predicted time steps match #observed time steps gause_out<-gause_wrapper(time=time, species=species, keeptimes = TRUE) #calculate goodness of fit test_goodness_of_fit(observed=species, predicted=gause_out) # > 0.9 for both time series - these are good fits!