中文 | Español | English | português | Turkish
knitr::opts_chunk$set(echo = FALSE) library(ecoevoapps) library(tidyverse) library(patchwork) library(knitr) library(kableExtra)
El mutualismo es un tipo de interacción en donde las especies que interactúan se confieren un efecto benéfico neto entre ellas. Los mutualismos se pueden manifestar de diversas formas que incluyen (pero no se limitan a) las interacciones planta-polinizador, la dispersión de semillas por vectores animales y la defensa de depredadores. Por ejemplo, las avispas de los higos polinizan, ponen sus huevos y se alimentan de los higos (Cook & Rasplus 2003). Otre ejemplo es el mutualismo que existe entre las hormigas y las acacias en donde las hormigas se alimentan de las acacias y se refugian en ellas al mismo tiempo que las protegen de herbívoros (Janzen 1966). Bronstein (2015) presenta un recuento detallado de los mutualismos.
Esta app explora un modelo de mutualismo directo entre dos especies (Holland 2012). La idea central del modelo es que la tasa de crecimiento poblacional de cada especie ($\frac{dN}{dt}$) se ve modificada por la interacción de individuos de su misma especie y de la otra especie, como sucede un modelo clásico de competencia de Lotka-Volterra competition model Cuando cada especie se encuentra creciendo sola experimenta competencia intraespecífica y solamente crece hasta la capacidad de carga de su población. Sin embargo, cuando las dos especies interactúan ambas se benefician, de tal forma que cada especie puede crecer más allá de su capacidad de carga. El modelo también supone que los beneficios que pueden obtener las poblaciones del mutualismo van disminuyendo, es decir que los efectos positivos de cada especie se estabilizan en cierto tamaño poblacional
Dadas estas condiciones el modelo se puede expresar de la siguiente forma:
$$\frac{dN_1}{dt} = r_1N_1 + \frac{\alpha_{12}N_2}{b_2 + N_2}N_1 - d_1N_1^2$$ $$\frac{dN_2}{dt} = r_2N_2 + \frac{\alpha_{21}N_1}{b_1 + N_1}N_2 - d_2N_2^2$$
Las descripciones de los parámetros se encuentran en la tabla subsecuente. En cada ecuación el primer término ($r_iN_i$) describe el crecimiento poblacional en ausencia de interacciones. El segundo término ($\frac{\alpha_{ij}N_j}{b_j + N_j}N_i$) describe cómo incrementa el crecimiento poblacional como una función de saturación del tamaño poblacional del mutualista (expresado como una curva de Michaelis–Menten). Finalmente, el tercer término ($d_iN_i^2$) describe cómo disminuye la tasa de crecimiento poblacional conforme aumenta el tamaño poblacional.
pars <- c("$r_i$", "$N_i$", "$\\alpha_{ij}$", "$d_i$", "$b_i$") descriptions <- c("Tasa de crecimiento per cápita de la especie $i$", "Tamaño poblacional de la especie $i$", "Efecto mutualista per cápita de la especie $j$ sobre la especie $i$", "Tasa de autolimitación de la especie $i$", "Constante de la mitad de la saturación de la ecuación de Michaelis-Menten, es decir el tamaño poblacional de la especie $i$ a la cual provee la mitad del beneficio máximo a la especie $j$" ) param_df <- data.frame(pars, descriptions) kable(x = param_df, format = "html", col.names = c("Parámetro o Variable", "Descripción"), table.attr = "style='width:50%;'") %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed"), position = "center")
Para explorar cómo crecen las poblaciones en presencia de las interacciones mutualistas podemos utilizar al modelo para simular las trayectorias poblacionales en el tiempo (selecciona "N vs tiempo"). También podemos explorar el resultado a largo plazo de las interacciones mutualistas al estudiar las gráficas de las isoclinas de crecimiento cero. Éstas muestran las condiciones en las cuales el crecimiento poblacional es cero ($\frac{dN_1}{dt} = \frac{dN_2}{dt} = 0$), para identificar la combinación de tamaños poblaciones en las cuáles ambas poblaciones están al equilibrio (selecciona "Diagrama de fase").
##### UI ##### # Input panel wellPanel( fluidRow( column(4, numericInput(inputId = "r1", label = HTML("r<sub>1</sub>: tasa de crecimiento per cápita de la sp. 1"), value = 0.5, step = 0.1)), column(4, numericInput(inputId = "r2", label = HTML("r<sub>2</sub>: tasa de crecimiento per cápita de la sp. 2"), value = 0.5, step = 0.1)), column(4, numericInput(inputId = "N1", label = "Tamaño inicial de la población de la sp. 1", value = 20, min = 0, step = 1))), fluidRow( column(4, numericInput(inputId = "a12", label = HTML("α<sub>12</sub>: Efecto de la sp. 2 sobre la sp. 1"), value = 0.8, min = 0, step = 0.1)), column(4, numericInput(inputId = "a21", label = HTML("α<sub>21</sub>: Efecto de la sp. 1 sobre la sp. 2"), value = 0.4, min = 0, step = 0.1)), column(4, numericInput(inputId = "N2", label = "Tamaño inicial de la población de la sp. 2", value = 40, min = 0, step = 1))), fluidRow( column(4, numericInput(inputId = "d1", label = HTML("d<sub>1</sub>: Tasa de autolimitación de la sp. 1"), value = 0.02, min = 0, step = 0.01)), column(4, numericInput(inputId = "d2", label = HTML("d<sub>2</sub>: Tasa de autolimitación de la sp. 2"), value = 0.01, min = 0, step = 0.01)), column(4, numericInput(inputId = "time", label = "Duración de la simulación", value = 50, min = 1, step = 1))), fluidRow( column(4, numericInput(inputId = "b1", label = HTML("b<sub>1</sub>: constante de la mitad de la saturación para la sp. 1"), value = 10, min = 0, step = 1)), column(4, numericInput(inputId = "b2", label = HTML("b<sub>2</sub>: constante de la mitad de la saturación para la sp. 2"), value = 10, min = 0, step = 1)), column(2, radioButtons(inputId = "plot", label = "Gráfica", choices = c("N vs tiempo" = "time", "Diagrama de fase" = "phase", "Ambos" = "both"), selected = "both")), column(2, conditionalPanel( condition = "input.plot != 'time'", checkboxGroupInput(inputId = "phase_opt", label = "Dibuja", choices = c("Campos de vectores" = "vec", "Trayectorias de las poblaciones" = "traj"), selected = c("vec", "traj"))))) ) # Output panel fluidRow( column(12, renderPlot(plot(), height = 500)) ) ##### Server ##### # Validate input observeEvent(input$a12, { if (input$a12 <= 0) updateNumericInput(inputId = "a12", value = 0.1) }) observeEvent(input$a21, { if (input$a21 <= 0) updateNumericInput(inputId = "a21", value = 0.1) }) observeEvent(input$d1, { if (input$d1 <= 0) updateNumericInput(inputId = "d1", value = 0.01) }) observeEvent(input$d2, { if (input$d2 <= 0) updateNumericInput(inputId = "d2", value = 0.01) }) observeEvent(input$b1, { if (input$b1 <= 0) updateNumericInput(inputId = "b1", value = 1) }) observeEvent(input$b2, { if (input$b2 <= 0) updateNumericInput(inputId = "b2", value = 1) }) observeEvent(input$N1, { if (input$N1 <= 0) updateNumericInput(inputId = "N1", value = 1) }) observeEvent(input$N2, { if (input$N2 <= 0) updateNumericInput(inputId = "N2", value = 1) }) observeEvent(input$time, { if (input$time < 1) updateNumericInput(inputId = "time", value = 1) }) # Retrieve user inputs params <- reactive({c(r1 = input$r1, r2 = input$r2, a12 = input$a12, a21 = input$a21, d1 = input$d1, d2 = input$d2, b1 = input$b1, b2 = input$b2)}) init <- reactive({c(N1 = input$N1, N2 = input$N2)}) time <- reactive({input$time}) vec <- reactive({"vec" %in% input$phase_opt}) traj <- reactive({"traj" %in% input$phase_opt}) # Run mutualism model sim <- reactive({run_mutualism(time(), init(), params())}) # Plot population trajectories over time plot <- reactive({ if (input$plot == "time") { plot_mutualism_time(sim()) + theme(aspect.ratio = 1) } else if (input$plot == "phase") { plot_mutualism_portrait(sim(), vec(), traj()) + theme(aspect.ratio = 1) } else { wrap_plots(plot_mutualism_time(sim()), plot_mutualism_portrait(sim(), vec(), traj()), nrow = 1) + theme(aspect.ratio = 1) } })
# Print footer suppressWarnings(print_app_footer())
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.