The statistical model:
\(y_t = \beta_0 + \beta_1 * (Elevation_s)_t + \beta_2 * Slope_t + (b_s)_t + \epsilon_t\)
Where:
Let’s define the parameters:
nstand = 5
nplot = 4
b0 = -1
b1 = .005
b2 = .1
sds = 2
sd = 1
Simulate other variables:
set.seed(16)
stand = rep(LETTERS[1:nstand], each = nplot)
standeff = rep( rnorm(nstand, 0, sds), each = nplot)
ploteff = rnorm(nstand*nplot, 0, sd)
Simulate elevation and slope:
elevation = rep( runif(nstand, 1000, 1500), each = nplot)
slope = runif(nstand*nplot, 2, 75)
Simulate response variable:
resp2 = b0 + b1*elevation + b2*slope + standeff + ploteff
Your tasks (complete each task in its’ own code chunk, make sure to use echo=TRUE so I can see your code):
# use this chunk to answer question 1
#install.packages('lme4')
library(lme4)
## Loading required package: Matrix
fit1=lmer(resp2 ~ 1 + elevation + slope + (1|stand))
summary(fit1)
## Linear mixed model fit by REML ['lmerMod']
## Formula: resp2 ~ 1 + elevation + slope + (1 | stand)
##
## REML criterion at convergence: 82
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.65583 -0.62467 -0.01693 0.53669 1.41736
##
## Random effects:
## Groups Name Variance Std.Dev.
## stand (Intercept) 1.208 1.099
## Residual 1.358 1.165
## Number of obs: 20, groups: stand, 5
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) -21.314628 6.602053 -3.228
## elevation 0.020600 0.004916 4.190
## slope 0.095105 0.016441 5.785
##
## Correlation of Fixed Effects:
## (Intr) elevtn
## elevation -0.991
## slope 0.049 -0.148
fit1
## Linear mixed model fit by REML ['lmerMod']
## Formula: resp2 ~ 1 + elevation + slope + (1 | stand)
## REML criterion at convergence: 81.9874
## Random effects:
## Groups Name Std.Dev.
## stand (Intercept) 1.099
## Residual 1.165
## Number of obs: 20, groups: stand, 5
## Fixed Effects:
## (Intercept) elevation slope
## -21.31463 0.02060 0.09511
#The intercept is -21.31 which is far from b0(-1). The elevation is 0.02, also different from b1(0.005). The slop is 0.095 which is similar to b2(0.1). The standard deviation is 1.099 which is different from our preset value 2. The residual is 1.17 which is close to our preset value 1.
# use this chunk to answer question 2
library(lme4)
fun1= function(nstand = 5, nplot = 4, b0 = -1, b1 = 0.005, b2 = 0.1, sds = 2, sd = 1) {
stand = rep(LETTERS[1:nstand], each = nplot)
standeff = rep(rnorm(nstand, 0, sds), each = nplot)
ploteff = rnorm(nstand * nplot, 0, sd)
elevation = rep(runif(nstand, 1000, 1500), each = nplot)
slope = runif(nstand * nplot, 2, 75)
resp = b0 + b1 * elevation + b2 * slope + standeff + ploteff
dat = data.frame(resp, elevation, slope, stand)
lmer(resp ~ 1 + elevation + slope + (1|stand), data = dat)
}
set.seed(16)
fun1()
## Linear mixed model fit by REML ['lmerMod']
## Formula: resp ~ 1 + elevation + slope + (1 | stand)
## Data: dat
## REML criterion at convergence: 81.9874
## Random effects:
## Groups Name Std.Dev.
## stand (Intercept) 1.099
## Residual 1.165
## Number of obs: 20, groups: stand, 5
## Fixed Effects:
## (Intercept) elevation slope
## -21.31463 0.02060 0.09511
simsmix=replicate(1000,fun1())
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
# use this chunk to answer question 3
#install.packages('tidyverse')
library('tidyverse')
## -- Attaching packages --------------------------------------- tidyverse 1.3.0 --
## √ ggplot2 3.3.0 √ purrr 0.3.3
## √ tibble 2.1.3 √ dplyr 0.8.5
## √ tidyr 1.0.2 √ stringr 1.4.0
## √ readr 1.3.1 √ forcats 0.5.0
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x tidyr::expand() masks Matrix::expand()
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
## x tidyr::pack() masks Matrix::pack()
## x tidyr::unpack() masks Matrix::unpack()
#install.packages('purrr')
library('purrr')
#install.packages('broom')
library('broom')
variances = simsmix %>% map_dfr(tidy, effects = "ran_pars", scales = "vcov")
head(variances,n=6)
## # A tibble: 6 x 3
## term group estimate
## <chr> <chr> <dbl>
## 1 var_(Intercept).stand stand 5.56
## 2 var_Observation.Residual Residual 0.951
## 3 var_(Intercept).stand stand 2.61
## 4 var_Observation.Residual Residual 1.11
## 5 var_(Intercept).stand stand 9.73
## 6 var_Observation.Residual Residual 1.36
# use this chunk to answer question 4
library(ggplot2)
library(dplyr)
stand_sims = c(5, 20, 100) %>%
set_names() %>%
map(~replicate(1000, fun1(nstand = .x)))
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
add_prefix = function(string) {
paste("Number Samples:", string, sep = " ")
}
stand_vars = stand_sims %>%
modify_depth(2, ~tidy(.x, effects = "ran_pars", scales = "vcov")) %>%
map_dfr(bind_rows, .id = "id")%>%
filter(group == "stand")
ggplot(stand_vars, aes(x = estimate)) +
geom_density(fill = "green", alpha = 0.25) +
facet_wrap(~id, labeller = as_labeller(add_prefix) ) +
geom_vline(xintercept = 4)
#We can clearly tell that the size of samples can affect the variance. The more samples we use, the less variance we have.
# use this chunk to answer question 5
#install.packages('furrr')
library('furrr')
## Loading required package: future
library('dplyr')
est_e_s <- simsmix %>% future_map(tidy, effects = "fixed")%>%bind_rows()
est_e_s %>%
dplyr::filter(term %in% c("elevation", "slope")) %>%
group_by(term) %>%
mutate(x = 1 : 1000) %>%
ungroup() %>%
mutate(real_value = ifelse(term == "elevation", 0.005, 0.1)) %>%
ggplot(aes(x = x, y = estimate)) +
geom_point()+
facet_wrap(~term) +
geom_hline(aes(yintercept = real_value, color = term), linetype = 4, size = 0.5)
# the elevation is around 0.005 and slop is around 0.1 which is very close to our preset values. And most of the data points are within a reasonable range.