中文 | Español | English | português | Turkish

library(ecoevoapps)
library(deSolve)
library(tidyverse)
library(patchwork)
library(RColorBrewer)
library(knitr)
library(kableExtra)
knitr::opts_chunk$set(echo=FALSE)
theme_set(ecoevoapps::theme_apps())

As equações de competição de Lotka-Volterra modelam a dinâmica de duas espécies que competem entre si por recursos (comida, espaço, etc). A ideia por trás desse modelo é que, conforme a população de uma espécie cresce, ela passa a ser limitada não só por competição entre os indivíduos dessa própria espécie (competição intraespecífica), mas também por indivíduos de outras espécies (competição interespecífica). Explicações detalhadas dos modelos podem ser encontradas em diversos livros-textos e páginas na internet.

Há várias formas de se escrever os modelos de competição de Lotka-Volterra. A forma mais comum é modelar a competição em termos da capacidade de suporte de cada espécie ($K_1$ e $K_2$) e dos efeitos relativos da competição interespecífica em cada espécie ($\alpha$ e $\beta$). Essa versão do modelo é apresentada na primeira aba abaixo (Modelo em termos de capacidade de suporte e efeitos relativos de competição). Outra forma menos usada, mas mais intuitiva, do modelo foi apresentada pelo já clássico artigo de Peter Chesson (2000) "Mecanismos de manutenção da diversidade de espécies". Nesse artigo, Chesson sugere escrever o modelo de Lotka-Volterra em termos de coeficientes absolutos de competição para cada espécie ($\alpha_{12}$ e $\alpha_{21}$). A segunda aba abaixo (Modelo em termos de coeficientes de competição absolutos) permite que o usuário explore essa outra forma do modelo.

{.tabset}

Modelo em termos de capacidade de suporte e efeitos relativos de competição

Equações de competição de Lotka-Volterra escritas com base na capacidade de suporte das espécies:

$$\frac{dN_1}{dt} = r_1N_1\left(1 - \frac{N_1 + \alpha N_2}{K_1}\right)$$ $$\frac{dN_2}{dt} = r_2N_2\left(1 - \frac{N_2 + \beta N_1}{K_2}\right)$$

pars_vars <- c("$r_1$", 
               "$r_2$", 
               "$N_1$", 
               "$N_2$", 
               "$K_1$", 
               "$K_2$", 
               "$\\alpha$", 
               "$\\beta$")
descriptions <- c("Taxa de crescimento intrínseco da espécie 1",
                 "Taxa de crescimento intrínseco da espécie 2",
                 "Tamanho da população da espécie 1",
                 "Tamanho da população da espécie 2",
                 "Capacidade de suporte da espécie 1",
                 "Capacidade de suporte da espécie 2",
                 "Efeito relativo per capita da espécie 2 na espécie 1",
                 "Efeito relativo per capita da espécie 1 na espécie 2")
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")

Isoclinas de crescimento líquido zero (resolvido como função de $N_2$):

$$N_2 = - \frac{N_1}{\alpha} + \frac{K_1}{\alpha}$$ $$N_2 = -\beta N_1 + K_2$$


sidebarLayout(
  sidebarPanel(
    # Allow user to select which plots to display
    checkboxGroupInput(inputId = "plots_to_show",
                       label = "Selecione os gráficos",
                       choices = c("Isoclinas de crescimento líquido zero (ZNGI)" = "ZNGI")),

    hr(),

    # User-defined parameter values
    sliderInput(inputId = "r1", 
                label = HTML("r<sub>1</sub>: Taxa de crescimento intrínseco da espécie 1"),
                min = 0.01, max = 1, value = 0.2, step = 0.01),
    sliderInput(inputId = "r2", 
                label = HTML("r<sub>2</sub>: Taxa de crescimento intrínseco da espécie 2"),
                min = 0.01, max = 1, value = 0.5, step = 0.01),
    numericInput(inputId = "K1", 
                 label = HTML("K<sub>1</sub>: Capacidade de suporte da espécie 1"),
                 min = 1, value = 300),
    numericInput(inputId = "K2", 
                 label = HTML("K<sub>2</sub>: Capacidade de suporte da espécie 2"),
                 min = 1, value = 200),
    sliderInput(inputId = "alpha", 
                label = HTML("&alpha;: Efeito relativo per capita da espécie 2 na espécie 1"),
                min = 0.01, max = 2, value = 0.3, step = 0.01),
    sliderInput(inputId = "beta", 
                label = HTML("&beta;: Efeito relativo per capita da espécie 1 na espécie 2"),
                min = 0.01, max = 2, value = 0.2, step = 0.01),
    # User-defined initial values
    numericInput(inputId = "N1", 
                 label = "Tamanho inicial da população da espécie 1",
                 min = 1, value = 50),
    numericInput(inputId = "N2", 
                 label = "Tamanho inicial da população da espécie 2",
                 min = 1, value = 70),

    numericInput(inputId = "max_time", 
                 label = "Duração da simulação",
                 min = 1, value = 100)
  ),

  # Panel of plots
  mainPanel(
    renderPlot(N_vs_Time(), width = 600, height = 500),
      renderPlot(ZNGI(), width = 600, height = 500))
)

