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):
model=lmer(resp2~1+elevation+slope+(1|stand))
summary(model)
## 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
From the result, the estimated beta2 is close to initial parameters. The estimated beta0 as well as beta1 is far from initial parameter.
myfunction=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)
resp2=b0+b1*elevation+b2*slope+standeff+ploteff
data1=data.frame(resp2,elevation,slope,stand)
lmer(resp2~1+elevation+slope+(1|stand),data=data1)
}
myfunction()
## Linear mixed model fit by REML ['lmerMod']
## Formula: resp2 ~ 1 + elevation + slope + (1 | stand)
## Data: data1
## REML criterion at convergence: 80.9781
## Random effects:
## Groups Name Std.Dev.
## stand (Intercept) 2.3573
## Residual 0.9754
## Number of obs: 20, groups: stand, 5
## Fixed Effects:
## (Intercept) elevation slope
## 10.584601 -0.005464 0.086839
simulation=replicate(n=1000,expr=myfunction())
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00350333
## (tol = 0.002, component 1)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00455142
## (tol = 0.002, component 1)
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.0036354
## (tol = 0.002, component 1)
## boundary (singular) fit: see ?isSingular
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00439557
## (tol = 0.002, component 1)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00239512
## (tol = 0.002, component 1)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00219495
## (tol = 0.002, component 1)
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00322495
## (tol = 0.002, component 1)
## boundary (singular) fit: see ?isSingular
variances=simulation %>% map_dfr(tidy,effects="ran_pars",scales="vcov")
variances[1:6,]
## # A tibble: 6 x 3
## term group estimate
## <chr> <chr> <dbl>
## 1 var_(Intercept).stand stand 2.61
## 2 var_Observation.Residual Residual 1.11
## 3 var_(Intercept).stand stand 9.73
## 4 var_Observation.Residual Residual 1.36
## 5 var_(Intercept).stand stand 0.827
## 6 var_Observation.Residual Residual 0.914
plan(multiprocess)
stand_sim=c(5, 50, 100) %>%
set_names(c("size_5","size_50","size_100")) %>%
future_map(function(.size)replicate(n=1000,expr=myfunction(nstand=.size)))
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00290078
## (tol = 0.002, component 1)
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00306721
## (tol = 0.002, component 1)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.0062793
## (tol = 0.002, component 1)
## boundary (singular) fit: see ?isSingular
## boundary (singular) fit: see ?isSingular
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00504501
## (tol = 0.002, component 1)
## 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
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00211455
## (tol = 0.002, component 1)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00206189
## (tol = 0.002, component 1)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00205707
## (tol = 0.002, component 1)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00209298
## (tol = 0.002, component 1)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00201666
## (tol = 0.002, component 1)
## Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl =
## control$checkConv, : Model failed to converge with max|grad| = 0.00210085
## (tol = 0.002, component 1)
stand_var=stand_sim %>%
modify_depth(2,~tidy(.x,effects="ran_pars",scales="vcov")) %>%
map_dfr(bind_rows,.id="stand_num") %>%
filter(group=="stand")
stand_var
## # A tibble: 3,000 x 4
## stand_num term group estimate
## <chr> <chr> <chr> <dbl>
## 1 size_5 var_(Intercept).stand stand 6.53
## 2 size_5 var_(Intercept).stand stand 0.657
## 3 size_5 var_(Intercept).stand stand 3.44
## 4 size_5 var_(Intercept).stand stand 5.34
## 5 size_5 var_(Intercept).stand stand 4.65
## 6 size_5 var_(Intercept).stand stand 0.234
## 7 size_5 var_(Intercept).stand stand 1.21
## 8 size_5 var_(Intercept).stand stand 2.55
## 9 size_5 var_(Intercept).stand stand 0.660
## 10 size_5 var_(Intercept).stand stand 0.993
## # ... with 2,990 more rows
ggplot(stand_var,aes(x=estimate))+
geom_density(fill="red",alpha=.25)+
facet_wrap(~stand_num)+
geom_vline(xintercept=4)
From the result, variance decreases when sample size increases (from 5 to 50 to 100).
coef=simulation %>%
map_dfr(tidy,effects="fixed") %>%
filter(term %in% c("elevation","slope"))
coef
## # A tibble: 2,000 x 4
## term estimate std.error statistic
## <chr> <dbl> <dbl> <dbl>
## 1 elevation 0.0152 0.00426 3.57
## 2 slope 0.121 0.0157 7.73
## 3 elevation 0.0156 0.0117 1.33
## 4 slope 0.124 0.0166 7.48
## 5 elevation 0.0130 0.00336 3.87
## 6 slope 0.0937 0.0100 9.32
## 7 elevation 0.0135 0.0157 0.856
## 8 slope 0.0767 0.0152 5.05
## 9 elevation -0.0235 0.0132 -1.78
## 10 slope 0.127 0.0106 12.0
## # ... with 1,990 more rows
coef %>%
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_line()+
facet_wrap(~term)+
geom_hline(aes(yintercept=real_value,color=term),linetype=4,size=0.5)+
theme_bw()
The plot shows the estimated coefficients are around 0.0047 (red line) and 0.0998 (green line). These are close to the initial parameters of 0.005 and 0.1 respectively. Each vertical line indicates one estimated coefficients beta1 and beta2 in each plot. These are around the line but are scattered, meaning the model might not fit well.