中文 | Español | English | português | Turkish
knitr::opts_chunk$set(echo = TRUE) library(tidyr) library(ggplot2) library(deSolve) library(ecoevoapps) library(patchwork) library(latex2exp) theme_set(ecoevoapps::theme_apps())
$N_{t+1} = \lambda N_t$
sidebarLayout( sidebarPanel( # User defined lambda ------- sliderInput("lambda", label = "Population growth rate (lambda):", min = 0.01, max = 2, value = 1.2, step = .01), # User defined N0 ------- numericInput("N0", label = "Initial population size (N0)", min = 1, max = 100, value = 1), # User defined time --------- numericInput("time", label = "Number of time steps to project", min = 1, max = 1000, value = 30) ), # Panel of plots ----- mainPanel( renderPlot({plots_to_print()}, width = 450, height = 450) ) ) # Generate trajectories for sp 1 -------- exponential_pop_df <- reactive({ run_discrete_exponential_model(N0 = input$N0, lambda = input$lambda, time = input$time) }) # Make plot ----------- trajaectory_plot <- reactive({ plot_discrete_population_growth(exponential_pop_df()) + ylab(latex2exp::TeX("Population size at time $t$ ($N_t$)")) + labs(caption = latex2exp::TeX(paste0("Parameter values: $\\lambda = $", input$lambda)), title = "Population growth with the discrete exponential model") }) # Make a list of plots ---- plots_to_print <- reactive({trajaectory_plot()})
Next, we can explore models of population growth where the growth rate of a population depends on the current population size. There are several different canonical models that track the dynamics of populations whose growth rates decrease as population size increases.
One way to model logistic growth in a population with discrete growth is with the logistic map, which is a discrete time analog of the continuous logistic equation:
$$N_{t+1} = r_dN_t\left(1-\frac{N_t}{K}\right)$$
This formulation was notably studied by Robert May in the classic 1976 paper "Simple mathematical models with very complicated dynamics", in which he showed the potential for this model to generate chaotic dynamics.
sidebarLayout( sidebarPanel( # User defined lambda ------- sliderInput("rd_dl", label = "Population growth rate (rd):", min = 0.01, max = 4.5, value = 1.05, step = .01), # User defined N0 ------- numericInput("N0_dl", label = "Initial population size (N0)", min = 1, max = 100, value = 1), # User defined carrying capacity (K) ---------- numericInput("K_dl", label = "Carrying capacity (K)", min = 1, max = 1000, value = 100), # User defined time --------- numericInput("time_dl", label = "Number of time steps to project", min = 1, max = 1000, value = 30) ), # Panel of plots ----- mainPanel( renderPlot({plots_to_print_dl()}, width = 450, height = 800) ) ) # Get user defined parameters for discrete logistic ------ params_dl <- reactive({c(rd = input$rd_dl, K = input$K_dl)}) dl_df <- reactive({ run_discrete_logistic_model(N0 = input$N0_dl, params = params_dl(), time = input$time_dl) }) # Generate trajectories for discrete logistic -------- trajaectory_plot_dl <- reactive({ plot_discrete_population_growth(dl_df()) + labs(title = "Population growth with the discrete logistic model") }) # cobweb for standard discrete logistic model ----- cobweb_dl <- reactive({ plot_discrete_population_cobweb(dl_df(), params_vec = params_dl(), model_type = "discrete_logistic") }) # Make plot caption ---- plot_caption_dl <- reactive({ latex2exp::TeX(paste0("Parameter values: $r_d = $", input$rd_dl, "; K = ", input$K_dl)) }) # Make a list of plots ---- plots_to_print_dl <- reactive({{trajaectory_plot_dl()/cobweb_dl()} + labs(caption = plot_caption_dl())})
Another way to model a population with discrete growth with a carrying capacity is with the Ricker model, originally described in a 1954 paper about stock and recruitment in fisheries.
$$N_{t+1} = N_t e^{(r (1 - N_t/K))}$$
sidebarLayout( sidebarPanel( # User defined lambda ------- sliderInput("r_ricker", label = "Population growth rate (r):", min = 0.01, max = 3, value = 1.01, step = .01), # User defined N0 ------- numericInput("N0_ricker", label = "Initial population size (N0)", min = 1, max = 100, value = 1), # User defined carrying capacity (K) ---------- numericInput("K_ricker", label = "Carrying capacity (K)", min = 1, max = 1000, value = 100), # User defined time --------- numericInput("time_ricker", label = "Number of time steps to project", min = 1, max = 1000, value = 30, step = 5) ), # Panel of plots ----- mainPanel( renderPlot({plots_to_print_ricker()}, width = 450, height = 800) ) ) params_ricker <- reactive({c(rd = input$r_ricker, K = input$K_ricker)}) ricker_df <- reactive({ run_ricker_model(N0 = input$N0_ricker, params = params_ricker(), time = input$time_ricker) }) # Generate trajectories for discrete logistic -------- trajaectory_plot_ricker <- reactive({ plot_discrete_population_growth(ricker_df()) + labs(title = "Population growth with the Ricker model") }) # cobweb plot for ricker model ----- cobweb_ricker <- reactive({ plot_discrete_population_cobweb(ricker_df(), params_vec = params_ricker(), model_type = "ricker") }) # Make plot caption ---- plot_caption_ricker <- reactive({ latex2exp::TeX(paste0("Parameter values: $r = $", input$r_ricker, "; K = ", input$K_ricker)) }) # Make a list of plots ---- plots_to_print_ricker <- reactive({{ trajaectory_plot_ricker()/cobweb_ricker()} + labs(caption = plot_caption_ricker())})
A third classic model for population growth in discrete time is the Beverton-Holt model, which was also developed in the context of fisheries management:
$$N_{t+1} = \frac{RN_t}{1+\left(\frac{R-1}{K}\right)N_t}$$
sidebarLayout( sidebarPanel( # User defined lambda ------- sliderInput("r_bh", label = "Population growth rate (R):", min = 0.01, max = 3, value = 1.25, step = .01), # User defined N0 ------- numericInput("N0_bh", label = "Initial population size (N0)", min = 1, max = 100, value = 1), # User defined carrying capacity (K) ---------- numericInput("K_bh", label = "Carrying capacity (K)", min = 1, max = 1000, value = 100), # User defined time --------- numericInput("time_bh", label = "Number of time steps to project", min = 1, max = 1000, value = 30, step = 5) ), # Panel of plots ----- mainPanel( renderPlot({plots_to_print_bh()}, width = 450, height = 800) ) ) # Get user defined parameters for discrete logistic ------ params_bh <- reactive({c(rd = input$r_bh, K = input$K_bh)}) bh_df <- reactive({ run_beverton_holt_model(N0 = input$N0_bh, params = params_bh(), time = input$time_bh) }) # Generate trajectories for beverton-holt model -------- trajaectory_plot_bh <- reactive({ plot_discrete_population_growth(bh_df()) + labs(title = "Population growth with the Beverton-Holt model") }) # Generate cobweb for beverton-holt model -------- cobweb_bh <- reactive({ plot_discrete_population_cobweb(bh_df(), params_vec = c(rd = input$r_bh, K = input$K_bh), model_type = "beverton_holt") }) # Make plot caption ---- plot_caption_bh <- reactive({ latex2exp::TeX(paste0("Parameter values: $r = $", input$r_bh, "; K = ", input$K_bh)) }) # Make a list of plots ---- plots_to_print_bh <- reactive({{trajaectory_plot_bh()/cobweb_bh()} + labs(caption = plot_caption_bh())})
"Simple mathematical models with very complicated dynamics", Robert May, 1976.
"Stock and Recruitment", Bill Ricker, 1954.
Course notes on the Ricker model from UGA course on population ecology
Dr. Sebastian Bonhoeffer's lecture notes on Ecology and Evolution (see Ch. 1)
Dr. Jan Engelstädter's e-book on analysis of biological data.
suppressWarnings(ecoevoapps::print_app_footer())
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.