# Get user-defined parameters
init <- reactive({
  c(N1 = input$N1, N2 = input$N2)
})
time <- reactive({
  seq(from = 0, to = input$max_time, by = 0.1)
})
params <- reactive({
  c(r1 = input$r1, r2 = input$r2, K1 = input$K1, K2 = input$K2, 
    a = input$alpha, b = input$beta)
})



# Run lotka_volterra_competition function
lvcomp_out <- reactive({
  run_lvcomp_model(time = time(), init = init(), params = params()) %>% 
    data.frame()
})


N_vs_Time <- reactive({
  plot_lvcomp_time(lvcomp_out())
})

# Plot ZNGIs with population trajectories

ZNGI <- reactive({
  if ("ZNGI" %in% input$plots_to_show) {
    plot_lvcomp_portrait(lvcomp_out(), params = params(), margin_text = T)
  } 
})

# Make a list of plots to print based on user request
plot_list <- reactive({ 
  list(N_vs_Time(), ZNGI()) %>%
    discard(is.null)
  })

plots_to_print <- reactive({ 
  wrap_plots(plot_list(), ncol = 1)
  })

Modelo em termos de coeficientes de competição absolutos

Equações de competição de Lotka-Volterra escritas sem usar a capacidade de suporte das espécies:

$$\frac{dN_1}{dt} = r_1N_1\left(1 - \alpha_{11}N_1 - \alpha_{12}N_2\right)$$ $$\frac{dN_2}{dt} = r_2N_2\left(1 - \alpha_{22}N_2 - \alpha_{21}N_1\right)$$

pars_vars_wo_K <- c("$r_1$",
                    "$r_2$",
                    "$N_1$",
                    "$N_2$",
                    "$\\alpha_{11}$",
                    "$\\alpha_{12}$",
                    "$\\alpha_{22}$",
                    "$\\alpha_{21}$")
descriptions_wo_K <- c("Taxa de crescimento intrínseco da espécie 1",
                       "Taxa de crescimento intrínseco da espécie 2",
                       "Tamanho da população da espécie 1",
                       "Tamanho da população da espécie 2",
                       "Efeito per capita da espécie 1 em si mesma",
                       "Efeito per capita da espécie 2 na espécie 1",
                       "Efeito per capita da espécie 2 em si mesma",
                       "Efeito per capita da espécie 1 na espécie 2")
param_df_wo_K <- data.frame(pars_vars_wo_K, descriptions_wo_K)
kable(x = param_df_wo_K, format = "html",
      col.names = c("Parâmetro/variável", "Descrição")) %>%
  kable_styling(full_width = FALSE,
                bootstrap_options = c("striped", "hover", "condensed"),
                position = "center")

Isoclinas de crescimento líquido zero (resolvido como função de $N_2$):

$$N_2 = -\frac{\alpha_{11}}{\alpha_{12}}N_1 + \frac{1}{\alpha_{12}}$$ $$N_2 = -\frac{\alpha_{21}}{\alpha_{22}}N_1 + \frac{1}{\alpha_{22}}$$


