A population in which birth and death rates are constant grows independently of its own density. This situation is usually related to the absence of restriction on growth, when resources are unlimited, but it can also be associated with a depletion of resources and the extinction of the population.
Let us now imagine a hypothetical population with constant growth and death rates and no migrations. At each time cycle related to a generation (T), the population size is the result of the number of individuals from the previous generation plus number of births (B), less deaths (D).
$$N_{T+1} = N_T + B - D $$
We can relate the number of deaths and births to a per capita value:
where: b = birth rate per capita for each generation; d = mortality rate per capita for each generation. Note that the rate does not change with population size, however, the number of births and deaths is proportional to population size. Let's just clarify one more premise, for didactic purposes: births and mortalities occur simultaneously in the population (eg, an annual plant). Since T is the scale of a generation, we can then say that:
if: $r_T = b-d$ ; discrete growth factor
Since $1+r_T$ is a constant, let's designate it as $\lambda$, a positive number that measures the proportional increase in population from one generation to the next. Therefore:
$$ N_{T+1} = \lambda N_T$$
We can then project our population to each time cycle (generations). For example:
If a population of 100 has a per capita birth rate of 0.8/year and a death rate of 0.75/year, what is the expected population size in the next year?
N0=100 lamb=1+(0.8-0.75) Nt1=N0*lamb Nt1
We can also project the population to other generations, using iterations:
(Nt2=Nt1*lamb) (Nt3=Nt2*lamb) (Nt4=Nt3*lamb)
Note that:
This recursive equation can be written as:
$$N_{T}=\lambda^T N_0 $$
Let's take our previous example and design it for 10 time cycles.
N0=100 lamb=1+(0.8-0.75) tmax=10 tseq=0:tmax Nseq=N0*lamb^tseq Nseq plot(tseq, Nseq, type="l")
Let's now explore the initial population size.
tseq=0:10 lamb=1.5 N0=c(10,20,30,40) N0.mat=matrix(N0, ncol=length(tseq), nrow=length(N0)) N0.mat lamb_t=lamb^tseq lambt_mat=matrix(lamb_t,ncol=length(tseq), nrow=length(N0), byrow=TRUE) Nt=N0.mat*lambt_mat colnames(Nt)<-paste("t", 0:10, sep="") rownames(Nt)<-paste("N0", c(10,20,30,40), sep="_") nt matplot(0:10,t(Nt))
Let's now put the same graph on a logarithmic scale for the y-axis.
par(mfrow=c(1,2)) matplot(0:10,t(Nt)) matplot(0:10, t(Nt), log="y")
What's up?? It seems that all populations grow equally when we are on a logarithmic scale! Let's investigate the equation we are using, $N_t=\lambda^T N_0$ and take the log of both sides of the equation:
This equation resembles an equation of the line $ y=ax+b $, where the intercept is $log(N_0)$ and the slope is equal to $log{\lambda}$.
We will now investigate the population size data of a North American sparrow species (Melopiza melody) starting from the premise that this population grows in discrete time, since births occur in a short period of nesting time every year.
The graph represents the singing sparrow count in the city of Darrtown, OH, USA. Download the data from the file pardal.txt on your computer.
Let's calculate the $\lambda$ for the first five intervals:
sparrow<-read.table("sparrow.txt", header=TRUE, sep="\t", as.is=TRUE) str(sparrow) head(sparrow) sparrow6= sparrow[1:6,] plot(sparrow6$Count ~sparrow6$Year) lamb_pardal=pardal6$Count[2:6]/pardal6$Count[1:5] lamb_sparrow
Now, let's calculate the population projection by the arithmetic and geometric mean of the $\lambda$ and draw the projections along with the observed data!
#arithmetic average (lamb.art = mean(lamb_pardal)) #geometric average (lamb.geo = prod(lamb_pardal)^(1/5)) tseq=0:5 plot(tseq, sparrow6$Count, pch=19) N0=sparrow6$Count[1] lines(tseq, N0*lamb.art^tseq, lty=2, col="red") lines(tseq, N0*lamb.geo^tseq, lty=3, col="blue")
Below is the code of a base function for projecting the growth of a population, which can be used as a basic structure for other functions that we will develop in the course. In this case, it is a function with 3 arguments: number of individuals at time 0 (N0), population growth rate (lamb) and maximum time (tmax) of population projection.
cresc.geom= function(No=100, lamb=1.04, tmax=10) { result <- rep(NA,tmax) result[1] <- No for (i in 2:tmax) { tam=result[i-1]*lamb result[i]=tam } return(result) }
By copying this code to the R desktop, a new object is created, named cresc.geom. It is an object of the function class that you can use it by typing its name and specifying its arguments, as in the following example:
result <- cresc.geom(No=10, lamb=0.98, tmax=100)
Note that the result of the function, in this case, will be stored in the object result. To graph the results you can use the code below:
plot(1:length(result), result)
Environmental fluctuations can have an effect on the instantaneous population growth rate. In a simple way, we can imagine that this variation works like a noise in r, as if the population on average had a rate, but at each realization it could be somewhat different due to conditions external to itself. The implementation of this environmental stochasticity in continuous models is a little more complicated, but we can imagine it as realizations in some small time interval. For a discrete growth, the construction of simulations with environmental stochasticity is more intuitive: at each realization the Lambda is affected by the environmental variation. Let's do it.
npop=10 n0=10 lamb.med = 1.2 lamb.sd= 0.4 lamb = rnorm(npop, mean=lamb.med, sd=lamb.sd) N0=rep(n0,npop) N1=lamb*N0 lamb=rnorm(npop, mean=lamb.med, sd=lamb.sd) N2=N1*lamb N3=N2*rnorm(npop,mean=lamb.med,sd=lamb.sd) N4=N3*rnorm(10,mean=lamb.med,sd=lamb.sd) N5=N4*rnorm(10,mean=lamb.med,sd=lamb.sd) Nt<-rbind(N0,N1,N2,N3,N4,N5) matplot(0:5, Nt, type="l", lty=2:7)
It is possible to adapt our previous discrete growth function so that it can also model populations with environmental stochasticity!
Tips