Make data vectors, calculate lambda, and put together dataframe with all necessary data.
The census period; an index from 1 to 39 of how many years of data have been collected.
census <- 1:39
census <- c(1:39)
census <- seq(1, 39)
census <- seq(1, 39, by = 1)
The year: 1959 to 1997 (Dennis et al use 1959-1987)
year.t <- 1959:1997
year.t <- seq(1959, 1997)
Population size is recorded as the number of females with …
females.N <- c(44,47,46,44,46,
45,46,40,39,39,
42,39,41,40,33,
36,34,39,35,34,
38,36,37,41,39,
51,47,57,48,60,
65,74,69,65,57,
70,81,99,99)
Population growth rate is…
Enter the population size for each year
females.N.1959 <- 44
females.N.1960 <- 47
Calculate the ratio of the 2 population sizes
lambda.59_60 <- females.N.1960/females.N.1959
Access the population sizes by using bracket notation rather than hard coding
# Access the data
females.N[1]
#> [1] 44
females.N[2]
#> [1] 47
# store in objects
females.N.1959 <- females.N[1]
females.N.1960 <- females.N[2]
# confirm the output
females.N.1960/females.N.1959
#> [1] 1.068182
Calculate lambda using bracket notation
lambda.59_60 <- females.N[2]/females.N[1]
The first year of data is 1959. What is lambda for 1958 to 1959?
No date is given for 1958, so this cannot be calculated
females.N[1]
#> [1] 44
lambda.58_59 <- females.N[1]/females.N[ ]
TASK
Briefly describe (1-2 sentence) what this code is doing.
This code is calculating lambdas between the first three index values of the female population size vector.
females.N[2:3]
#> [1] 47 46
females.N[1:2]
#> [1] 44 47
females.N[2:3]/females.N[1:2]
#> [1] 1.0681818 0.9787234
This is similar t the previous code chunk, just using all of the data (no need to describe)
length(females.N)
#> [1] 39
females.N[2:39]/females.N[1:38]
#> [1] 1.0681818 0.9787234 0.9565217 1.0454545 0.9782609 1.0222222 0.8695652
#> [8] 0.9750000 1.0000000 1.0769231 0.9285714 1.0512821 0.9756098 0.8250000
#> [15] 1.0909091 0.9444444 1.1470588 0.8974359 0.9714286 1.1176471 0.9473684
#> [22] 1.0277778 1.1081081 0.9512195 1.3076923 0.9215686 1.2127660 0.8421053
#> [29] 1.2500000 1.0833333 1.1384615 0.9324324 0.9420290 0.8769231 1.2280702
#> [36] 1.1571429 1.2222222 1.0000000
TASK What does this do? Briefly describe in 1 to 2 sentences why I am using length().
The length function in the first line finds the total number of elements in the vector. The second line is used to find the lambdas between the values in the entirety of the vector.
len <- length(females.N)
females.N[2:len]/females.N[1:len-1]
#> [1] 1.0681818 0.9787234 0.9565217 1.0454545 0.9782609 1.0222222 0.8695652
#> [8] 0.9750000 1.0000000 1.0769231 0.9285714 1.0512821 0.9756098 0.8250000
#> [15] 1.0909091 0.9444444 1.1470588 0.8974359 0.9714286 1.1176471 0.9473684
#> [22] 1.0277778 1.1081081 0.9512195 1.3076923 0.9215686 1.2127660 0.8421053
#> [29] 1.2500000 1.0833333 1.1384615 0.9324324 0.9420290 0.8769231 1.2280702
#> [36] 1.1571429 1.2222222 1.0000000
TASK What does this do? Briefly describe in 1 to 2 sentences what is different about this code chunk from the previous one.
This code is also used to find lambdas between values in the entirety of the vector. The difference is that length(females.N) is not set to a variable len, as done in the previous code.
females.N[2:length(females.N)]/females.N[1:length(females.N)-1]
#> [1] 1.0681818 0.9787234 0.9565217 1.0454545 0.9782609 1.0222222 0.8695652
#> [8] 0.9750000 1.0000000 1.0769231 0.9285714 1.0512821 0.9756098 0.8250000
#> [15] 1.0909091 0.9444444 1.1470588 0.8974359 0.9714286 1.1176471 0.9473684
#> [22] 1.0277778 1.1081081 0.9512195 1.3076923 0.9215686 1.2127660 0.8421053
#> [29] 1.2500000 1.0833333 1.1384615 0.9324324 0.9420290 0.8769231 1.2280702
#> [36] 1.1571429 1.2222222 1.0000000
Make a short vector to play with; first 10 years
females.N[1:10]
#> [1] 44 47 46 44 46 45 46 40 39 39
females.Ntemp <- females.N[seq(1,10)]
Check - are there 10 numbers
length(females.Ntemp)
#> [1] 10
TASK
What does this do? Briefly describe what the [-1] is doing.
The negative index strips the member whose position has the same absolute value as the negative index (in this case, index 1).
females.Ntemp[-1]
#> [1] 47 46 44 46 45 46 40 39 39
TASK How many lambdas can I calculate using the first 10 years of data?
9 lambdas
females.Ntemp[2:10]/females.Ntemp[1:9]
#> [1] 1.0681818 0.9787234 0.9565217 1.0454545 0.9782609 1.0222222 0.8695652
#> [8] 0.9750000 1.0000000
“Negative indexing” allows you to drop a specific element from a vector.
TASK Drop the the first element
females.Ntemp[-1]
#> [1] 47 46 44 46 45 46 40 39 39
TASK Drop the second element
females.Ntemp[-2]
#> [1] 44 46 44 46 45 46 40 39 39
TASK
How do you drop the 10th element? Type in the code below.
females.Ntemp[-10]
#> [1] 44 47 46 44 46 45 46 40 39
TASK How do you access the last element? Do this in a general way without hard-coding.
females.Ntemp[length(females.Ntemp)]
#> [1] 39
TASK How do DROP the last element? Do this in a general way without hard-coding. By general, I mean in a way that if the length of the vector females.Ntemp changed the code would still drop the correct element.
females.Ntemp[-length(females.Ntemp)]
#> [1] 44 47 46 44 46 45 46 40 39
TASK Calculate the first 9 lambdas.
lambda.i <- females.Ntemp[-1]/females.Ntemp[-10]
Converting between these 2 code chunks would be a good test question : )
lambda.i <- females.Ntemp[-1]/females.Ntemp[-length(females.Ntemp)]
TASK
Below each bulleted line describe what the parts of the code do. Run the code to test it.
What does females.N[-1] do? Drops the first element
What does females.N[-length(females.N)? Drops the very last element
TASK Calculate lambdas for all of the data
females.N[-1]
#> [1] 47 46 44 46 45 46 40 39 39 42 39 41 40 33 36 34 39 35 34 38 36 37 41 39 51
#> [26] 47 57 48 60 65 74 69 65 57 70 81 99 99
females.N[-length(females.N)]
#> [1] 44 47 46 44 46 45 46 40 39 39 42 39 41 40 33 36 34 39 35 34 38 36 37 41 39
#> [26] 51 47 57 48 60 65 74 69 65 57 70 81 99
lambda.i <- females.N[-1]/females.N[-length(females.N)]
TASK
What does this code do? Why do I include NA in the code? (I didn’t cover this in lecture, so just type 1 line - your best guess. “I don’t know” is fine.)
I don’t know
lambda.i <- c(lambda.i,NA)
TASK
Check the help file; what type of log does log() calculate (I forgot to put this question on the test!)
base 10 logarithms
lambda_log <- log(lambda.i)
bear_N <- data.frame(census,
year.t,
females.N,
lambda.i,
lambda_log)
TASK
List 3 functions that allow you to examine this dataframe.
1.summary() 2.str() 3.dim()
TASK
plot(females.N ~ year.t, data = bear_N,
type = "b",
ylab = "Population index (females + cubs)",
xlab = "Year")
Bears love to eat trash. Yellowstone closed the last garbage dump in 1970 https://www.yellowstonepark.com/things-to-do/yellowstone-bears-no-longer-get-garbage-treats
census <- 1:39
year.t <- 1959:1997
females.N <- c(44,47,46,44,46,
45,46,40,39,39,
42,39,41,40,33,
36,34,39,35,34,
38,36,37,41,39,
51,47,57,48,60,
65,74,69,65,57,
70,81,99,99)
lambda.i <- females.N[-1]/females.N[-length(females.N)]
lambda.i <- c(lambda.i,NA)
lambda_log <- log(lambda.i)
plot(females.N ~ year.t, data = bear_N,
type = "b",
ylab = "Population index (females + cubs)",
xlab = "Year")
abline(v = 1970)
ADD 1-2 sentences note here
To model population dynamics we randomly pull population growth rates out of a hat.
hat_of_lambdas <- bear_N$lambda.i
is.na(hat_of_lambdas)
#> [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#> [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#> [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#> [37] FALSE FALSE TRUE
any(is.na(hat_of_lambdas) == TRUE)
#> [1] TRUE
Drop the NA
length(hat_of_lambdas)
#> [1] 39
hat_of_lambdas[39]
#> [1] NA
hat_of_lambdas[-39]
#> [1] 1.0681818 0.9787234 0.9565217 1.0454545 0.9782609 1.0222222 0.8695652
#> [8] 0.9750000 1.0000000 1.0769231 0.9285714 1.0512821 0.9756098 0.8250000
#> [15] 1.0909091 0.9444444 1.1470588 0.8974359 0.9714286 1.1176471 0.9473684
#> [22] 1.0277778 1.1081081 0.9512195 1.3076923 0.9215686 1.2127660 0.8421053
#> [29] 1.2500000 1.0833333 1.1384615 0.9324324 0.9420290 0.8769231 1.2280702
#> [36] 1.1571429 1.2222222 1.0000000
hat_of_lambdas[-length(hat_of_lambdas)]
#> [1] 1.0681818 0.9787234 0.9565217 1.0454545 0.9782609 1.0222222 0.8695652
#> [8] 0.9750000 1.0000000 1.0769231 0.9285714 1.0512821 0.9756098 0.8250000
#> [15] 1.0909091 0.9444444 1.1470588 0.8974359 0.9714286 1.1176471 0.9473684
#> [22] 1.0277778 1.1081081 0.9512195 1.3076923 0.9215686 1.2127660 0.8421053
#> [29] 1.2500000 1.0833333 1.1384615 0.9324324 0.9420290 0.8769231 1.2280702
#> [36] 1.1571429 1.2222222 1.0000000
na.omit(hat_of_lambdas)
#> [1] 1.0681818 0.9787234 0.9565217 1.0454545 0.9782609 1.0222222 0.8695652
#> [8] 0.9750000 1.0000000 1.0769231 0.9285714 1.0512821 0.9756098 0.8250000
#> [15] 1.0909091 0.9444444 1.1470588 0.8974359 0.9714286 1.1176471 0.9473684
#> [22] 1.0277778 1.1081081 0.9512195 1.3076923 0.9215686 1.2127660 0.8421053
#> [29] 1.2500000 1.0833333 1.1384615 0.9324324 0.9420290 0.8769231 1.2280702
#> [36] 1.1571429 1.2222222 1.0000000
#> attr(,"na.action")
#> [1] 39
#> attr(,"class")
#> [1] "omit"
hat_of_lambdas <- hat_of_lambdas[-length(hat_of_lambdas)]
hist(hat_of_lambdas)
The following code deals with extracting random lambda values and saving them to the object. The lambdas are recycled after every extraction.
# pulled a lambda from the hat
sample(x = hat_of_lambdas, size = 1,replace = TRUE)
#> [1] 0.9714286
#pulled lambda from hat and saved to object
lambda_rand.t <- sample(x = hat_of_lambdas, size = 1,replace = TRUE)
This code consists of setting up aspects of population simulation.
head(bear_N)
#> census year.t females.N lambda.i lambda_log
#> 1 1 1959 44 1.0681818 0.06595797
#> 2 2 1960 47 0.9787234 -0.02150621
#> 3 3 1961 46 0.9565217 -0.04445176
#> 4 4 1962 44 1.0454545 0.04445176
#> 5 5 1963 46 0.9782609 -0.02197891
#> 6 6 1964 45 1.0222222 0.02197891
tail(bear_N)
#> census year.t females.N lambda.i lambda_log
#> 34 34 1992 65 0.8769231 -0.1313360
#> 35 35 1993 57 1.2280702 0.2054440
#> 36 36 1994 70 1.1571429 0.1459539
#> 37 37 1995 81 1.2222222 0.2006707
#> 38 38 1996 99 1.0000000 0.0000000
#> 39 39 1997 99 NA NA
N.1997 <- 99
This code is predicting the number of bears the following year.
1.22807*99
#> [1] 121.5789
lambda_rand.t*N.1997
#> [1] 86.08696
N.1998 <- lambda_rand.t*N.1997
We are doing a simulation almost like how it is done in Excel, but only worse
#1997 to 1998
lambda_rand.t <- sample(x = hat_of_lambdas, size = 1,replace = TRUE)
N.1998 <- lambda_rand.t*N.1997
#1998 to 1999
lambda_rand.t <- sample(x = hat_of_lambdas, size = 1,replace = TRUE)
N.1999 <- lambda_rand.t*N.1998
#1999 to 2000
lambda_rand.t <- sample(x = hat_of_lambdas, size = 1,replace = TRUE)
N.2000 <- lambda_rand.t*N.1999
#2000 to 2001
lambda_rand.t <- sample(x = hat_of_lambdas, size = 1,replace = TRUE)
N.2001 <- lambda_rand.t*N.2000
#2001 to 2002
lambda_rand.t <- sample(x = hat_of_lambdas, size = 1,replace = TRUE)
N.2002 <- lambda_rand.t*N.2001
#2002 to 2003
lambda_rand.t <- sample(x = hat_of_lambdas, size = 1,replace = TRUE)
N.2003 <- lambda_rand.t*N.2002
#2003 to 2004
lambda_rand.t <- sample(x = hat_of_lambdas, size = 1,replace = TRUE)
N.2004 <- lambda_rand.t*N.2003
#2004 to 2005
lambda_rand.t <- sample(x = hat_of_lambdas, size = 1,replace = TRUE)
N.2005 <- lambda_rand.t*N.2004
Population change is demonstrated through for loops.
year <- seq(1997, 2004)
N.rand <- c(N.1998,N.1999,N.2000,N.2001,N.2002,N.2003,N.2004,N.2005)
df.rand <- data.frame(N.rand, year)
plot(N.rand ~ year, data = df.rand, type = "b")
We are setting initial conditions, xlim and ylim, and a for loop
# initial conditions
N.1997 <- 99
N.initial <- 99
# exploring xlim = argument
plot(N.1997 ~ c(1997))
plot(N.1997 ~ c(1997), xlim = c(1997, 1997+50))
#xlim and ylim
plot(N.1997 ~ c(1997), xlim = c(1997, 1997+50), ylim = c(0, 550))
# not a for() loop for loop
# for loop the difficult way
N.current <- N.initial
# where the for () loop would be
t <- 1
# grab lambda
lambda_rand.t <- sample(x = hat_of_lambdas, size = 1,replace = TRUE)
# determine population size
N.t <- N.current*lambda_rand.t
# calculating the next year
year.t <- 1997+t
# plotting the population
points(N.t ~ year.t)
# update N.current
N.current <- N.t
Randomly Finding Population Size and Plotting
#make a new plot with starting population size
plot(N.1997 ~ c(1997), xlim = c(1997, 1997+50), ylim = c(0, 550))
#start at 1997's population size
N.current <- N.1997
# time 1 to time 50, iterating by 1 and grabbing random lambdas
for(t in 1:50){
# grab lambda
lambda_rand.t <- sample(x = hat_of_lambdas,
size = 1,
replace = TRUE)
# determine population size
N.t <- N.current*lambda_rand.t
# calculating the next year
year.t <- 1997+t
# plotting the population
points(N.t ~ year.t)
#update N.current
N.current <- N.t
}
R plotting code— 3 by 3 panel of graphs
par(mfrow = c(3,3), mar = c(1,1,1,1))
Using a for() loop to find random lambdas
plot(N.1997 ~ c(1997), xlim = c(1997, 1997+50), ylim = c(0, 550))
N.current <- N.1997
for(t in 1:50){
lambda_rand.t <- sample(x = hat_of_lambdas,
size = 1,
replace = TRUE)
N.t <- N.current*lambda_rand.t
year.t <- 1997+t
points(N.t ~ year.t)
N.current <- N.t
}