sidebarLayout(
  sidebarPanel(
    # Allow users to select which plots to display
    checkboxGroupInput(inputId = "plots_to_show_wo_K",
                       label = "Selecione os gráficos",
                       choices = c("Isoclinas de crescimento líquido zero (ZNGI)" = "ZNGI_wo_K")),

    hr(),

    # User-defined parameter values
    sliderInput(inputId = "r1_wo_K",
                label = HTML("r<sub>1</sub>: Taxa de crescimento intrínseco da espécie 1"),
                min = 0.01, max = 1, value = 0.2, step = 0.01),
    sliderInput(inputId = "r2_wo_K",
                label = HTML("r<sub>2</sub>: Taxa de crescimento intrínseco da espécie 2"),
                min = 0.01, max = 1, value = 0.5, step = 0.01),

    # Allow user to choose input method for competition coefficients
    radioButtons(inputId = "alpha_input_wo_K",
                 label = "Método de seleção de coeficientes de competição:",
                 choices = c("Controle deslizante" = "slider", "Manual" = "manual"),
                 selected = "slider"),

    # Conditional panel for slider input of competition coefficients
    conditionalPanel(
      condition = "input.alpha_input_wo_K == 'slider'",
      sliderInput(inputId = "alpha11_slider",
                  label = HTML("&alpha;<sub>11</sub>: Efeito per capita da espécie 1 em si mesma"),
                  min = 0.0001, max = 0.01, value = 0.0033, step = NULL),
      sliderInput(inputId = "alpha12_slider",
                  label = HTML("&alpha;<sub>12</sub>: Efeito per capita da espécie 2 na espécie 1"),
                  min = 0.0001, max = 0.01, value = 0.001, step = NULL),
      sliderInput(inputId = "alpha22_slider",
                  label = HTML("&alpha;<sub>22</sub>: Efeito per capita da espécie 2 em si mesma"),
                  min = 0.0001, max = 0.01, value = 0.005, step = NULL),
      sliderInput(inputId = "alpha21_slider",
                  label = HTML("&alpha;<sub>21</sub>: Efeito per capita da espécie 1 na espécie 2"),
                  min = 0.0001, max = 0.01, value = 0.001, step = NULL)
    ),

    # Conditional panel for manual input of competition coefficients
    conditionalPanel(
      condition = "input.alpha_input_wo_K == 'manual'",
      numericInput(inputId = "alpha11_manual",
                   label = HTML("&alpha;<sub>11</sub>: Efeito per capita da espécie 1 em si mesma"),
                   min = 0.0001, max = 1, value = 0.0033, step = 0.0001),
      numericInput(inputId = "alpha12_manual",
                   label = HTML("&alpha;<sub>12</sub>: Efeito per capita da espécie 2 na espécie 1"),
                   min = 0.0001, max = 1, value = 0.001, step = 0.0001),
      numericInput(inputId = "alpha22_manual",
                   label = HTML("&alpha;<sub>22</sub>: Efeito per capita da espécie 2 em si mesma"),
                   min = 0.0001, max = 1, value = 0.005, step = 0.0001),
      numericInput(inputId = "alpha21_manual",
                   label = HTML("&alpha;<sub>21</sub>: Efeito per capita da espécie 1 na espécie 2"),
                   min = 0.0001, max = 1, value = 0.001, step = 0.0001)
    ),

    # User-defined initial values
    numericInput(inputId = "N1_wo_K",
                 label = "Tamanho inicial da população da espécie 1",
                 min = 1, value = 50),
    numericInput(inputId = "N2_wo_K",
                 label = "Tamanho inicial da população da espécie 2",
                 min = 1, value = 70),

    numericInput(inputId = "max_time_wo_K",
                 label = "Duração da simulação",
                 min = 1, value = 100)
  ),

  # Panel of plots 
  mainPanel(renderPlot(N_vs_Time_wo_K(), width = 600, height = 500),
            renderPlot(ZNGI_wo_K(), width = 600, height = 500))
)

# Store inputted competition coefficients as new reactive objects
alpha11_wo_K <- reactive({
  if (input$alpha_input_wo_K == "slider") {
    input$alpha11_slider
  } else if (input$alpha_input_wo_K == "manual") {
    input$alpha11_manual
  }
})
alpha12_wo_K <- reactive({
  if (input$alpha_input_wo_K == "slider") {
    input$alpha12_slider
  } else if (input$alpha_input_wo_K == "manual") {
    input$alpha12_manual
  }
})
alpha22_wo_K <- reactive({
  if (input$alpha_input_wo_K == "slider") {
    input$alpha22_slider
  } else if (input$alpha_input_wo_K == "manual") {
    input$alpha22_manual
  }
})
alpha21_wo_K <- reactive({
  if (input$alpha_input_wo_K == "slider") {
    input$alpha21_slider
  } else if (input$alpha_input_wo_K == "manual") {
    input$alpha21_manual
  }
})

# Get user-defined parameters
init_wo_K <- reactive({
  c(N1 = input$N1_wo_K, N2 = input$N2_wo_K)
})
time_wo_K <- reactive({
  seq(from = 0, to = input$max_time_wo_K, by = 0.1)
})
params_wo_K <- reactive({
  c(r1 = input$r1_wo_K, r2 = input$r2_wo_K,
    a11 = alpha11_wo_K(), a12 = alpha12_wo_K(),
    a22 = alpha22_wo_K(), a21 = alpha21_wo_K())
})


# Run lotka_volterra_competition_wo_K function
lvcomp_out_wo_K <- reactive({
    run_lvcomp_model(time = time_wo_K(), 
init = init_wo_K(), params = params_wo_K()) %>% 
      data.frame()
})

N_vs_Time_wo_K <- reactive({
  plot_lvcomp_time(lvcomp_out_wo_K())
})
# Convert data to long format

# Plot ZNGIs with population trajectories
ZNGI_wo_K <- reactive({
  if ("ZNGI_wo_K" %in% input$plots_to_show_wo_K) {
    plot_lvcomp_portrait(lvcomp_out_wo_K(), params = params_wo_K(),
                         margin_text = T)
  } 
})

# Make a list of plots to print based on user request
plot_list_wo_K <- reactive({
  list(N_vs_Time_wo_K(), ZNGI_wo_K()) %>%
    discard(is.null)
})

plots_to_print_wo_K <- reactive({
  wrap_plots(plot_list_wo_K(), ncol = 1)
})

References


suppressWarnings(ecoevoapps::print_app_footer(language = "pt"))


gauravsk/ecoevoapps documentation built on July 9, 2024, 9:37 p.m.