中文 | Español | English | português | Turkish
source("single_populations_app_setup.R")
Aqui vamos considerar a dinâmica populacional de uma única espécie. Para tornar as coisas um pouco mais simples, vamos por ora considerar essa uma população "fechada", isto é, uma população que não está sujeita a imigração ou emigração. Essa população, portanto, apenas pode crescer com o aumento da natalidade e/ou redução da mortalidade. Uma população com acesso ilimitado a recursos crescerá exponencialmente e suas taxas de natalidade e mortalidade permanecerão constantes ao longo do tempo ($T$), independentemente do tamanho populacional ($N$). Se $b$ e $d$ forem, respectivamente, as taxas de natalidade e mortalidade per capita, então a taxa de crescimento populacional pode ser descrita como:
$$\frac{dN}{dT} = bN - dN = (b-d)N$$
Dado que $(b-d)$ é uma constante ($r$), chamada de taxa de crescimento intrínseco, podemos reescrever a equação acima da seguinte forma:
$$\frac{dN}{dT} = rN$$
A trajetória de uma população em crescimento exponencial tem um formato de "J" num gráfico de tamanho populacional ($N$) em função do tempo ($T$).
O modelo de crescimento populacional acima é bem simples e elegante, mas também pouco realista. Esse modelo prevê que o tamanho de uma população seguindo esse tipo de trajetória de crescimento exponencial tenderá ao infinito. Como isso é obviamente impossível na natureza, devemos aprimorar esse modelo. Isso pode ser feito reavaliando algumas premissas do modelo acima, especificamente as premissas de que as taxas de natalidade ($b$) e mortalidade ($d$) per capita são independentes do tamanho populacional ($N$). Podemos, por exemplo, assumir que a taxa de crescimento per capita diminua linearmente com $N$ até chegar a zero. O tamanho $N$ de uma população que chega a esse ponto, em que a população pára de crescer e estabiliza ($dN/dT = 0$), é conhecido como capacidade de suporte ($K$). A dinâmica de uma população com crescimento limitado pode ser modelada através de uma equação de crescimento logística como esta:
$$\frac{dN}{dt} = rN \left(1-\frac{N}{K}\right)$$
Podemos ver que quando $N$ se iguala a $K$, a taxa de crescimento populacional é zerada. Da mesma forma, sempre que o valor de $N$ for maior que $K$, a taxa de crescimento populacional se torna negativa, até que a população retorne à capacidade de suporte.
Em algumas situações, a taxa de crescimento de uma população leva um tempo (atraso) para responder à mudança de tamanho dessa população. Por exemplo, quando a reprodução ou sobrevivência de indivíduos adultos depende da quantidade de recursos que tiveram acesso quando ainda imaturos, as taxas de natalidade e mortalidade podem refletir uma condição ambiental que não existe mais. Ou seja, a população pode continuar crescendo ou diminuindo mesmo após ter chegado à sua capacidade de suporte. Podemos modelar esse cenário fazendo com que a taxa de crescimento populacional no tempo $t$ seja uma função do tamanho populacional num tempo pretérito ($t-\tau$):
$$ \frac{dN}{dt} = rN_{t} \left(1-\frac{N_{t-\tau}}{K}\right)$$
pars_vars <- c("$r_i$", "$K_i$", "$N_i$", "$\\tau$") descriptions <- c("taxa de crescimento intrínseco", "capacidade de suporte", "tamanho populacional", "tempo de atraso (modelo logístico defasado)") param_df <- data.frame(pars_vars, descriptions) kable(x = param_df, format = "html", col.names = c("Parâmetro/variável", "Descrição")) %>% kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover", "condensed"), position = "center")
sidebarLayout( sidebarPanel( # User defined density dependent or independent growth ---- radioButtons("densdep", "Tipo de crescimento populacional", choices = c(`Denso independente` = "indep", `Denso dependente` = "dep")), # User defined intrinsic growth rate r ----- sliderInput("r_val", label = "Taxa de crescimento intrínseca (r):", min = -0.25, max = 1, value = .25), # If Density Dependent growth requested, ask for K ----- conditionalPanel(condition = "input.densdep == 'dep'", sliderInput("K_val", label = "Capacidade de suporte (K)", min = 1, max = 10000, value = 500, step = 10)), # If Density Dependent growth requested, ask if time lag requested ----- conditionalPanel(condition = "input.densdep == 'dep'", radioButtons("densdepLag", label = "denso-dependência atrasada?", choices = c(`No` = "nolag",`denso dependência atrasada` = "lag"))), # If timelag requested in density-dependent growth, ask for tau ----- conditionalPanel(condition = "input.densdepLag == 'lag'", sliderInput("tau", label = "Tempo de atraso (tau)", min = 0, max = 4, value = 1, step = .1)), # User defined initial population size ----- sliderInput("N1_val", label = "Tamanho inicial da população::", min = 1, max = 1000, value = 50, step = 10), hr(), # User can add a second species ---- checkboxInput("secondsp", "Adicione uma segunda espécie?", value = F), # If second species requested, add the following... ---- conditionalPanel(condition = "input.secondsp == true", # User defined density dependent or independent growth for sp2 ---- radioButtons("densdep2", "Tipo de crescimento populacional para a segunda espécie:", choices = c(`Denso independente` = "indep", `Denso dependente` = "dep")), # User defined intrinsic growth rate r2 ----- sliderInput("r_val2", label = "Taxa de crescimento intrínseca da espécie 2 (r2):", min = -0.25, max = 1, value = .25), # If Density Dependent growth requested for sp2, ask for K2 ----- conditionalPanel(condition = "input.densdep2 == 'dep'", sliderInput("K_val2", label = "Capacidade de suporte da espécie 2 (K2)", min = 1, max = 10000, value = 500, step = 10), ), # If Density Dependent growth requested, ask if time lag requested ----- conditionalPanel(condition = "input.densdep2 == 'dep'", radioButtons("densdepLag2", label = "denso-dependência atrasada?", choices = c(`No` = "nolag",`denso dependência atrasada` = "lag"))), # If timelag requested in density-dependent growth, ask for tau ----- conditionalPanel(condition = "input.densdepLag2 == 'lag'", sliderInput("tau2", label = "tempo de atraso (tau2)", min = 0, max = 4, value = 1, step = .1)), sliderInput("N2_val", label = "Tamanho inicial da população para a espécie 2:", min = 1, max = 1000, value = 50, step = 10), hr()), # User can select which plots to show ---- checkboxGroupInput("plots_to_show", "Escolha os gráficos que quer ver:", c("N ao longo do tempo" = "Nvtime", "ln(N) ao longo do tempo" = "lnNvtime", "crescimento populacional em função de N" = "n1overn", "crescimento populacional per capita em função de N" = "n1novern"), selected = c("Nvtime", "lnNvtime")), hr(), # User defined length of simulation ----- numericInput("max_time", label = "duração da simulação:", value = 100), # User defined initial population size ----- ), # Panel of plots ----- mainPanel( renderPlot({plots_to_print()}, width = 600, height = 600) ) ) # Get user defined parameters for sp 1 ------ params <- reactive({ if(input$densdep == "indep") { c(r = input$r_val) } else if(input$densdepLag == 'lag') { c(r = input$r_val, K = input$K_val, tau = input$tau) } else { c(r = input$r_val, K = input$K_val) } }) init <- reactive({c(N1 = input$N1_val)}) time <- reactive({seq(from = 0, to = input$max_time, by=1)}) params2 <- reactive({ if(input$densdep2 == "indep") { c(r = input$r_val2) } else if(input$densdepLag2 == 'lag') { c(r = input$r_val2, K = input$K_val2, tau = input$tau2) } else { c(r = input$r_val2, K = input$K_val2) } }) init2 <- reactive({c(N1 = input$N2_val)}) # Generate trajectories for sp 1 -------- pop_growth <- reactive({ if(input$densdep == 'indep') { data.frame(ecoevoapps::run_exponential_model(time= time(), init = init(), params = params())) } else { data.frame(ecoevoapps::run_logistic_model(time= time(), init = init(), params = params())) } }) # Generate trajectories for sp 2 -------- pop_growth2 <- reactive({ if(input$secondsp) { if(input$densdep2 == 'indep') { data.frame(ecoevoapps::run_exponential_model(time= time(), init = init2(), params = params2())) } else { data.frame(ecoevoapps::run_logistic_model(time= time(), init = init2(), params = params2())) } } }) pops_combined <- reactive({ if(input$secondsp) { dplyr::bind_rows(pop_growth(), pop_growth2(), .id = "which_pop") } else { pg <- pop_growth() pg$which_pop = "1" pg } }) # Make plots ----------- # 0. Make caption ------ plot_caption1 <- reactive({ if(input$densdep == 'indep') { paste0("Species 1 parameter values: r1 = ", input$r_val) } else if (input$densdepLag == "nolag") { paste0("Species 1 parameter values: r1 = ", input$r_val, ", K1 = ", input$K_val) } else { paste0("Species 1 parameter values: r1 = ", input$r_val, ", K1 = ", input$K_val, ", Tau1 = ", input$tau) } }) plot_caption2 <- reactive({ if(input$secondsp) { if(input$densdep2 == 'indep') { paste0("Species 2 parameter values: r2 = ", input$r_val2) } else if (input$densdepLag2 == "nolag") { paste0("Species 2 parameter values: r2 = ", input$r_val2, ", K2 = ", input$K_val2) } else { paste0("Species 2 parameter values: r2 = ", input$r_val2, ", K2 = ", input$K_val2, ", Tau2 = ", input$tau2) } } }) plot_caption <- reactive ({ if(input$secondsp) { paste0(plot_caption1(), "\n", plot_caption2()) } else { plot_caption1() } }) # 1. Trajectory of N vs. time ----------- trajectory <- reactive({ if("Nvtime" %in% input$plots_to_show) { ggplot(pops_combined()) + geom_line(aes(x = time, y = N1, color = which_pop), linewidth = 2) + ecoevoapps::theme_apps() + scale_x_continuous(expand = c(0, 0, .1, 0)) + scale_y_continuous(expand = c(0, 0, .1, 0)) + annotate("text", x = 0, y = 0, label = "") + scale_color_brewer("Species", palette = "Set1") + ylab("Population size") } }) # 2. Trjectory of ln(N) vs. time -------- trajectory_log <- reactive({ if("lnNvtime" %in% input$plots_to_show) { ggplot(pops_combined()) + geom_line(aes(x = time, y = log(N1), color = which_pop), linewidth = 2) + scale_color_brewer("Species", palette = "Set1") + ecoevoapps::theme_apps() + scale_x_continuous(expand = c(0, 0, .1, 0)) + scale_y_continuous(expand = c(0, 0, .1, 0)) + annotate("text", x = 0, y = 0, label = "") + ylab("ln(Population size)") } }) # 3. dN/dT vs. N ----------- n1_over_n <- reactive({ if("n1overn" %in% input$plots_to_show) { dndt_out <- data.frame(dndt = dndt(params()), which_pop = "1") dndt_out$x <- 1:nrow(dndt_out) dndt_out_for_plot <- if(input$secondsp) { dn2dt_out <- data.frame(dndt = dndt(params2()), which_pop = "2") dn2dt_out$x <- 1:nrow(dn2dt_out) dplyr::bind_rows(dndt_out, dn2dt_out) } else { dndt_out } ggplot(dndt_out_for_plot) + geom_line(aes(x= x, y = dndt, color = which_pop), linewidth = 2) + xlab("Population Size") + ylab("Population growth rate (dN/dt)") + scale_color_brewer("Species", palette = "Set1") + scale_x_continuous(expand = c(0, 0, .1, 0)) + scale_y_continuous(expand = c(0, 0, .1, 0)) + theme_apps() } }) # 4. dN/Ndt vs. N ----------- n1n_over_n <- reactive({ if("n1novern" %in% input$plots_to_show) { dnNdt_out <- data.frame(dnNdt = dnNdt(params()), which_pop = "1") dnNdt_out$x <- 1:nrow(dnNdt_out) dnNdt_out_for_plot <- if(input$secondsp) { dnN2dt_out <- data.frame(dnNdt = dnNdt(params2()), which_pop = "2") dnN2dt_out$x <- 1:nrow(dnN2dt_out) dplyr::bind_rows(dnNdt_out, dnN2dt_out) } else { dnNdt_out } ggplot(dnNdt_out_for_plot) + geom_line(aes(x = x, y = dnNdt, color = which_pop), linewidth = 2) + xlab("Population Size") + ylab("per-capita population growth rate\n(dN/Ndt)") + scale_color_brewer("Species", palette = "Set1") + scale_x_continuous(expand = c(0, 0, .1, 0)) + # limits = c(0, min(max(pop_growth()$N1)), max(pop_growth2()$N1) scale_y_continuous(limits = c(-0.26, 1), expand = c(0, 0, .1, 0)) + theme_apps() } }) # Make a list of plots and print out plots based on which ones were requested ---- plot_list <- reactive({ list(trajectory(), trajectory_log(), n1_over_n(), n1n_over_n()) %>% discard(is.null) }) plots_to_print <- reactive({ wrap_plots(plot_list(), ncol = 2) + labs(caption = plot_caption()) + plot_layout(guides = "collect") & theme(legend.position = 'bottom') })
"How populations grow: the Exponential and the logistic", John Vandermeer, Nature Education Knowledge.
"Exponential & logistic growth" at Khan Academy.
suppressWarnings(ecoevoapps::print_app_footer(language = "pt"))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.