Feature/core eco basic ricker#1
Conversation
Added a few comments to Brett's original script to provide additional context to students. In addition, added explanation and examples of Poisson and Bernoulli distributions
Working off of 05_plotprodfunc.R, I added the poisson, poisson binomial, and the negative binomial-binomial gamma plots (with associated functions) to the code. Re-creates some of Suppl. Fig 1. Guiding questions incorporated too
| @@ -0,0 +1,10 @@ | |||
| .Rproj.user | |||
There was a problem hiding this comment.
Add to gitignore:
*.rproj
.gitignore
and delete gitignore from this branch
There was a problem hiding this comment.
Delete this file from commit (suggested adding to gitignore)
| fit <- lmer(r ~ Nt + (1|fbatch), data = filter(tribdata, r != -Inf)) | ||
| fit | ||
|
|
||
| # Fit by ordinary linear regression (can remove batch given results above) |
There was a problem hiding this comment.
It's worth showing how transforming the model allows this linear fit. Also, it's a rough fit because of not handling the various data issues (-Inf etc)
N_{t+1} = R N_t e^(-alpha N_t)
N_{t+1} / N_t = R e^(-alpha N_t)
log(N_{t+1} / N_t) = log(R e^(-alpha N_t))
r = log(R) - alpha N_t
r = r_0 - alpha N_t
| geom_point() + | ||
| ylim(0, 250) + | ||
| labs(title = "Predicted dynamics") | ||
|
|
There was a problem hiding this comment.
Try also increasing R to see stable limit cycles and chaos. The code in bifurcation.R will make some plots that show where the bifurcations occur. This is one of the interesting dynamical properties that emerge from these discrete generation models.
| set.seed(19) #ensure reproducibility | ||
| sexRatio1000 <- rbinom(n = 1000, size = 1, prob = 0.5) #1000 beetles | ||
| table(sexRatio1000) #how many are in each category? | ||
| set.seed(19) #ensure reproducibility |
There was a problem hiding this comment.
By setting the seed the same, this 100 will be same as the first 100 in previous 1000. Perhaps that's what you wanted to show? Otherwise, suggest not resetting the seed.
| Ricker <- function(Nt, R, alpha){ | ||
| Nt * R * exp(-1 * alpha * Nt) | ||
| } | ||
|
|
There was a problem hiding this comment.
I think here a good thing to do might be to walk through the lifecycle of a single individual.
R = B(1-m), where B is birth rate and m is mortality probability
- It gives birth
births <- rpois(n=1, lambda=B)
- Now each of these individuals survives or dies. For a single individual, it has to survive both cannibalism (a density-dependent process) and density-independent causes of death. Let's look at one individual:
First, does it survive density-dependent cannibalism?
p_sdd <- exp(-1 * alpha * Nt)
survive <- rbinom(n=1, size=1, prob = p_sdd )
Now, if it does survive cannibalism, does it also survive density-independent causes of death?
p_sdi <- 1 - m
if ( survive ) {
survive <- rbinom(n=1, size=1, prob = p_sdi )
}
A simple emergent stochastic process arises from these two different binomial stochastic processes. The emergent process is also binomial. Combining them together gives the following stochastic process for the survival of a single individual:
p_sdd <- exp(-1 * alpha * Nt)
p_sdi <- 1 - m
survive <- rbinom(n=1, size=1, prob = p_sdd * p_sdi )
Now summing up the survival of all the individuals that were born:
survivors <- 0
if ( births > 0 ) {
for ( i in 1:births) {
survive <- rbinom(n=1, size=1, prob = p_sdd * p_sdi )
if ( survive ) {
survivors <- survivors + 1
}
}
}
So, how many made it to become the next generation , N_{t+1}:
print(survivors)
For the whole population of N_t, we add up the contribution from all the individuals. The function following collapses these steps into two emergent overall stochastic distributions and is a vectorized version of this, and is further vectorized to accept multiple populations at once (i.e. Nt can be a vector).
There was a problem hiding this comment.
One neat thing about the above, is that the emergent stochastic process for that original individual, even though a sequence of different stochastic processes (one Poisson and two binomial events), is simply Poisson:
Ntp1_i <- rpois(n=1, lambda = R * exp(-1 * alpha * Nt))
| RickerStBS <- function(Nt, R, alpha){ | ||
| # Births and density independent survival (R = births*(1-mortality); mortality | ||
| # is binomial, so compound distribution is Poisson with mean R). | ||
| births <- rpois( length(Nt), Nt * R ) |
There was a problem hiding this comment.
It could be worth replacing length(Nt) with n=1, as that's all we're doing here. The length(Nt) allows multiple populations to be done at once but it might be confusing at first.
| # How does it incorporate stochasticity? Also, pay attention to how the binomial | ||
| # simulation is then plugged into the Poisson simulation. Why does it make | ||
| # sense biologically to model the binomial first? | ||
| RickerStSexBS <- function(Nt, R, alpha, p=0.5){ |
There was a problem hiding this comment.
What might be cool here instead is to add the steps back in (since the rpois is combining the two steps from the previous function, so it's less obvious what is happening biologically):
females <- rbinom(1, size=Nt, prob=p)
births <- rpois(1, lambda=females * (1/p) * R)) #why do we multiply R * 1/p?
survivors <- rbinom(1, size=births, prob= exp(-1 * alpha * Nt)| survivors <- rpois( length(Nt), females * (1/p) * R * exp( -alpha * Nt ) ) | ||
| return(survivors) | ||
| } | ||
|
|
There was a problem hiding this comment.
Then modify the function to add back in the length(Nt) argument, which allows multiple populations to be simulated at once in a vectorized way. Then simulate a bunch of populations with the same Nt
Ntp1 <- RickerStBS(Nt=rep(10, 10000), R, alpha)
hist(Ntp1)
var(Ntp1)
Make a histogram of N_{t+1}. This is the distribution of the stochastic process. What is the variance in N_{t+1}?
| # plotting stage, look at the code and think about why or why not) | ||
| # Notice how it returns the sum of the poisvar and sexvar. Can you figure | ||
| # out why it does this (again, may need to plot first!) | ||
| Ricker_poisbinom.var <- function(Nt,R,alpha) { |
There was a problem hiding this comment.
So this is the math solution to the variance. It's kinda neat ('cause math ;) but perhaps not obvious directly. We could add in the simulation of the variance suggested above and show that it matches the math.
There was a problem hiding this comment.
vars <- rep(NA,101)
i = 1
for ( Nt in seq(0, 1000, 10) ) {
Ntp1 <- RickerStBS(rep(Nt, 10000), R, alpha)
vars[i] <- var(Ntp1)
i <- i + 1
}
plot(seq(0, 1000, 10) , sqrt(vars), xlab="Nt", ylab="Standard deviation in N_{t+1}")| return( poisvar + sexvar ) | ||
| } | ||
|
|
||
| # 2. Now we'll reproduce a few of the plots in Melbourne & Hasting (2008), |
There was a problem hiding this comment.
It would be good to simulate the dynamics over time now. Code is simple and is in plottimeseries.R. Do a few runs to see the variability. Compare to the deterministic model. Compare Poisson to say a model with environmental variation.
| # about how adding more stochasticity reflects the biology. | ||
|
|
||
| # First, we'll define some additional parameters needed for the simulation | ||
| kD <- 0.5 #Shape parameter of gamma for birth rate |
There was a problem hiding this comment.
Some people may be familiar with the negative binomial. This is the same K. This is where a negative binomial comes from: it's a compound Poisson-gamma distribution. K can be thought of as the dispersion parameter, much like the variance of the Normal is the dispersion parameter of the Normal. The only twist is that magnitude is reversed: small K is large dispersion, infinite K is zero dispersion and returns the Poisson model. Biologically, the way to think about this is: small K = large variation in birth rates, large K = small variation in birth rates, infinite K = no variation in birth rates among individuals or environments (reduces to Poisson variation, i.e. pure demographic stochasticity).
|
|
||
| # 2. Function for adding in std later on. Note how it returns a combination | ||
| # of the 4 types of stochasticity/4 models! | ||
| Ricker_nbinombinomgamma.var <- function(Nt,R,alpha,kD,kE) { |
There was a problem hiding this comment.
For me, the neat discovery was that these variances simply add up (and had simple equations for the components). The reason the Ricker function is there is because it gives the mean N_{t+1} of the stochastic process. In the Poisson, the variance is equal to the mean of the stochastic process. I forget the derivation of the others (I remember discovering it and being surprised, actually after the paper was published, so the results in the paper were actually by simulation) but it's the expected variance for that component.
There was a problem hiding this comment.
This is great! I've made a few suggestions.
brettmelbourne
left a comment
There was a problem hiding this comment.
Thanks for this, it looks wonderful! I made a few suggestions.
Creates a new script, coreEcoBasicRicker.R, for use in the population ecology unit for Core Ecology to accompany discussion of Melbourne & Hastings, 2008
Script overview: