Exploratory analyses

Data amount: all

Author

Brunno Oliveira & Bioshifts working group

1 Setup

# rm(list=ls())
# gc()

library(dplyr)
library(tidyverse)
library(tidyr)
library(ggplot2)
library(knitr)
library(pbapply)
library(data.table)
library(GGally)
library(here)
library(terra)
library(tidyterra)
library(rcompanion)
library(lme4)
library(glmmTMB)
library(MuMIn)
library(emmeans)
library(parallel)
library(sjPlot)
library(jtools)
library(deming)
library(cowplot)
library(DescTools)
library(gtools)
library(ggpp)

computer = "personal"
source(here("R/settings.R"))
source(here("R/my_functions.R"))
source(here("R/velocity_functions.R"))
source(here("R/emm_extra_functions.R"))

options(na.action = "na.fail")

2 Load data

# data amount
if(params$data_amount=="all"){
  
  bioshifts <- read.csv(here("Data/Output/Bioshifts_merge_Exposure_all.csv"))
  
} else {
  
  bioshifts <- read.csv(here("Data/Output/Bioshifts_merge_Exposure.csv"))
  
}
# select classes with more than X observations per edge
N_obs_class = 5
class_param_select <- bioshifts %>%
  group_by(class, Param) %>%
  tally() %>%
  filter(n >= N_obs_class) %>%
  mutate(class_param = paste(class,Param))

bioshifts <- bioshifts %>% 
  mutate(class_param = paste(class,Param)) %>% 
  filter(class_param %in% class_param_select$class_param) %>%
  select(!class_param)
# N species
length(unique(bioshifts$sp_name_std))
[1] 3623
bioshifts %>% 
  group_by(Param) %>% 
  summarise(N=length(unique(sp_name_std)))
# A tibble: 3 × 2
  Param     N
  <chr> <int>
1 LE     1772
2 O      2647
3 TE      568
bioshifts %>% 
  group_by(Eco) %>% 
  summarise(N=length(unique(sp_name_std)))
# A tibble: 2 × 2
  Eco       N
  <chr> <int>
1 Mar     519
2 Ter    3104
bioshifts %>% 
  group_by(Eco,Param) %>% 
  summarise(N=length(unique(sp_name_std)))
`summarise()` has grouped output by 'Eco'. You can override using the `.groups`
argument.
# A tibble: 6 × 3
# Groups:   Eco [2]
  Eco   Param     N
  <chr> <chr> <int>
1 Mar   LE      206
2 Mar   O       388
3 Mar   TE       75
4 Ter   LE     1566
5 Ter   O      2259
6 Ter   TE      493
# N range shifts
length(bioshifts$sp_name_std)
[1] 9579
bioshifts %>% 
  group_by(Param) %>% 
  summarise(N=length(sp_name_std))
# A tibble: 3 × 2
  Param     N
  <chr> <int>
1 LE     2468
2 O      6351
3 TE      760
bioshifts %>% 
  group_by(Eco) %>%
  summarise(N=length(sp_name_std))
# A tibble: 2 × 2
  Eco       N
  <chr> <int>
1 Mar     937
2 Ter    8642
bioshifts %>% 
  group_by(Eco,Param) %>%
  summarise(N=length(sp_name_std))
`summarise()` has grouped output by 'Eco'. You can override using the `.groups`
argument.
# A tibble: 6 × 3
# Groups:   Eco [2]
  Eco   Param     N
  <chr> <chr> <int>
1 Mar   LE      211
2 Mar   O       650
3 Mar   TE       76
4 Ter   LE     2257
5 Ter   O      5701
6 Ter   TE      684

3 Make dataset for modeling

mod_data <- bioshifts %>%
  mutate(ShiftRate_raw = ShiftRate,
         ShiftMod_raw = bvel_lat,
         ShiftMod_raw95 = bvel95_lat,
         ShiftRate = scale(ShiftRate),
         ShiftMod = scale(bvel_lat),
         ShiftMod95 = scale(bvel95_lat),
         Lat_extent = scale(log(LatExtentk)),
         Study_duration = scale(Duration),
         TSS = scale(calibration),
         Interannual_var = scale(log1p(bvel_lat_error)),
         N_periods = scale(N_periodes),
         Connectivity = scale((connectivity)),
         match_direction = relevel(factor(match_direction), ref = "mismatch"),
         mismatch = abs(mismatch),
         Mobility = as.character(str_to_sentence(Mobility)),
         Locomotion_mode = as.character(str_to_sentence(Locomotion_mode)),
         Life_form = as.character(str_to_sentence(lifeform)),
         Match_dir = case_when(match_direction_class=="pospos" ~ "Poleward",
                               match_direction_class=="negneg" ~ "Equatorward",
                               match_direction == "mismatch" ~ "Mismatch"),
         mismatch_binary = case_when(match_direction=="mismatch" ~ 0,
                                     match_direction=="match" ~ 1),
         Sampling_category = Category,
         Random_ID_Param_Class = paste(ID,Param,class),
         Random_ID_Class = paste(ID,class),
         Random_Param_Class = paste(Param,class)) %>%
  select(ShiftRate_raw, ShiftMod_raw, ShiftMod_raw95, ShiftRate, ShiftMod, ShiftMod95,
         mismatch, match_direction, mismatch_binary, Match_dir, mismatch_trend,
         Lat_extent, Sampling_category, TSS, Interannual_var, N_periods, Study_duration,
         Life_form, Mobility, Locomotion_mode, Connectivity, 
         ID, Param, class, Eco, sp_name_std, 
         Random_ID_Param_Class, Random_Param_Class, Random_ID_Class)

Extra fixes for variables

# fixing Locomotion_mode
unique(mod_data$Locomotion_mode)
 [1] "Flying"             "Running/flying"     "Running"           
 [4] "Slithering"         "Swimming"           "Planktonic"        
 [7] "Crawling"           "Sessile"            "Swimming/walking"  
[10] "Walking/hopping"    "Walking"            "Burrowing"         
[13] "Swimming/burrowing"
pos <- grep("lying",mod_data$Locomotion_mode)
mod_data$Locomotion_mode[pos] <- "Flying"
pos <- grep("wimming",mod_data$Locomotion_mode)
mod_data$Locomotion_mode[pos] <- "Swimming"
pos <- grep("alk",mod_data$Locomotion_mode)
mod_data$Locomotion_mode[pos] <- "Run/Walk"
pos <- grep("unning",mod_data$Locomotion_mode)
mod_data$Locomotion_mode[pos] <- "Run/Walk"
pos <- grep("lithering",mod_data$Locomotion_mode)
mod_data$Locomotion_mode[pos] <- "Slithering/Crawling"
pos <- grep("rawling",mod_data$Locomotion_mode)
mod_data$Locomotion_mode[pos] <- "Slithering/Crawling"
pos <- grep("Burrowing",mod_data$Locomotion_mode)
mod_data$Locomotion_mode[pos] <- "Sessile"

unique(mod_data$Locomotion_mode)
[1] "Flying"              "Run/Walk"            "Slithering/Crawling"
[4] "Swimming"            "Planktonic"          "Sessile"            
mod_data$Locomotion_mode <- factor(
  mod_data$Locomotion_mode, 
  levels = c("Flying", "Run/Walk", "Swimming", "Slithering/Crawling",  "Planktonic", "Sessile"))

table(mod_data$Locomotion_mode[which(mod_data$Eco=="Ter")])

             Flying            Run/Walk            Swimming Slithering/Crawling 
               5477                  91                  12                  27 
         Planktonic             Sessile 
                  0                3035 
table(mod_data$Locomotion_mode[which(mod_data$Eco=="Mar")])

             Flying            Run/Walk            Swimming Slithering/Crawling 
                  0                   0                 794                  50 
         Planktonic             Sessile 
                 28                  65 
# fixing Sampling_category
table(mod_data$Sampling_category)

Census-Resurvey   CensusPeriods Survey-Resurvey       Synthesis      TimeSeries 
             34            6525            1010               4            2006 
# remove synthresis because there is a only a single study
mod_data <- mod_data %>% filter(!Sampling_category == "Synthesis")
# combine census-resurvey and survey-resurvey 
pos <- grep("Census-Resurvey",mod_data$Sampling_category)
mod_data$Sampling_category[pos] <- "Survey-Resurvey"
table(mod_data$Sampling_category)

  CensusPeriods Survey-Resurvey      TimeSeries 
           6525            1044            2006 
# Fix direction levels
mod_data$Match_dir <- factor(mod_data$Match_dir, levels = c("Poleward", "Equatorward", "Mismatch"))

table(mod_data$Mobility[which(mod_data$Eco=="Ter")])

 Mobile Sessile 
   5606    3032 
table(mod_data$Mobility[which(mod_data$Eco=="Mar")])

               Drift Facultatively mobile               Mobile 
                  28                   44                  842 
             Sessile 
                  23 
table(mod_data$Life_form[which(mod_data$Eco=="Ter")])

 Cryptogam  Ectotherm  Endotherm Phanerogam 
        94       1688       3918       2938 
table(mod_data$Life_form[which(mod_data$Eco=="Mar")])

Cryptogam Ectotherm Endotherm 
       45       884         8 
# N classes 
mod_data %>% 
  group_by(Eco) %>%
  summarise(N = length(unique(class)))
# A tibble: 2 × 2
  Eco       N
  <chr> <int>
1 Mar      15
2 Ter      10
# N studies 
mod_data %>% 
  group_by(Eco) %>%
  summarise(N = length(unique(ID)))
# A tibble: 2 × 2
  Eco       N
  <chr> <int>
1 Mar      44
2 Ter      94
# make numeric as.numeric
pos <- which(sapply(mod_data, is.numeric))
tmp <- lapply(mod_data[pos], as.numeric)
tmp <- do.call(cbind,tmp)
mod_data[pos] <- tmp

4 Check for correlations

4.1 Scatters

# is Study_duration correlated with range shift mismatch?
ggplot(mod_data, aes(Study_duration,mismatch))+
  geom_point()+
  theme_classic()+
  geom_smooth()+
  facet_wrap(.~Eco)
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

# is NPeriods correlated with range shift mismatch?
ggplot(mod_data, aes((N_periods),mismatch))+
  geom_point()+
  theme_classic()+
  geom_smooth()+
  facet_wrap(.~Eco)
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

# is env variability correlated with range shift mismatch?
ggplot(mod_data, aes(Interannual_var,mismatch))+
  geom_point()+
  theme_classic()+
  geom_smooth()+
  facet_wrap(.~Eco)
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

# is NPeriods correlated with Study_duration?
ggplot(mod_data, aes((N_periods),Study_duration))+
  geom_point()+
  theme_classic()+
  geom_smooth()+
  facet_wrap(.~Eco)
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

# is NPeriods correlated with Sampling_category?
ggplot(mod_data, aes(Sampling_category,(N_periods)))+
  geom_point()+
  theme_classic()+
  geom_smooth()+
  facet_wrap(.~Eco)
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

# is Study_duration correlated with Sampling_category?
ggplot(mod_data, aes(Sampling_category,Study_duration))+
  geom_point()+
  theme_classic()+
  geom_smooth()+
  facet_wrap(.~Eco)
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

# is Study_duration correlated with env variability?
ggplot(mod_data, aes(Interannual_var,Study_duration))+
  geom_point()+
  theme_classic()+
  geom_smooth()+
  facet_wrap(.~Eco)
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

Removed N_periods as it is highly correlated with Sampling_category

5 VIF

5.1 Terrestrial

subdata_ter <- mod_data %>%
  filter(Eco=="Ter") %>%
  select("mismatch", "TSS", "Study_duration", "Interannual_var", "Lat_extent", "Connectivity", "Sampling_category", "Life_form", "Locomotion_mode") %>%
  na.omit

mm_formula_ter <- "mismatch ~ TSS + Study_duration + Interannual_var + Lat_extent + Connectivity + Sampling_category + Life_form + Locomotion_mode"

m1 <- glm(mm_formula_ter, 
          data = subdata_ter,
          family = Gamma(link = "log"))
summary(m1)

Call:
glm(formula = mm_formula_ter, family = Gamma(link = "log"), data = subdata_ter)

Coefficients: (1 not defined because of singularities)
                                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)                         0.14314    0.13441   1.065 0.286932    
TSS                                -0.04776    0.01584  -3.016 0.002571 ** 
Study_duration                     -0.24158    0.02010 -12.017  < 2e-16 ***
Interannual_var                     0.22560    0.01960  11.508  < 2e-16 ***
Lat_extent                          0.43081    0.02698  15.968  < 2e-16 ***
Connectivity                       -0.11750    0.01720  -6.830 9.04e-12 ***
Sampling_categorySurvey-Resurvey   -0.20582    0.05738  -3.587 0.000336 ***
Sampling_categoryTimeSeries        -0.08206    0.04638  -1.769 0.076873 .  
Life_formEctotherm                  0.80750    0.14125   5.717 1.12e-08 ***
Life_formEndotherm                  0.48740    0.13970   3.489 0.000488 ***
Life_formPhanerogam                -0.22967    0.13378  -1.717 0.086064 .  
Locomotion_modeRun/Walk            -0.49722    0.14027  -3.545 0.000395 ***
Locomotion_modeSwimming            -0.85041    0.37103  -2.292 0.021928 *  
Locomotion_modeSlithering/Crawling -0.07291    0.25403  -0.287 0.774096    
Locomotion_modeSessile                   NA         NA      NA       NA    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for Gamma family taken to be 1.618215)

    Null deviance: 18518  on 8603  degrees of freedom
Residual deviance: 12358  on 8590  degrees of freedom
AIC: 24224

Number of Fisher Scoring iterations: 8
# locomotion mode is problematic >> remove

mm_formula_ter <- "mismatch ~ TSS + Study_duration + Interannual_var + Lat_extent + Connectivity + Sampling_category + Life_form"

m1 <- glm(mm_formula_ter, 
          data = subdata_ter,
          family = Gamma(link = "log"))
summary(m1)

Call:
glm(formula = mm_formula_ter, family = Gamma(link = "log"), data = subdata_ter)

Coefficients:
                                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)                       0.14743    0.13385   1.102 0.270709    
TSS                              -0.04402    0.01575  -2.794 0.005220 ** 
Study_duration                   -0.25226    0.01990 -12.675  < 2e-16 ***
Interannual_var                   0.22450    0.01944  11.547  < 2e-16 ***
Lat_extent                        0.44050    0.02675  16.468  < 2e-16 ***
Connectivity                     -0.12090    0.01706  -7.085 1.50e-12 ***
Sampling_categorySurvey-Resurvey -0.18436    0.05606  -3.288 0.001011 ** 
Sampling_categoryTimeSeries      -0.07412    0.04598  -1.612 0.107022    
Life_formEctotherm                0.77679    0.14003   5.547 2.99e-08 ***
Life_formEndotherm                0.46906    0.13908   3.373 0.000748 ***
Life_formPhanerogam              -0.22572    0.13323  -1.694 0.090250 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for Gamma family taken to be 1.604798)

    Null deviance: 18518  on 8603  degrees of freedom
Residual deviance: 12382  on 8593  degrees of freedom
AIC: 24238

Number of Fisher Scoring iterations: 8
VIF(m1)
                      GVIF Df GVIF^(1/(2*Df))
TSS               1.232935  1        1.110376
Study_duration    2.236088  1        1.495356
Interannual_var   2.053056  1        1.432849
Lat_extent        3.912820  1        1.978085
Connectivity      1.560710  1        1.249284
Sampling_category 2.396487  2        1.244210
Life_form         4.416607  3        1.280899
# high VIF value for life form
# try keeping locomotion mode and removing life form

mm_formula_ter <- "mismatch ~ TSS + Study_duration + Interannual_var + Lat_extent + Connectivity + Sampling_category + Locomotion_mode"
m1 <- glm(mm_formula_ter, 
          data = subdata_ter,
          family = Gamma(link = "log"))
summary(m1)

Call:
glm(formula = mm_formula_ter, family = Gamma(link = "log"), data = subdata_ter)

Coefficients:
                                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)                         0.73919    0.02480  29.805  < 2e-16 ***
TSS                                -0.02997    0.01580  -1.897  0.05780 .  
Study_duration                     -0.19629    0.01793 -10.947  < 2e-16 ***
Interannual_var                     0.24505    0.01917  12.781  < 2e-16 ***
Lat_extent                          0.37246    0.02484  14.994  < 2e-16 ***
Connectivity                       -0.10212    0.01705  -5.988  2.2e-09 ***
Sampling_categorySurvey-Resurvey   -0.02824    0.04958  -0.570  0.56895    
Sampling_categoryTimeSeries        -0.10138    0.04638  -2.186  0.02885 *  
Locomotion_modeRun/Walk            -0.45106    0.13895  -3.246  0.00117 ** 
Locomotion_modeSwimming            -0.70875    0.37192  -1.906  0.05673 .  
Locomotion_modeSlithering/Crawling  0.10591    0.25237   0.420  0.67474    
Locomotion_modeSessile             -0.86913    0.04373 -19.873  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for Gamma family taken to be 1.630934)

    Null deviance: 18518  on 8603  degrees of freedom
Residual deviance: 12429  on 8592  degrees of freedom
AIC: 24280

Number of Fisher Scoring iterations: 8
VIF(m1) # Ok
                      GVIF Df GVIF^(1/(2*Df))
TSS               1.219583  1        1.104347
Study_duration    1.785977  1        1.336405
Interannual_var   1.964511  1        1.401610
Lat_extent        3.320521  1        1.822230
Connectivity      1.533969  1        1.238535
Sampling_category 1.764746  2        1.152579
Locomotion_mode   2.405843  4        1.115985

5.2 Marine

subdata_mar <- mod_data %>%
  filter(Eco=="Mar") %>%
  select("mismatch", "TSS", "Study_duration", "N_periods", "Interannual_var", "Lat_extent", "Sampling_category", "Life_form", "Locomotion_mode") %>%
  na.omit

mm_formula_mar <- "mismatch ~ TSS + Study_duration + Interannual_var + Lat_extent + Sampling_category + Life_form + Locomotion_mode"

m1 <- glm(mm_formula_mar, 
          data = subdata_mar,
          family = Gamma(link = "log"))
summary(m1)

Call:
glm(formula = mm_formula_mar, family = Gamma(link = "log"), data = subdata_mar)

Coefficients:
                                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)                        -0.13607    0.34325  -0.396  0.69190    
TSS                                 0.03874    0.03126   1.239  0.21549    
Study_duration                     -0.43185    0.08895  -4.855 1.41e-06 ***
Interannual_var                     0.13187    0.04804   2.745  0.00616 ** 
Lat_extent                          0.65795    0.05584  11.782  < 2e-16 ***
Sampling_categorySurvey-Resurvey   -0.16426    0.13620  -1.206  0.22812    
Sampling_categoryTimeSeries         0.25666    0.08830   2.907  0.00374 ** 
Life_formEctotherm                  1.33154    0.33919   3.926 9.29e-05 ***
Life_formEndotherm                  0.84553    0.52782   1.602  0.10952    
Locomotion_modeSlithering/Crawling -0.26091    0.17229  -1.514  0.13029    
Locomotion_modePlanktonic           0.94827    0.39571   2.396  0.01676 *  
Locomotion_modeSessile              0.32037    0.18420   1.739  0.08232 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for Gamma family taken to be 1.262171)

    Null deviance: 1615.7  on 936  degrees of freedom
Residual deviance: 1278.0  on 925  degrees of freedom
AIC: 4075.7

Number of Fisher Scoring iterations: 11
VIF(m1) # Ok!
                      GVIF Df GVIF^(1/(2*Df))
TSS               1.071991  1        1.035370
Study_duration    2.024081  1        1.422702
Interannual_var   1.529302  1        1.236649
Lat_extent        1.309589  1        1.144373
Sampling_category 2.079162  2        1.200804
Life_form         3.965445  2        1.411149
Locomotion_mode   4.799972  3        1.298793

6 Models

Set random and fixed effects

# Random effects

## Nested 
RE_nest <- "(1 | Param/class/ID)"
## custom 
RE_cust <- "(1 | Random_ID_Param_Class)"

########################

# fixed effects
cont_vars <- 
  c(
    "TSS",
    "Study_duration",
    "Interannual_var",
    "Lat_extent",
    "Connectivity"
  )
cont_vars_names <- 
  c(
    "SDM performance",
    "Study duration",
    "Climate variability",
    "Latitudinal extent",
    "Landscape connectivity"
  )

cat_vars <- c(
  "Life_form",
  "Sampling_category",
  "Locomotion_mode"
)
cat_names <- c(
  "Life form",
  "Sampling_category",
  "Locomotion mode"
)

6.1 Documented velocities in function of modeled velocities

6.1.1 Simple model - species-level (Shift ~ ShiftMod)

shiftmodtype <- ""
# shiftmodtype <- "95"

if(shiftmodtype=="95"){
  sm_fixed_eff <- "ShiftRate ~  ShiftMod95"
  sm_formula <- paste(sm_fixed_eff, RE_nest, sep = " + ")
} else {
  sm_fixed_eff <- "ShiftRate ~  ShiftMod"
  sm_formula <- paste(sm_fixed_eff, RE_nest, sep = " + ")
  
}

6.1.1.1 Terrestrial

subdata_ter <- mod_data %>%
  filter(Eco=="Ter")

# length(unique(mod_data$Random_ID_Param_Class))

sm_ter <- glmmTMB(as.formula(sm_formula),
                  data = subdata_ter)

tab_model(sm_ter)
  Shift Rate
Predictors Estimates CI p
(Intercept) -0.01 -0.24 – 0.22 0.939
ShiftMod -0.02 -0.04 – -0.00 0.025
Random Effects
σ2 0.74
τ00 ID:class:Param 0.48
τ00 class:Param 0.02
τ00 Param 0.02
ICC 0.41
N ID 94
N class 10
N Param 3
Observations 8638
Marginal R2 / Conditional R2 0.000 / 0.414
plot(effects::allEffects(sm_ter))

No association between modeled shift velocity and observed shift velocity.

6.1.1.2 Marine

subdata_mar <- mod_data %>%
  filter(Eco=="Mar")

# length(unique(subdata_mar$Random_ID_Param_Class))

sm_mar <- glmmTMB(as.formula(sm_formula),
                  data = subdata_mar)

tab_model(sm_mar)
  Shift Rate
Predictors Estimates CI p
(Intercept) 0.31 -0.03 – 0.65 0.071
ShiftMod -0.01 -0.12 – 0.09 0.781
Random Effects
σ2 1.63
τ00 ID:class:Param 0.79
τ00 class:Param 0.03
τ00 Param 0.02
ICC 0.34
N ID 44
N class 15
N Param 3
Observations 937
Marginal R2 / Conditional R2 0.000 / 0.339
plot(effects::allEffects(sm_mar))

Same here…

6.1.1.3 Save model results

if(shiftmodtype=="95"){
  sm_mar_raw <- glmmTMB(
    as.formula(paste("ShiftRate_raw~ShiftMod_raw95", RE_nest, sep = " + ")),
    data = subdata_mar)
} else {
  sm_mar_raw <- glmmTMB(
    as.formula(paste("ShiftRate_raw~ShiftMod_raw", RE_nest, sep = " + ")),
    data = subdata_mar)
}

mar_sm_res <- summary(sm_mar_raw)
mar_sm_res <- data.frame(mar_sm_res$coefficients$cond)
mar_sm_res$Param <- rownames(mar_sm_res)
names(mar_sm_res) <- c("Estimate", "Std_Error", "z-value", "P-value", "Param")


if(shiftmodtype=="95"){
  sm_ter_raw <- glmmTMB(
    as.formula(paste("ShiftRate_raw~ShiftMod_raw95", RE_nest, sep = " + ")),
    data = subdata_ter)
} else {
  sm_ter_raw <- glmmTMB(
    as.formula(paste("ShiftRate_raw~ShiftMod_raw", RE_nest, sep = " + ")),
    data = subdata_ter)
}

ter_sm_res <- summary(sm_ter_raw)
ter_sm_res <- data.frame(ter_sm_res$coefficients$cond)
ter_sm_res$Param <- rownames(ter_sm_res)
names(ter_sm_res) <- c("Estimate", "Std_Error", "z-value", "P-value", "Param")

res_glmm_simple_model <- rbind(
  data.frame(Eco = "Ter",
             ter_sm_res),
  data.frame(Eco = "Mar",
             mar_sm_res)
)

# data amount
if(params$data_amount=="all"){
  
  if(shiftmodtype=="95"){
    write.csv(res_glmm_simple_model, 
              here("Data/Output/res_glmm_sm95_all.csv"), 
              row.names = FALSE)
  } else {
    write.csv(res_glmm_simple_model, 
              here("Data/Output/res_glmm_sm_all.csv"), 
              row.names = FALSE)
  }
  
} else {
  
  if(shiftmodtype=="95"){
    write.csv(res_glmm_simple_model, 
              here("Data/Output/res_glmm_sm95.csv"), 
              row.names = FALSE)
  } else {
    write.csv(res_glmm_simple_model, 
              here("Data/Output/res_glmm_sm.csv"), 
              row.names = FALSE)
  }
  
}

6.1.1.4 Combine

tab_model(sm_ter,sm_mar, 
          dv.labels = c("Terrestrial","Marine"),  
          show.icc = FALSE, 
          show.r2 = FALSE)
  Terrestrial Marine
Predictors Estimates CI p Estimates CI p
(Intercept) -0.01 -0.24 – 0.22 0.939 0.31 -0.03 – 0.65 0.071
ShiftMod -0.02 -0.04 – -0.00 0.025 -0.01 -0.12 – 0.09 0.781
Random Effects
σ2 0.74 1.63
τ00 0.48 ID:class:Param 0.79 ID:class:Param
0.02 class:Param 0.03 class:Param
0.02 Param 0.02 Param
N 94 ID 44 ID
10 class 15 class
3 Param 3 Param
Observations 8638 937

6.2 Simple model - Study-level (Shift ~ ShiftMod)

6.2.1 Terrestrial

new_data <- as_tibble(bioshifts) %>%
  filter(Eco=="Ter") %>%
  select(ID, sp_name_std, class, Param, bvel_lat, bvel95_lat, ShiftRate, Eco)%>%
  group_by(ID, class, Param, Eco) %>%
  mutate(Nsps = length(unique(sp_name_std)),
         ShiftMod_raw = bvel_lat,
         ShiftMod_raw95 = bvel95_lat,
         ShiftRate_raw = ShiftRate) %>%
  filter(Nsps>3) %>%
  summarise(Nsps = mean(Nsps),
            ShiftMod = mean(ShiftMod_raw),
            ShiftMod95 = mean(ShiftMod_raw95),
            ShiftRate  = mean(ShiftRate_raw),
            ShiftMod95_sd = sd(ShiftMod_raw95),
            ShiftMod_sd = sd(ShiftMod_raw),
            ShiftRate_sd = sd(ShiftRate_raw)) %>%
  plyr::rename(replace = c(class = "Class"), warn_missing = FALSE) 
`summarise()` has grouped output by 'ID', 'class', 'Param'. You can override
using the `.groups` argument.
# Fit a deming model

if(shiftmodtype=="95"){
  sm_SA_deming_ter <- deming(
    formula = as.formula("ShiftRate ~  ShiftMod95"),
    xstd = ShiftMod95_sd,
    ystd = ShiftRate_sd,
    weights = Nsps,
    data = new_data)
} else {
  sm_SA_deming_ter <- deming(
    formula = as.formula(sm_fixed_eff),
    xstd = ShiftMod_sd,
    ystd = ShiftRate_sd,
    weights = Nsps,
    data = new_data)
}

sm_SA_deming_ter

Call:
deming(formula = as.formula(sm_fixed_eff), data = new_data, weights = Nsps,     xstd = ShiftMod_sd, ystd = ShiftRate_sd)

n= 128
               Coef   se(coef)  lower 0.95 upper 0.95
Intercept 0.1150676 0.07690119 -0.03565591  0.2657912
Slope     4.9399763 1.35867386  2.27702445  7.6029281

   Scale= 1.04201 
# Fit a GLMM (more appropriate because contains the random effects)

if(shiftmodtype=="95"){
  sm_SA_glmm_ter <- glmmTMB(
    as.formula("ShiftRate ~  ShiftMod95"), 
    weights = Nsps, 
    new_data)
} else {
  sm_SA_glmm_ter <- glmmTMB(
    as.formula(sm_fixed_eff),
    weights = Nsps, 
    new_data)
}

tab_model(sm_SA_glmm_ter)
  Shift Rate
Predictors Estimates CI p
(Intercept) 0.61 0.58 – 0.64 <0.001
ShiftMod 0.94 0.86 – 1.02 <0.001
Observations 128
R2 / R2 adjusted 0.062 / 0.047
tmp <- summary(sm_SA_glmm_ter)

{
  plot(ShiftRate~ShiftMod, new_data)
  abline(h = 0, v = 0, lty = "dashed")
  abline(sm_SA_deming_ter, col = "blue")
  abline(b = tmp$coefficients$cond[2,1], a = tmp$coefficients$cond[1,1], col = "red")
}

No association between modeled shift velocity and observed shift velocity.

6.2.2 Marine

new_data <- as_tibble(bioshifts) %>%
  filter(Eco=="Mar") %>%
  select(ID, sp_name_std, class, Param, bvel_lat, bvel95_lat, ShiftRate, Eco)%>%
  group_by(ID, class, Param, Eco) %>%
  mutate(Nsps = length(unique(sp_name_std)),
         ShiftMod_raw = bvel_lat,
         ShiftMod_raw95 = bvel95_lat,
         ShiftRate_raw = ShiftRate) %>%
  filter(Nsps>3) %>%
  summarise(Nsps = mean(Nsps),
            ShiftMod = mean(ShiftMod_raw),
            ShiftMod95 = mean(ShiftMod_raw95),
            ShiftRate  = mean(ShiftRate_raw),
            ShiftMod95_sd = sd(ShiftMod_raw95),
            ShiftMod_sd = sd(ShiftMod_raw),
            ShiftRate_sd = sd(ShiftRate_raw)) %>%
  plyr::rename(replace = c(class = "Class"), warn_missing = FALSE) 
`summarise()` has grouped output by 'ID', 'class', 'Param'. You can override
using the `.groups` argument.
# new_data$ShiftMod_sd[which(new_data$ShiftMod_sd==0)] <- 0.0001
# new_data$ShiftRate_sd[which(new_data$ShiftMod_sd==0)] <- 0.0001
# new_data[is.na(new_data)] <- 0.0001

# Fit a deming model

# if(shiftmodtype=="95"){
#   sm_SA_deming_mar <- deming(
#     formula = as.formula("ShiftRate ~  ShiftMod95"),
#     xstd = ShiftMod95_sd,
#     ystd = ShiftRate_sd,
#     weights = Nsps,
#     data = new_data)
# } else {
#   sm_SA_deming_mar <- deming(
#     formula = as.formula(sm_fixed_eff),
#     xstd = ShiftMod_sd,
#     ystd = ShiftRate_sd,
#     weights = Nsps,
#     data = new_data)
# }
# 
# sm_SA_deming_mar

# Fit a GLMM (more appropriate because contains the random effects)

if(shiftmodtype=="95"){
  sm_SA_glmm_mar <- glmmTMB(
    as.formula("ShiftRate ~  ShiftMod95"), 
    weights = Nsps, 
    new_data)
} else {
  sm_SA_glmm_mar <- glmmTMB(
    as.formula(sm_fixed_eff),
    weights = Nsps, 
    new_data)
}

tab_model(sm_SA_glmm_mar)
  Shift Rate
Predictors Estimates CI p
(Intercept) 1.75 1.56 – 1.94 <0.001
ShiftMod 1.59 1.22 – 1.97 <0.001
Observations 59
R2 / R2 adjusted 0.077 / 0.044
tmp <- summary(sm_SA_glmm_mar)

{
  plot(ShiftRate~ShiftMod, new_data)
  abline(h = 0, v = 0, lty = "dashed")
  # abline(sm_SA_deming_mar, col = "blue")
  abline(b = tmp$coefficients$cond[2,1], a = tmp$coefficients$cond[1,1], col = "red")
}

Same here…

6.2.3 Save model results

ter_sm_SA_glmm_res <- summary(sm_SA_glmm_ter)
ter_sm_SA_glmm_res <- data.frame(ter_sm_SA_glmm_res$coefficients$cond)
ter_sm_SA_glmm_res$Param <- rownames(ter_sm_SA_glmm_res)
names(ter_sm_SA_glmm_res) <- c("Estimate", "Std_Error", "z-value", "P-value", "Param")

mar_sm_SA_glmm_res <- summary(sm_SA_glmm_mar)
mar_sm_SA_glmm_res <- data.frame(mar_sm_SA_glmm_res$coefficients$cond)
mar_sm_SA_glmm_res$Param <- rownames(mar_sm_SA_glmm_res)
names(mar_sm_SA_glmm_res) <- c("Estimate", "Std_Error", "z-value", "P-value", "Param")


sm_SA_glmm_res <- rbind(data.frame(Eco = "Ter",ter_sm_SA_glmm_res),
                        data.frame(Eco = "Mar",mar_sm_SA_glmm_res))



# data amount
if(params$data_amount=="all"){
  
  if(shiftmodtype=="95"){
    write.csv(sm_SA_glmm_res, 
              here("Data/Output/res_sm_SA_glmm95_all.csv"), 
              row.names = FALSE)
  } else {
    write.csv(sm_SA_glmm_res, 
              here("Data/Output/res_sm_SA_glmm_all.csv"), 
              row.names = FALSE)
  }
  
} else {
  
  if(shiftmodtype=="95"){
    write.csv(sm_SA_glmm_res, 
              here("Data/Output/res_sm_SA_glmm95.csv"), 
              row.names = FALSE)
  } else {
    write.csv(sm_SA_glmm_res, 
              here("Data/Output/res_sm_SA_glmm.csv"), 
              row.names = FALSE)
  }
  
}

6.2.4 Combine

tab_model(sm_SA_glmm_ter,sm_SA_glmm_mar, 
          dv.labels = c("Terrestrial","Marine"),
          show.icc = FALSE, 
          show.r2 = FALSE)
  Terrestrial Marine
Predictors Estimates CI p Estimates CI p
(Intercept) 0.61 0.58 – 0.64 <0.001 1.75 1.56 – 1.94 <0.001
ShiftMod 0.94 0.86 – 1.02 <0.001 1.59 1.22 – 1.97 <0.001
Observations 128 59

6.3 Simple model - direction (Shift ~ ShiftMod * dir)

sm_fixed_eff_dir <- "ShiftRate ~  ShiftMod * Match_dir"

sm_formula_dir <- paste(sm_fixed_eff_dir, RE_nest, sep = " + ")

6.3.1 Terrestrial

var_to_go <- strsplit(sm_formula_dir,"~|[+]|[/]|[|]|[*]")[[1]]
var_to_go <- gsub(" |[(]|[)]","",var_to_go)
var_to_go <- var_to_go[-which(var_to_go=="1")]

subdata_ter <- mod_data %>%
  filter(Eco=="Ter") %>%
  select(var_to_go) %>%
  na.omit
Warning: Using an external vector in selections was deprecated in tidyselect 1.1.0.
ℹ Please use `all_of()` or `any_of()` instead.
  # Was:
  data %>% select(var_to_go)

  # Now:
  data %>% select(all_of(var_to_go))

See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
sm_dir_ter <- glmmTMB(as.formula(sm_formula_dir),
                      data = subdata_ter)

tab_model(sm_dir_ter)
  Shift Rate
Predictors Estimates CI p
(Intercept) 0.37 0.14 – 0.60 0.002
ShiftMod 0.06 0.03 – 0.09 <0.001
Match dir [Equatorward] -0.71 -0.77 – -0.65 <0.001
Match dir [Mismatch] -0.52 -0.56 – -0.48 <0.001
ShiftMod × Match dir
[Equatorward]
0.16 0.09 – 0.23 <0.001
ShiftMod × Match dir
[Mismatch]
-0.35 -0.39 – -0.31 <0.001
Random Effects
σ2 0.63
τ00 ID:class:Param 0.50
τ00 class:Param 0.00
τ00 Param 0.03
N ID 94
N class 10
N Param 3
Observations 8215
Marginal R2 / Conditional R2 0.176 / NA
plot(effects::allEffects(sm_dir_ter), main = "Terrestrial")

Modeled shift velocity is positively related to observed shift velocity only when they shift in the same direction.

6.3.2 Marine

var_to_go <- strsplit(sm_formula_dir,"~|[+]|[/]|[|]|[*]")[[1]]
var_to_go <- gsub(" |[(]|[)]","",var_to_go)
var_to_go <- var_to_go[-which(var_to_go=="1")]

subdata_mar <- mod_data %>%
  filter(Eco=="Mar") %>%
  select(var_to_go) %>%
  na.omit

sm_dir_mar <- glmmTMB(as.formula(sm_formula_dir),
                      data = subdata_mar)

tab_model(sm_dir_mar)
  Shift Rate
Predictors Estimates CI p
(Intercept) 0.55 0.30 – 0.80 <0.001
ShiftMod 0.53 0.31 – 0.75 <0.001
Match dir [Equatorward] -0.75 -1.01 – -0.50 <0.001
Match dir [Mismatch] -0.23 -0.45 – -0.01 0.044
ShiftMod × Match dir
[Equatorward]
-0.14 -0.52 – 0.24 0.464
ShiftMod × Match dir
[Mismatch]
-1.14 -1.40 – -0.88 <0.001
Random Effects
σ2 1.35
τ00 ID:class:Param 0.98
τ00 class:Param 0.00
τ00 Param 0.00
N ID 43
N class 15
N Param 3
Observations 852
Marginal R2 / Conditional R2 0.235 / NA
plot(effects::allEffects(sm_dir_mar), main = "Marine")

Modeled shift velocity is positively related to observed shift velocity only when they shift in the same direction.

6.3.3 Combine

tab_model(sm_dir_ter,sm_dir_mar, 
          dv.labels = c("Terrestrial","Marine"),  
          show.icc = FALSE, 
          show.r2 = FALSE)
  Terrestrial Marine
Predictors Estimates CI p Estimates CI p
(Intercept) 0.37 0.14 – 0.60 0.002 0.55 0.30 – 0.80 <0.001
ShiftMod 0.06 0.03 – 0.09 <0.001 0.53 0.31 – 0.75 <0.001
Match dir [Equatorward] -0.71 -0.77 – -0.65 <0.001 -0.75 -1.01 – -0.50 <0.001
Match dir [Mismatch] -0.52 -0.56 – -0.48 <0.001 -0.23 -0.45 – -0.01 0.044
ShiftMod × Match dir
[Equatorward]
0.16 0.09 – 0.23 <0.001 -0.14 -0.52 – 0.24 0.464
ShiftMod × Match dir
[Mismatch]
-0.35 -0.39 – -0.31 <0.001 -1.14 -1.40 – -0.88 <0.001
Random Effects
σ2 0.63 1.35
τ00 0.50 ID:class:Param 0.98 ID:class:Param
0.00 class:Param 0.00 class:Param
0.03 Param 0.00 Param
N 94 ID 43 ID
10 class 15 class
3 Param 3 Param
Observations 8215 852

6.3.4 Chi-squared test for direction frequency

# Terrestrial
dir_table <- mod_data %>%
  filter(Eco == "Ter",
         ShiftRate!=0) %>% 
  group_by(match_direction) %>%
  count %>%
  na.omit 

dir_table
# A tibble: 2 × 2
# Groups:   match_direction [2]
  match_direction     n
  <fct>           <int>
1 mismatch         3814
2 match            4459
chisq.test(dir_table$n)

    Chi-squared test for given probabilities

data:  dir_table$n
X-squared = 50.287, df = 1, p-value = 1.328e-12
# Marine
dir_table <- mod_data %>%
  filter(Eco == "Mar",
         ShiftRate!=0) %>% 
  group_by(match_direction) %>%
  count %>%
  na.omit 

dir_table
# A tibble: 2 × 2
# Groups:   match_direction [2]
  match_direction     n
  <fct>           <int>
1 mismatch          230
2 match             696
chisq.test(dir_table$n)

    Chi-squared test for given probabilities

data:  dir_table$n
X-squared = 234.51, df = 1, p-value < 2.2e-16

6.4 Binomial model

6.4.0.1 Terrestrial

subdata_ter <- mod_data %>%
  filter(Eco=="Ter") %>%
  select(mismatch_binary,Param,class,ID) %>%
  na.omit

# fit model
mm01_ter <- glmmTMB(mismatch_binary ~ 1 + (1 | Param/class/ID),
                    family = binomial,
                    data = subdata_ter)

tab_model(mm01_ter, transform = NULL, string.est = "Estimate")
  mismatch binary
Predictors Estimate CI p
(Intercept) 0.11 0.01 – 0.21 0.032
Random Effects
σ2 3.29
τ00 ID:class:Param 0.20
τ00 class:Param 0.00
τ00 Param 0.00
N ID 94
N class 10
N Param 3
Observations 8273
Marginal R2 / Conditional R2 0.000 / NA

6.4.0.2 Marine

subdata_mar <- mod_data %>%
  filter(Eco=="Mar") %>%
  select(mismatch_binary,Param,class,ID) %>%
  na.omit

# fit model
mm01_mar <- glmmTMB(mismatch_binary ~ 1 + (1 | Param/class/ID),
                    family = binomial,
                    data = subdata_mar)

tab_model(mm01_mar, transform = NULL, string.est = "Estimate")
  mismatch binary
Predictors Estimate CI p
(Intercept) 1.21 NaN – NaN NaN
Random Effects
σ2 3.29
τ00 ID:class:Param 0.70
τ00 class:Param 0.00
τ00 Param 0.00
N ID 44
N class 15
N Param 3
Observations 926
Marginal R2 / Conditional R2 0.000 / NA

6.5 Mismatch between documented and modeled shifts

6.5.1 Terrestrial

y <- strsplit(mm_formula_ter," ")[[1]][1]

var_to_go <- strsplit(paste(mm_formula_ter, "+", RE_nest),"~|[+]|[/]|[|]")[[1]]
var_to_go <- gsub(" |[(]|[)]","",var_to_go)
var_to_go <- var_to_go[-which(var_to_go=="1")]

subdata_ter <- mod_data %>%
  filter(Eco=="Ter") %>% 
  select(var_to_go) %>%
  na.omit

nrow(subdata_ter)
[1] 8604
# fit model
mm_ter <- glmmTMB(as.formula(paste(mm_formula_ter, "+", RE_nest)),
                  family = Gamma(link = "log"),
                  data = subdata_ter)

# simulationOutput <- DHARMa::simulateResiduals(fittedModel = mm_ter, plot = F)
# DHARMa::testResiduals(simulationOutput)

tab_model(mm_ter, transform = NULL, string.est = "Estimate")
  mismatch
Predictors Estimate CI p
(Intercept) 0.83 0.59 – 1.07 <0.001
TSS -0.02 -0.04 – 0.01 0.243
Study duration -0.19 -0.29 – -0.09 <0.001
Interannual var 0.16 0.12 – 0.20 <0.001
Lat extent 0.38 0.24 – 0.51 <0.001
Connectivity -0.11 -0.15 – -0.06 <0.001
Sampling category
[Survey-Resurvey]
-0.00 -0.44 – 0.43 0.987
Sampling category
[TimeSeries]
0.16 -0.19 – 0.50 0.369
Locomotion mode
[Run/Walk]
-0.36 -0.79 – 0.07 0.101
Locomotion mode
[Swimming]
-0.38 -1.13 – 0.38 0.326
Locomotion mode
[Slithering/Crawling]
-0.08 -0.68 – 0.52 0.796
Locomotion mode [Sessile] -0.97 -1.33 – -0.61 <0.001
Random Effects
σ2 1.08
τ00 ID:class:Param 0.28
τ00 class:Param 0.05
τ00 Param 0.00
N ID 94
N class 10
N Param 3
Observations 8604
Marginal R2 / Conditional R2 0.440 / NA
# get emmeans for categorical variables
files_cat_cont_names <- gsub("_"," ",cat_vars)

mm_ter_emm <- lapply(cat_vars, function(x){
  if(any(grepl(x,var_to_go))){
    emmeans(object = mm_ter, 
            specs = x,
            type = "response")
  }
})
names(mm_ter_emm) <- files_cat_cont_names

test <- sapply(mm_ter_emm,is.null)
if(any(test)){
  mm_ter_emm <- mm_ter_emm[-which(test)]
}
mm_ter_emm
$`Sampling category`
 Sampling_category response    SE  df asymp.LCL asymp.UCL
 CensusPeriods         1.62 0.218 Inf     1.245      2.11
 Survey-Resurvey       1.61 0.404 Inf     0.989      2.64
 TimeSeries            1.90 0.416 Inf     1.235      2.92

Results are averaged over the levels of: Locomotion_mode 
Confidence level used: 0.95 
Intervals are back-transformed from the log scale 

$`Locomotion mode`
 Locomotion_mode     response    SE  df asymp.LCL asymp.UCL
 Flying                 2.439 0.368 Inf     1.814      3.28
 Run/Walk               1.698 0.379 Inf     1.096      2.63
 Swimming               1.670 0.640 Inf     0.788      3.54
 Slithering/Crawling    2.254 0.693 Inf     1.234      4.12
 Sessile                0.927 0.138 Inf     0.693      1.24

Results are averaged over the levels of: Sampling_category 
Confidence level used: 0.95 
Intervals are back-transformed from the log scale 
mm_ter_cont <- lapply(mm_ter_emm, 
                      contrast, 
                      method = "eff",
                      type = "response")
names(mm_ter_cont) <- names(mm_ter_cont)
mm_ter_cont
$`Sampling category`
 contrast                 ratio     SE  df null z.ratio p.value
 CensusPeriods effect     0.950 0.0944 Inf    1  -0.518  0.7214
 (Survey-Resurvey) effect 0.946 0.1463 Inf    1  -0.357  0.7214
 TimeSeries effect        1.112 0.1472 Inf    1   0.805  0.7214

Results are averaged over the levels of: Locomotion_mode 
P value adjustment: fdr method for 3 tests 
Tests are performed on the log scale 

$`Locomotion mode`
 contrast                     ratio     SE  df null z.ratio p.value
 Flying effect                1.430 0.2186 Inf    1   2.337  0.0486
 (Run/Walk) effect            0.995 0.1414 Inf    1  -0.035  0.9720
 Swimming effect              0.979 0.2770 Inf    1  -0.075  0.9720
 (Slithering/Crawling) effect 1.321 0.3132 Inf    1   1.174  0.4007
 Sessile effect               0.544 0.0898 Inf    1  -3.692  0.0011

Results are averaged over the levels of: Sampling_category 
P value adjustment: fdr method for 5 tests 
Tests are performed on the log scale 
mm_ter_cont_pairs <- lapply(mm_ter_emm, 
                            contrast, 
                            method = "pairwise",
                            type = "response")
names(mm_ter_cont_pairs) <- names(mm_ter_cont)
mm_ter_cont_pairs
$`Sampling category`
 contrast                          ratio    SE  df null z.ratio p.value
 CensusPeriods / (Survey-Resurvey) 1.004 0.224 Inf    1   0.016  0.9999
 CensusPeriods / TimeSeries        0.854 0.150 Inf    1  -0.899  0.6411
 (Survey-Resurvey) / TimeSeries    0.851 0.230 Inf    1  -0.599  0.8209

Results are averaged over the levels of: Locomotion_mode 
P value adjustment: tukey method for comparing a family of 3 estimates 
Tests are performed on the log scale 

$`Locomotion mode`
 contrast                           ratio    SE  df null z.ratio p.value
 Flying / (Run/Walk)                1.437 0.317 Inf    1   1.642  0.4704
 Flying / Swimming                  1.460 0.563 Inf    1   0.982  0.8636
 Flying / (Slithering/Crawling)     1.082 0.330 Inf    1   0.259  0.9990
 Flying / Sessile                   2.630 0.482 Inf    1   5.275  <.0001
 (Run/Walk) / Swimming              1.016 0.337 Inf    1   0.049  1.0000
 (Run/Walk) / (Slithering/Crawling) 0.753 0.231 Inf    1  -0.923  0.8881
 (Run/Walk) / Sessile               1.831 0.430 Inf    1   2.577  0.0747
 Swimming / (Slithering/Crawling)   0.741 0.329 Inf    1  -0.674  0.9620
 Swimming / Sessile                 1.801 0.701 Inf    1   1.513  0.5540
 (Slithering/Crawling) / Sessile    2.430 0.782 Inf    1   2.760  0.0457

Results are averaged over the levels of: Sampling_category 
P value adjustment: tukey method for comparing a family of 5 estimates 
Tests are performed on the log scale 
# marginal R2 model avg
Actual    = subdata_ter[,y]
Predicted = predict(mm_ter, 
                    type="response", 
                    re.form=NA)
Residuals = Actual - Predicted

mm_ter_R2_avg_marginal <- efronRSquared(residual = Residuals, 
                                        predicted = Predicted, 
                                        statistic = "EfronRSquared")
mm_ter_R2_avg_marginal
EfronRSquared 
        0.196 
# conditional R2 model avg
Actual    = subdata_ter[,y]
Predicted = predict(mm_ter, type="response")
Residuals = Actual - Predicted

mm_ter_R2_avg_conditional <- efronRSquared(residual = Residuals, 
                                           predicted = Predicted, 
                                           statistic = "EfronRSquared")
mm_ter_R2_avg_conditional
EfronRSquared 
        0.301 

6.5.2 Marine

y <- strsplit(mm_formula_mar," ")[[1]][1]

var_to_go <- strsplit(paste(mm_formula_mar, "+", RE_nest),"~|[+]|[/]|[|]")[[1]]
var_to_go <- gsub(" |[(]|[)]","",var_to_go)
var_to_go <- var_to_go[-which(var_to_go=="1")]

subdata_mar <- mod_data %>%
  filter(Eco=="Mar") %>% 
  select(var_to_go) %>%
  na.omit

# fit model
mm_mar <- glmmTMB(as.formula(paste(mm_formula_mar, "+", RE_nest)),
                  family = Gamma(link = "log"),
                  data = subdata_mar)

# simulationOutput <- DHARMa::simulateResiduals(fittedModel = mm_mar, plot = F)
# DHARMa::testResiduals(simulationOutput)

tab_model(mm_mar, transform = NULL, string.est = "Estimate")
  mismatch
Predictors Estimate CI p
(Intercept) -0.30 -1.27 – 0.66 0.538
TSS 0.06 -0.01 – 0.12 0.088
Study duration -0.35 -0.60 – -0.09 0.007
Interannual var 0.16 0.07 – 0.26 0.001
Lat extent 0.63 0.48 – 0.78 <0.001
Sampling category
[Survey-Resurvey]
-0.25 -0.69 – 0.18 0.256
Sampling category
[TimeSeries]
0.28 0.00 – 0.56 0.048
Life form [Ectotherm] 1.57 0.65 – 2.49 0.001
Life form [Endotherm] 1.00 -0.21 – 2.21 0.107
Locomotion mode
[Slithering/Crawling]
-0.49 -0.96 – -0.02 0.041
Locomotion mode
[Planktonic]
1.21 0.13 – 2.29 0.028
Locomotion mode [Sessile] 0.31 -0.19 – 0.81 0.231
Random Effects
σ2 1.04
τ00 ID:class:Param 0.16
τ00 class:Param 0.00
τ00 Param 0.06
N ID 44
N class 15
N Param 3
Observations 937
Marginal R2 / Conditional R2 0.276 / NA
# get emmeans for categorical variables
files_cat_cont_names <- gsub("_"," ",cat_vars)

mm_mar_emm <- lapply(cat_vars, function(x){
  if(any(grepl(x,var_to_go))){
    emmeans(object = mm_mar, 
            specs = x,
            type = "response")
  }
})
names(mm_mar_emm) <- files_cat_cont_names

test <- sapply(mm_mar_emm,is.null)
if(any(test)){
  mm_mar_emm <- mm_mar_emm[-which(test)]
}
mm_mar_emm
$`Life form`
 Life_form response    SE  df asymp.LCL asymp.UCL
 Cryptogam    0.861 0.333 Inf     0.404      1.84
 Ectotherm    4.152 0.966 Inf     2.631      6.55
 Endotherm    2.331 1.072 Inf     0.947      5.74

Results are averaged over the levels of: Sampling_category, Locomotion_mode 
Confidence level used: 0.95 
Intervals are back-transformed from the log scale 

$`Sampling category`
 Sampling_category response    SE  df asymp.LCL asymp.UCL
 CensusPeriods         2.01 0.486 Inf     1.248      3.23
 Survey-Resurvey       1.56 0.449 Inf     0.887      2.74
 TimeSeries            2.66 0.651 Inf     1.649      4.30

Results are averaged over the levels of: Life_form, Locomotion_mode 
Confidence level used: 0.95 
Intervals are back-transformed from the log scale 

$`Locomotion mode`
 Locomotion_mode     response    SE  df asymp.LCL asymp.UCL
 Swimming               1.567 0.413 Inf     0.935      2.63
 Slithering/Crawling    0.961 0.334 Inf     0.486      1.90
 Planktonic             5.274 2.509 Inf     2.076     13.40
 Sessile                2.127 0.615 Inf     1.207      3.75

Results are averaged over the levels of: Sampling_category, Life_form 
Confidence level used: 0.95 
Intervals are back-transformed from the log scale 
mm_mar_cont <- lapply(mm_mar_emm, 
                      contrast, 
                      method = "eff",
                      type = "response")
names(mm_mar_cont) <- names(mm_mar_cont)
mm_mar_cont
$`Life form`
 contrast         ratio    SE  df null z.ratio p.value
 Cryptogam effect 0.425 0.145 Inf    1  -2.515  0.0179
 Ectotherm effect 2.048 0.417 Inf    1   3.515  0.0013
 Endotherm effect 1.150 0.355 Inf    1   0.452  0.6512

Results are averaged over the levels of: Sampling_category, Locomotion_mode 
P value adjustment: fdr method for 3 tests 
Tests are performed on the log scale 

$`Sampling category`
 contrast                 ratio     SE  df null z.ratio p.value
 CensusPeriods effect      0.99 0.0988 Inf    1  -0.103  0.9180
 (Survey-Resurvey) effect  0.77 0.1076 Inf    1  -1.874  0.0915
 TimeSeries effect         1.31 0.1314 Inf    1   2.719  0.0196

Results are averaged over the levels of: Life_form, Locomotion_mode 
P value adjustment: fdr method for 3 tests 
Tests are performed on the log scale 

$`Locomotion mode`
 contrast                     ratio    SE  df null z.ratio p.value
 Swimming effect              0.773 0.146 Inf    1  -1.367  0.2287
 (Slithering/Crawling) effect 0.474 0.113 Inf    1  -3.119  0.0073
 Planktonic effect            2.601 1.033 Inf    1   2.407  0.0321
 Sessile effect               1.049 0.193 Inf    1   0.261  0.7941

Results are averaged over the levels of: Sampling_category, Life_form 
P value adjustment: fdr method for 4 tests 
Tests are performed on the log scale 
mm_mar_cont_pairs <- lapply(mm_mar_emm, 
                            contrast, 
                            method = "pairwise",
                            type = "response")
names(mm_mar_cont_pairs) <- names(mm_mar_cont)
mm_mar_cont_pairs
$`Life form`
 contrast              ratio     SE  df null z.ratio p.value
 Cryptogam / Ectotherm 0.207 0.0972 Inf    1  -3.356  0.0023
 Cryptogam / Endotherm 0.369 0.2280 Inf    1  -1.613  0.2399
 Ectotherm / Endotherm 1.781 0.7075 Inf    1   1.453  0.3139

Results are averaged over the levels of: Sampling_category, Locomotion_mode 
P value adjustment: tukey method for comparing a family of 3 estimates 
Tests are performed on the log scale 

$`Sampling category`
 contrast                          ratio    SE  df null z.ratio p.value
 CensusPeriods / (Survey-Resurvey) 1.286 0.285 Inf    1   1.137  0.4913
 CensusPeriods / TimeSeries        0.754 0.108 Inf    1  -1.976  0.1181
 (Survey-Resurvey) / TimeSeries    0.586 0.130 Inf    1  -2.409  0.0423

Results are averaged over the levels of: Life_form, Locomotion_mode 
P value adjustment: tukey method for comparing a family of 3 estimates 
Tests are performed on the log scale 

$`Locomotion mode`
 contrast                           ratio    SE  df null z.ratio p.value
 Swimming / (Slithering/Crawling)   1.631 0.390 Inf    1   2.045  0.1714
 Swimming / Planktonic              0.297 0.164 Inf    1  -2.201  0.1230
 Swimming / Sessile                 0.737 0.188 Inf    1  -1.198  0.6278
 (Slithering/Crawling) / Planktonic 0.182 0.109 Inf    1  -2.852  0.0225
 (Slithering/Crawling) / Sessile    0.452 0.143 Inf    1  -2.512  0.0581
 Planktonic / Sessile               2.479 1.251 Inf    1   1.799  0.2739

Results are averaged over the levels of: Sampling_category, Life_form 
P value adjustment: tukey method for comparing a family of 4 estimates 
Tests are performed on the log scale 
# marginal R2 model avg
Actual    = subdata_mar[,y]
Predicted = predict(mm_mar, 
                    type="response", 
                    re.form=NA)
Residuals = Actual - Predicted

mm_mar_R2_avg_marginal <- efronRSquared(residual = Residuals, 
                                        predicted = Predicted, 
                                        statistic = "EfronRSquared")
mm_mar_R2_avg_marginal
EfronRSquared 
        0.163 
# conditional R2 model avg
Actual    = subdata_mar[,y]
Predicted = predict(mm_mar, type="response")
Residuals = Actual - Predicted

mm_mar_R2_avg_conditional <- efronRSquared(residual = Residuals, 
                                           predicted = Predicted, 
                                           statistic = "EfronRSquared")
mm_mar_R2_avg_conditional
EfronRSquared 
        0.318 

6.5.3 Combine

tab_model(mm_ter, mm_mar, 
          transform = NULL, string.est = "Estimate",
          dv.labels = c("Terrestrial","Marine"),  
          show.icc = FALSE, 
          show.r2 = FALSE)
  Terrestrial Marine
Predictors Estimate CI p Estimate CI p
(Intercept) 0.83 0.59 – 1.07 <0.001 -0.30 -1.27 – 0.66 0.538
TSS -0.02 -0.04 – 0.01 0.243 0.06 -0.01 – 0.12 0.088
Study duration -0.19 -0.29 – -0.09 <0.001 -0.35 -0.60 – -0.09 0.007
Interannual var 0.16 0.12 – 0.20 <0.001 0.16 0.07 – 0.26 0.001
Lat extent 0.38 0.24 – 0.51 <0.001 0.63 0.48 – 0.78 <0.001
Connectivity -0.11 -0.15 – -0.06 <0.001
Sampling category
[Survey-Resurvey]
-0.00 -0.44 – 0.43 0.987 -0.25 -0.69 – 0.18 0.256
Sampling category
[TimeSeries]
0.16 -0.19 – 0.50 0.369 0.28 0.00 – 0.56 0.048
Locomotion mode
[Run/Walk]
-0.36 -0.79 – 0.07 0.101
Locomotion mode
[Swimming]
-0.38 -1.13 – 0.38 0.326
Locomotion mode
[Slithering/Crawling]
-0.08 -0.68 – 0.52 0.796 -0.49 -0.96 – -0.02 0.041
Locomotion mode [Sessile] -0.97 -1.33 – -0.61 <0.001 0.31 -0.19 – 0.81 0.231
Life form [Ectotherm] 1.57 0.65 – 2.49 0.001
Life form [Endotherm] 1.00 -0.21 – 2.21 0.107
Locomotion mode
[Planktonic]
1.21 0.13 – 2.29 0.028
Random Effects
σ2 1.08 1.04
τ00 0.28 ID:class:Param 0.16 ID:class:Param
0.05 class:Param 0.00 class:Param
0.00 Param 0.06 Param
N 94 ID 44 ID
10 class 15 class
3 Param 3 Param
Observations 8604 937

7 Compile model results

7.1 Terrestrial

# get results from continuous variables
cont_vars_res_ter <- summary(mm_ter)
cont_vars_res_ter <- data.frame(cont_vars_res_ter$coefficients$cond)
confint_mm_ter <- confint(mm_ter)[,1:2]
confint_mm_ter <- confint_mm_ter[rownames(cont_vars_res_ter),]
cont_vars_res_ter <- cbind(cont_vars_res_ter, confint_mm_ter)

cont_vars_res_ter$var <- rownames(cont_vars_res_ter)
rownames(cont_vars_res_ter) <- NULL
cont_vars_res_ter <- cont_vars_res_ter %>% filter(var %in% c("Int",cont_vars))
names(cont_vars_res_ter) <- c("Estimate","Std.Error","z.value","P-value","Lower.CI","Upper.CI","var")

# data amount
if(params$data_amount=="all"){
  
  write.csv(cont_vars_res_ter, 
            here("Data/Output/cont_vars_res_ter_all.csv"), 
            row.names = TRUE)
  
} else {
  
  write.csv(cont_vars_res_ter, 
            here("Data/Output/cont_vars_res_ter.csv"), 
            row.names = TRUE)
  
}


# get results from categorical variables
# contrasts
cat_vars_cont_res_ter <- lapply(1:length(mm_ter_cont), function(x){
  data.frame(confint(mm_ter_cont[[x]]),var=names(mm_ter_cont)[x])
})
rem <- which(sapply(cat_vars_cont_res_ter,is.null))
cat_vars_cont_res_ter <- rbindlist(cat_vars_cont_res_ter)

cat_vars_cont_res_ter$level <- cat_vars_cont_res_ter$contrast
cat_vars_cont_res_ter$level <- gsub(" effect","",cat_vars_cont_res_ter$level)
cat_vars_cont_res_ter <- cat_vars_cont_res_ter[,-1]
names(cat_vars_cont_res_ter) <- c("Estimate","SE","df","Lower.CI","Upper.CI","var","level")

# data amount
if(params$data_amount=="all"){
  
  write.csv(cat_vars_cont_res_ter,
            here("Data/Output/cat_vars_cont_res_ter_all.csv"), 
            row.names = TRUE)
  
} else {
  
  write.csv(cat_vars_cont_res_ter,
            here("Data/Output/cat_vars_cont_res_ter.csv"), 
            row.names = TRUE)
  
}

# pairwise contrasts
cat_vars_cont_pairs_res_ter <- lapply(1:length(mm_ter_cont_pairs), function(x){
  data.frame(mm_ter_cont_pairs[[x]],var=names(mm_ter_cont_pairs)[x])
})
rem <- which(sapply(cat_vars_cont_pairs_res_ter,is.null))
cat_vars_cont_pairs_res_ter <- rbindlist(cat_vars_cont_pairs_res_ter)

cat_vars_cont_pairs_res_ter$level <- cat_vars_cont_pairs_res_ter$contrast
cat_vars_cont_pairs_res_ter$level <- gsub(" effect","",cat_vars_cont_pairs_res_ter$level)
cat_vars_cont_pairs_res_ter <- cat_vars_cont_pairs_res_ter[,-1]
names(cat_vars_cont_pairs_res_ter) <- c("Estimate","SE","df","null","z-ratio","P-value","var","level")

# data amount
if(params$data_amount=="all"){
  
  write.csv(cat_vars_cont_pairs_res_ter,
            here("Data/Output/cat_vars_cont_pairs_res_ter_all.csv"), 
            row.names = TRUE)
  
} else {
  
  write.csv(cat_vars_cont_pairs_res_ter,
            here("Data/Output/cat_vars_cont_pairs_res_ter.csv"), 
            row.names = TRUE)
  
}

# emmeans
cat_emm_vars_res_ter <- lapply(1:length(mm_ter_emm), function(x){
  data.frame(confint(mm_ter_emm[[x]]),var=names(mm_ter_emm)[x])
})
cat_emm_vars_res_ter <- rbindlist(cat_emm_vars_res_ter)
Column 1 ['Locomotion_mode'] of item 2 is missing in item 1. Use fill=TRUE to fill with NA (NULL for list columns), or use.names=FALSE to ignore column names. use.names='check' (default from v1.12.2) emits this message and proceeds as if use.names=FALSE for  backwards compatibility. See news item 5 in v1.12.2 for options to control this message.
cat_emm_vars_res_ter$level <- cat_emm_vars_res_ter[,1]
cat_emm_vars_res_ter <- cat_emm_vars_res_ter[,-1]
cat_emm_vars_res_ter$level <- gsub(" effect","",cat_emm_vars_res_ter$level)
names(cat_emm_vars_res_ter) <- c("Estimate","SE","df","Lower.CI","Upper.CI","var","level")

# data amount
if(params$data_amount=="all"){
  
  write.csv(cat_emm_vars_res_ter,
            here("Data/Output/cat_emm_vars_res_ter_all.csv"), 
            row.names = TRUE)
  
} else {
  
  write.csv(cat_emm_vars_res_ter,
            here("Data/Output/cat_emm_vars_res_ter.csv"), 
            row.names = TRUE)
  
}

7.2 Marine

# get results from continuous variables
cont_vars_res_mar <- summary(mm_mar)
cont_vars_res_mar <- data.frame(cont_vars_res_mar$coefficients$cond)
confint_mm_mar <- confint(mm_mar)[,1:2]
confint_mm_mar <- confint_mm_mar[rownames(cont_vars_res_mar),]
cont_vars_res_mar <- cbind(cont_vars_res_mar, confint_mm_mar)

cont_vars_res_mar$var <- rownames(cont_vars_res_mar)
rownames(cont_vars_res_mar) <- NULL
cont_vars_res_mar <- cont_vars_res_mar %>% filter(var %in% c("Int",cont_vars))
names(cont_vars_res_mar) <- c("Estimate","Std.Error","z.value","P-value","Lower.CI","Upper.CI","var")

# data amount
if(params$data_amount=="all"){
  
  write.csv(cont_vars_res_mar, 
            here("Data/Output/cont_vars_res_mar_all.csv"), 
            row.names = TRUE)
  
} else {
  
  write.csv(cont_vars_res_mar, 
            here("Data/Output/cont_vars_res_mar.csv"), 
            row.names = TRUE)
  
}

# get results from categorical variables
# contrasts
cat_vars_cont_res_mar <- lapply(1:length(mm_mar_cont), function(x){
  data.frame(confint(mm_mar_cont[[x]]),var=names(mm_mar_cont)[x])
})
rem <- which(sapply(cat_vars_cont_res_mar,is.null))
cat_vars_cont_res_mar <- rbindlist(cat_vars_cont_res_mar)

cat_vars_cont_res_mar$level <- cat_vars_cont_res_mar$contrast
cat_vars_cont_res_mar$level <- gsub(" effect","",cat_vars_cont_res_mar$level)
cat_vars_cont_res_mar <- cat_vars_cont_res_mar[,-1]
names(cat_vars_cont_res_mar) <- c("Estimate","SE","df","Lower.CI","Upper.CI","var","level")

# data amount
if(params$data_amount=="all"){
  
  write.csv(cat_vars_cont_res_mar,
            here("Data/Output/cat_vars_cont_res_mar_all.csv"), 
            row.names = TRUE)
  
} else {
  
  write.csv(cat_vars_cont_res_mar,
            here("Data/Output/cat_vars_cont_res_mar.csv"), 
            row.names = TRUE)
  
}

# pairwise contrasts
cat_vars_cont_pairs_res_mar <- lapply(1:length(mm_mar_cont_pairs), function(x){
  data.frame(mm_mar_cont_pairs[[x]],var=names(mm_mar_cont_pairs)[x])
})
rem <- which(sapply(cat_vars_cont_pairs_res_mar,is.null))
cat_vars_cont_pairs_res_mar <- rbindlist(cat_vars_cont_pairs_res_mar)

cat_vars_cont_pairs_res_mar$level <- cat_vars_cont_pairs_res_mar$contrast
cat_vars_cont_pairs_res_mar$level <- gsub(" effect","",cat_vars_cont_pairs_res_mar$level)
cat_vars_cont_pairs_res_mar <- cat_vars_cont_pairs_res_mar[,-1]
names(cat_vars_cont_pairs_res_mar) <- c("Estimate","SE","df","null","z-ratio","P-value","var","level")

# data amount
if(params$data_amount=="all"){
  
  write.csv(cat_vars_cont_pairs_res_mar,
            here("Data/Output/cat_vars_cont_pairs_res_mar_all.csv"), 
            row.names = TRUE)
  
} else {
  
  write.csv(cat_vars_cont_pairs_res_mar,
            here("Data/Output/cat_vars_cont_pairs_res_mar.csv"), 
            row.names = TRUE)
  
}

# emmeans
cat_emm_vars_res_mar <- lapply(1:length(mm_mar_emm), function(x){
  data.frame(confint(mm_mar_emm[[x]]),var=names(mm_mar_emm)[x])
})
cat_emm_vars_res_mar <- rbindlist(cat_emm_vars_res_mar)
Column 1 ['Sampling_category'] of item 2 is missing in item 1. Use fill=TRUE to fill with NA (NULL for list columns), or use.names=FALSE to ignore column names. use.names='check' (default from v1.12.2) emits this message and proceeds as if use.names=FALSE for  backwards compatibility. See news item 5 in v1.12.2 for options to control this message.
cat_emm_vars_res_mar$level <- cat_emm_vars_res_mar[,1]
cat_emm_vars_res_mar <- cat_emm_vars_res_mar[,-1]
cat_emm_vars_res_mar$level <- gsub(" effect","",cat_emm_vars_res_mar$level)
names(cat_emm_vars_res_mar) <- c("Estimate","SE","df","Lower.CI","Upper.CI","var","level")

# data amount
if(params$data_amount=="all"){
  
  write.csv(cat_emm_vars_res_mar,
            here("Data/Output/cat_emm_vars_res_mar_all.csv"), 
            row.names = TRUE)
  
} else {
  
  write.csv(cat_emm_vars_res_mar,
            here("Data/Output/cat_emm_vars_res_mar.csv"), 
            row.names = TRUE)
  
}

8 Plot coeffs

8.1 Effects contrast

mm_mag_coefs_cont_ter <- data.frame(Eco = "Terrestrial",
                                    rbindlist(list(cont_vars_res_ter,
                                                   cat_vars_cont_res_ter),
                                              fill = TRUE))
mm_mag_coefs_cont_mar <- data.frame(Eco = "Marine",
                                    rbindlist(list(cont_vars_res_mar,
                                                   cat_vars_cont_res_mar),
                                              fill = TRUE))

mag_coefs_cont <- rbind(mm_mag_coefs_cont_ter,
                        mm_mag_coefs_cont_mar)

mag_coefs_cont$level[which(is.na(mag_coefs_cont$level))] <- mag_coefs_cont$var[which(is.na(mag_coefs_cont$level))]

sign_test <- sapply(1:nrow(mag_coefs_cont), function(x){
  sign(mag_coefs_cont$Lower.CI[x])==sign(mag_coefs_cont$Upper.CI[x])
})
mag_coefs_cont$sig <- ifelse(sign_test, 1, 0)
mag_coefs_cont$level <- factor(mag_coefs_cont$level, levels = rev(unique(mag_coefs_cont$level)))
mag_coefs_cont$var <- factor(mag_coefs_cont$var, levels = (unique(mag_coefs_cont$var)))

mag_coefs_cont_plot_data <- mag_coefs_cont %>% filter(!var == "Int")

mag_coefs_cont_plot <- ggplot(mag_coefs_cont_plot_data, 
                              aes(x = Estimate, y = level, alpha = sig)) +
  geom_vline(xintercept=0, color = "gray",linetype="dashed", lwd=1.5)+ 
  geom_point(size=6, shape = 21, color = "black", fill = "gray")+
  geom_errorbar(aes(xmin=Lower.CI,xmax=Upper.CI), width=0, lwd=1.5) +
  theme_classic(base_size = 20)+ 
  # coord_cartesian(xlim = c(-1,1))+
  xlab("Coefficient\n<<< Match - Mismatch >>>")+ylab("")+
  theme(legend.position = "none")+
  facet_grid(var~Eco, scales = "free_y", space = "free")

mag_coefs_cont_plot

8.2 Effects pairwise

mm_mag_coefs_cont_pair_ter <- data.frame(Eco = "Terrestrial",
                                         rbindlist(list(cont_vars_res_ter,
                                                        cat_vars_cont_pairs_res_ter),
                                                   fill = TRUE))
mm_mag_coefs_cont_pair_mar <- data.frame(Eco = "Marine",
                                         rbindlist(list(cont_vars_res_mar,
                                                        cat_vars_cont_pairs_res_mar),
                                                   fill = TRUE))

mag_coefs_cont_pair <- rbind(mm_mag_coefs_cont_pair_ter,
                             mm_mag_coefs_cont_pair_mar)

mag_coefs_cont_pair$level[which(is.na(mag_coefs_cont_pair$level))] <- mag_coefs_cont_pair$var[which(is.na(mag_coefs_cont_pair$level))]

sign_test <- sapply(1:nrow(mag_coefs_cont_pair), function(x){
  mag_coefs_cont_pair$P.value[x] < 0.05
})
mag_coefs_cont_pair$sig <- ifelse(sign_test, 1, 0)
mag_coefs_cont_pair$level <- factor(mag_coefs_cont_pair$level, levels = rev(unique(mag_coefs_cont_pair$level)))
mag_coefs_cont_pair$var <- factor(mag_coefs_cont_pair$var, levels = (unique(mag_coefs_cont_pair$var)))

mag_coefs_cont_pair_plot_data <- mag_coefs_cont_pair %>% filter(!var == "Int")

mag_coefs_cont_pair_plot <- ggplot(mag_coefs_cont_pair_plot_data, 
                                   aes(x = Estimate, y = level, alpha = sig)) +
  geom_vline(xintercept=0, color = "gray",linetype="dashed", lwd=1.5)+ 
  geom_point(size=6, shape = 21, color = "black", fill = "gray")+
  geom_errorbar(aes(xmin=Lower.CI,xmax=Upper.CI), width=0, lwd=1.5) +
  theme_classic(base_size = 20)+ 
  coord_cartesian(xlim = c(-1,1))+
  xlab("Coefficient\n<<< Match - Mismatch >>>")+ylab("")+
  theme(legend.position = "none")+
  facet_grid(var~Eco, scales = "free_y", space = "free")

mag_coefs_cont_pair_plot

8.3 Effects Emmeans

mm_mag_coefs_emm_ter <- data.frame(Eco = "Terrestrial",
                                   rbindlist(list(cont_vars_res_ter,
                                                  cat_emm_vars_res_ter),
                                             fill = TRUE))
mm_mag_coefs_emm_mar <- data.frame(Eco = "Marine",
                                   rbindlist(list(cont_vars_res_mar,
                                                  cat_emm_vars_res_mar),
                                             fill = TRUE))

mag_coefs_emm <- rbind(mm_mag_coefs_emm_ter,
                       mm_mag_coefs_emm_mar)

mag_coefs_emm$level[which(is.na(mag_coefs_emm$level))] <- mag_coefs_emm$var[which(is.na(mag_coefs_emm$level))]

sign_test <- sapply(1:nrow(mag_coefs_emm), function(x){
  sign(mag_coefs_emm$Lower.CI[x])==sign(mag_coefs_emm$Upper.CI[x])
})
mag_coefs_emm$sig <- ifelse(sign_test, 1, 0)
mag_coefs_emm$level <- factor(mag_coefs_emm$level, levels = rev(unique(mag_coefs_emm$level)))
mag_coefs_emm$var <- factor(mag_coefs_emm$var, levels = (unique(mag_coefs_emm$var)))

mag_coefs_emm_plot_data <- mag_coefs_emm %>% filter(!var == "Int")

mag_coefs_emm_plot <- ggplot(mag_coefs_emm_plot_data, 
                             aes(x = Estimate, y = level, alpha = sig)) +
  geom_vline(xintercept=0, color = "gray",linetype="dashed", lwd=1.5)+ 
  geom_point(size=6, shape = 21, color = "black", fill = "gray")+
  geom_errorbar(aes(xmin=Lower.CI,xmax=Upper.CI), width=0, lwd=1.5) +
  theme_classic(base_size = 20)+ 
  # coord_cartesian(xlim = c(-1,1))+
  xlab("Coefficient\n<<< Match - Mismatch >>>")+ylab("")+
  theme(legend.position = "none")+
  facet_grid(var~Eco, scales = "free_y", space = "free")

mag_coefs_emm_plot

9 Plot significant effects

9.1 Effects contrast

# get significant effects
mag_coefs <- mag_coefs_cont

vars_sig <- mag_coefs %>% 
  filter(sig==1,
         !var == "Int") %>% 
  select(var,Eco) %>% 
  unique %>% 
  mutate(var = as.character(var))

plot_list_ter <- list()
plot_list_mar <- list()

count_ter = 0
count_mar = 0

for(i in 1:nrow(vars_sig)){
  
  var2go <- as.character(vars_sig[i,"var"])
  eco2go <- as.character(vars_sig[i,2])
  if(eco2go=="Terrestrial"){
    eco2go_ <- "Ter"
  }else{
    eco2go_ <- "Mar"
  }
  
  subdata <- mod_data %>%
    filter(Eco==eco2go_) %>%
    select(cont_vars, cat_vars, gsub(" ","_",var2go), Eco, mismatch, Param,class,ID) %>%
    na.omit()
  
  # is factor or numeric
  if(is.numeric(subdata[,gsub(" ","_",var2go)])){
    
    if(eco2go == "Terrestrial"){
      
      p_i <- plot_model(mm_ter,  type = "eff", terms = gsub(" ","_",var2go),
                        line.size = 1.5,
                        colors  = "bw",
                        title = "") +
        theme_classic(base_size = 20)+
        ylab("Mismatch")+
        xlab(gsub("_"," ",var2go))+
        theme(legend.position = "none",
              aspect.ratio=1)
      
      count_ter <- count_ter+1
      plot_list_ter[[count_ter]] <- p_i
      
    } else {
      
      p_i <- plot_model(mm_mar,  type = "eff", terms = gsub(" ","_",var2go),
                        line.size = 1.5,
                        colors  = "bw",
                        title = "") +
        theme_classic(base_size = 20)+
        ylab("Mismatch")+
        xlab(gsub("_"," ",var2go))+
        theme(legend.position = "none",
              aspect.ratio=1)
      
      count_mar <- count_mar+1
      plot_list_mar[[count_mar]] <- p_i
      
    }
    
  } else {
    
    subdata_coeffs <- mag_coefs %>%
      filter(Eco == eco2go,
             var == var2go)%>%
      mutate(sig = as.character(sig))
    
    p_i <- ggplot(subdata_coeffs, 
                  aes_string(x="Estimate",y="level", alpha = "sig"))+
      geom_vline(xintercept=0, color = "gray",linetype="dashed", lwd=1.5)+
      scale_alpha_manual(values = c("1"=1,"0"=0.3))+
      geom_point(size=6, shape = 21, color = "black", fill = "gray")+
      geom_errorbar(aes(xmin=Lower.CI,xmax=Upper.CI), width=0, lwd=1.5) +
      theme_classic(base_size = 20)+ 
      # coord_cartesian(xlim = c(-1,1))+
      xlab("Mismatch")+
      ylab(gsub("_"," ",var2go))+
      theme(legend.position = "none",
            aspect.ratio=1)
    
    if(eco2go == "Terrestrial"){
      count_ter <- count_ter+1
      plot_list_ter[[count_ter]] <- p_i
    } else {
      count_mar <- count_mar+1
      plot_list_mar[[count_mar]] <- p_i
    }
  }
}
Warning: Using an external vector in selections was deprecated in tidyselect 1.1.0.
ℹ Please use `all_of()` or `any_of()` instead.
  # Was:
  data %>% select(cont_vars)

  # Now:
  data %>% select(all_of(cont_vars))

See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
Warning: Using an external vector in selections was deprecated in tidyselect 1.1.0.
ℹ Please use `all_of()` or `any_of()` instead.
  # Was:
  data %>% select(cat_vars)

  # Now:
  data %>% select(all_of(cat_vars))

See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
ℹ Please use tidy evaluation idioms with `aes()`.
ℹ See also `vignette("ggplot2-in-packages")` for more information.
plot_list_ter
[[1]]


[[2]]


[[3]]


[[4]]


[[5]]


[[6]]

plot_list_mar
[[1]]


[[2]]


[[3]]


[[4]]


[[5]]


[[6]]

9.2 Effects pairwise

# get significant effects
mag_coefs <- mag_coefs_cont_pair

vars_sig <- mag_coefs %>%
  filter(sig==1,
         !var == "Int") %>%
  select(var,Eco) %>%
  unique %>%
  mutate(var = as.character(var))

mag_coefs <- mag_coefs_emm

plot_list_ter <- list()
plot_list_mar <- list()

count_ter = 0
count_mar = 0

for(i in 1:nrow(vars_sig)){
  
  var2go <- as.character(vars_sig[i,"var"])
  eco2go <- as.character(vars_sig[i,2])
  if(eco2go=="Terrestrial"){
    eco2go_ <- "Ter"
  }else{
    eco2go_ <- "Mar"
  }
  
  subdata <- mod_data %>%
    filter(Eco==eco2go_) %>%
    select(cont_vars, cat_vars, gsub(" ","_",var2go), Eco, mismatch, Param,class,ID) %>%
    na.omit()
  
  # is factor or numeric
  if(is.numeric(subdata[,gsub(" ","_",var2go)])){
    
    if(eco2go == "Terrestrial"){ 
      mm_2go <- mm_ter  
    } else { 
      mm_2go <- mm_mar 
    }
    
    preds <- ggeffects::ggpredict(mm_2go,terms = gsub(" ","_",var2go))
    
    p_i <- plot_model(mm_2go,  
                      type = "eff", 
                      terms = gsub(" ","_",var2go),
                      line.size = 1.5,
                      colors  = "bw",
                      title = "") +
      scale_y_continuous(
        trans="log",
        labels=function(x) round(x,1),
        breaks = exp(seq(min(log(preds$conf.low),na.rm = TRUE),
                         max(log(preds$conf.high),na.rm = TRUE),
                         length.out = 5)))+
      theme_classic(base_size = 20)+
      ylab("Mismatch")+
      xlab(gsub("_"," ",var2go))+
      theme(legend.position = "none",
            aspect.ratio=1)
    
    if(eco2go == "Terrestrial"){
      count_ter <- count_ter+1
      plot_list_ter[[count_ter]] <- p_i
    } else {
      count_mar <- count_mar+1
      plot_list_mar[[count_mar]] <- p_i
    } 
    
  } else {
    subdata_coeffs <- mag_coefs %>%
      filter(Eco == eco2go,
             var == var2go)%>%
      mutate(sig = as.character(sig))
    
    if(eco2go == "Terrestrial"){
      cat_vars_cont_pairs_res <- cat_vars_cont_pairs_res_ter
    } else {
      cat_vars_cont_pairs_res <- cat_vars_cont_pairs_res_mar
    }
    
    cat_vars_cont_pairs_res <- cat_vars_cont_pairs_res %>%
      filter(var == var2go,
             `P-value` <= 0.05)
    
    cat_vars_cont_pairs_res$from <- sapply(cat_vars_cont_pairs_res$level, function(x){
      tmp <- strsplit(x," / ")[[1]][1]
    })
    cat_vars_cont_pairs_res$to <- sapply(cat_vars_cont_pairs_res$level, function(x){
      tmp <- strsplit(x," / ")[[1]][2]
    })
    
    
    cat_vars_cont_pairs_res$from <- gsub("(","",cat_vars_cont_pairs_res$from, 
                                         fixed = TRUE)
    cat_vars_cont_pairs_res$from <- gsub(")","",cat_vars_cont_pairs_res$from, 
                                         fixed = TRUE)
    cat_vars_cont_pairs_res$to <- gsub("(","",cat_vars_cont_pairs_res$to, 
                                       fixed = TRUE)
    cat_vars_cont_pairs_res$to <- gsub(")","",cat_vars_cont_pairs_res$to, 
                                       fixed = TRUE)
    
    t.test.df <- data.frame(
      p.value = as.vector(cat_vars_cont_pairs_res$`P-value`),
      right.tip = cat_vars_cont_pairs_res$to,
      left.tip = cat_vars_cont_pairs_res$from,
      y.bar = max(subdata_coeffs$Upper.CI) + seq(1,nrow(cat_vars_cont_pairs_res))/10
    )
    
    t.test.df$label_y = as.character(stars.pval(t.test.df$p.value))
    
    p_i <- ggplot(subdata_coeffs,
                  aes(x=level,y=Estimate))+
      geom_errorbar(aes(ymin=Lower.CI,ymax=Upper.CI), width=0, lwd=1.5) +
      geom_point(size=6, shape = 21, color = "black", fill = "gray")+
      theme_classic(base_size = 20)+
      scale_y_continuous(
        trans="log",
        labels=function(x) round(x,1),
        breaks = exp(seq(min(log(subdata_coeffs$Lower.CI)), 
                         max(log(subdata_coeffs$Upper.CI)), 
                         length.out = 5)))+
      ylab("Mismatch")+
      xlab(gsub("_"," ",var2go))+
      theme(legend.position = "none",
            aspect.ratio=1,
            axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1))+
      geom_text_pairwise(data = t.test.df,
                         aes(xmin = left.tip,
                             xmax = right.tip,
                             y = (y.bar),
                             label = label_y),
                         na.rm = TRUE,
                         size = 10, vjust = 0.3)+
      expand_limits(y = (max(t.test.df$y.bar)+1))
    
    if(eco2go == "Terrestrial"){
      count_ter <- count_ter+1
      plot_list_ter[[count_ter]] <- p_i
    } else {
      count_mar <- count_mar+1
      plot_list_mar[[count_mar]] <- p_i
    }
  }
}
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
plot_list_ter
[[1]]


[[2]]


[[3]]


[[4]]


[[5]]

plot_list_mar
[[1]]


[[2]]


[[3]]


[[4]]


[[5]]


[[6]]

if(params$data_amount=="all"){
  
  pg <- plot_grid(
  plot_grid(plotlist = c(plot_list_ter[1:5],
                         plot_list_ter[6]), 
            ncol = 3, labels = LETTERS[1:4], align = "h"),
  
  plot_grid(plotlist = c(plot_list_mar[1:3],
                         plot_list_mar[4:6]), 
            ncol = 3, labels = LETTERS[1:6+4], align = "h"),
  
  nrow = 2)
  
} else {
  
  pg <- plot_grid(
  plot_grid(plotlist = c(plot_list_ter[1:3],
                         plot_list_ter[4]), 
            ncol = 3, labels = LETTERS[1:4], align = "vh"),
  
  plot_grid(plotlist = c(plot_list_mar[1:3],
                         plot_list_mar[4:6]), 
            ncol = 3, labels = LETTERS[1:6+4], align = "vh"),
  
  nrow = 2)
  
}



pg

# data amount
if(params$data_amount=="all"){
  
  ggsave(plot = pg, 
         filename = here("Figures/EffectPlots_Mar_Ter_EMM_pairwise_all.svg"), 
         device = "svg",
         width = 4.5*3, height = 6*4, 
         units = "in")

  
} else {
  
  ggsave(plot = pg, 
         filename = here("Figures/EffectPlots_Mar_Ter_EMM_pairwise.svg"), 
         device = "svg",
         width = 4.5*3, height = 6*4, 
         units = "in")

}

10 Further comparisons

# compare flying organisms
pred_values <- predict(mm_ter)

var_to_go <- strsplit(paste(mm_formula_ter, "+", RE_nest),"~|[+]|[/]|[|]")[[1]]
var_to_go <- gsub(" |[(]|[)]","",var_to_go)
var_to_go <- var_to_go[-which(var_to_go=="1")]

subdata_ter <- mod_data %>%
  filter(Eco=="Ter") %>% 
  select(var_to_go) %>%
  na.omit

subdata_ter$pred_values <- pred_values

subdata_ter <- subdata_ter %>% 
  filter(Locomotion_mode=="Flying" | Locomotion_mode=="Sessile")

ggplot(subdata_ter, aes(x = pred_values, y = class))+
  geom_boxplot()+
  theme_bw()

11 Map study areas

mundi <- rnaturalearth::ne_coastline(scale = 110, returnclass = "sv")
mundi <- crop(mundi, ext(c(-180,180,-60,90)))

# get raster bioshifts shp files study areas
get_raster_bioshifts = "NO"
if(get_raster_bioshifts=="YES"){
  my_ext = terra::ext(mundi)
  my_crs = crs(mundi)
  rast_bioshifts <- terra::rast(my_ext, crs = my_crs, res = 2)
  values(rast_bioshifts) <- 0
  
  fgdb <- "C:/Users/brunn/ShadowDrive/CreateGeodatabaseBioShifts/Data/Study_Areas_v1/Study_Areas.gdb"
  fc_list <- terra::vector_layers(fgdb)
  fc_list <- fc_list[which(fc_list %in% unique(mod_data$ID))]
  
  for(i in 1:length(fc_list)){ cat("\r",i,"from",length(fc_list))
    tmp = terra::vect(fgdb, layer = fc_list[i])
    tmp = terra::cells(rast_bioshifts,tmp)
    tmp_cell = tmp[,2]
    tmp_vals = rast_bioshifts[tmp_cell][,1]
    rast_bioshifts[tmp_cell] = tmp_vals+1
  }
  names(rast_bioshifts) <- "SA"
  rast_bioshifts[rast_bioshifts==0] <- NA
  
  # data amount
  if(params$data_amount=="all"){
    
    writeRaster(rast_bioshifts, here::here("Data/raster_bioshifts_SA_SDMs_all.tif"), overwrite = TRUE)
    
  } else {
    
    writeRaster(rast_bioshifts, here::here("Data/raster_bioshifts_SA_SDMs.tif"), overwrite = TRUE)
    
  }
  
  
  
} else {
  
  # data amount
  if(params$data_amount=="all"){
    
    rast_bioshifts <- terra::rast(here::here("Data/raster_bioshifts_SA_SDMs_all.tif"))
    
  } else {
    
    rast_bioshifts <- terra::rast(here::here("Data/raster_bioshifts_SA_SDMs.tif"))
    
  }
  
  
  rast_bioshifts <- crop(rast_bioshifts, ext(mundi))
}


bio_fig <- ggplot() +
  geom_spatraster(data=rast_bioshifts)+
  scale_fill_viridis_c(
    name = "Number of studies",
    alpha=.7,
    na.value = "white",
    # trans="log", 
    labels=function(x) round(x,0),
    breaks=seq(
      as.numeric(global(rast_bioshifts,min,na.rm=TRUE)),
      as.numeric(global(rast_bioshifts,max,na.rm=TRUE)),
      length.out=4)
  )+
  geom_spatvector(data=mundi)+
  theme_void()
bio_fig 

# data amount
  if(params$data_amount=="all"){
    
    filetosave <- here("Figures/Number_of_studies_all.png")
    
  } else {
    
    filetosave <- here("Figures/Number_of_studies.png")
    
  }

ggsave(filename = filetosave, 
       device = "png",
       width = 8, height = 3, 
       units = "in", bg = "white")

12 Sensitivity

Compare models with all life form vs models with locomotion mode

cont_vars2 <- 
  c(
    "TSS",
    "Study_duration",
    "Interannual_var",
    "SA_Extent",
    "Life_form",
    "Connectivity"
  )
cat_vars2 <- c(
  # "Locomotion_mode",
  "Category"
)

## mismatch model magnitude
mm_2_fixed_eff <- paste("mismatch ~ ",
                        paste(cont_vars2,collapse = " + "),
                        paste(cat_vars2,collapse = " + "),
                        sep = " + ")
mm_2_fixed_eff <- gsub(" ~  [+] " , " ~ ", mm_2_fixed_eff)
mm_2_formula_ter <- paste(mm_2_fixed_eff, RE_nest, sep = " + ")
# mm_2_formula_mar <- paste(mm_2_fixed_eff, RE_nest, sep = " + ")

# mm_2_formula_ter <- paste(gsub(" [+] Locomotion_mode","",mm_2_fixed_eff), RE_nest, sep = " + ")
mm_2_formula_mar <- paste(gsub(" [+] Connectivity","",mm_2_fixed_eff), RE_nest, sep = " + ")

y <- strsplit(mm_2_formula_ter," ")[[1]][1]

Terrestrial: I had to remove Locomotion_mode for the model to fit without singularity issues. We can keep Locomotion_mode removing Life_form works

12.0.1 Terrestrial

var_to_go <- strsplit(mm_2_formula_ter,"~|[+]|[/]|[|]")[[1]]
var_to_go <- gsub(" |[(]|[)]","",var_to_go)
var_to_go <- var_to_go[-which(var_to_go=="1")]

subdata_ter <- mod_data %>%
  filter(Eco=="Ter") %>% 
  select(var_to_go) %>%
  na.omit

# fit model
mm_2_ter <- glmmTMB(as.formula(mm_2_formula_ter),
                    family = Gamma(link = "log"),
                    data = subdata_ter)

tab_model(mm_2_ter, transform = NULL, string.est = "Estimate")

# plot(effects::allEffects(mm_2_ter))

# make avg model
clust <- makeCluster(detectCores()-3)
clusterExport(clust, c("mm_2_ter","subdata_ter","glmmTMB"))
mm_2_ter_dredge <- dredge(mm_2_ter, cluster = clust)
stopCluster(clust)

# get best models
# remove models that could not calculate AICc (?)
if(any(is.na(mm_2_ter_dredge$AICc))){
  pos <- which(is.na(mm_2_ter_dredge$AICc))
  mm_2_ter_dredge <- mm_2_ter_dredge[-pos,]
}
mm_2_ter_best_models <- subset(mm_2_ter_dredge, cumsum(weight) <= .95)

# make model avg
mm_2_ter_avg_model <- model.avg(mm_2_ter_best_models, fit = TRUE)       

# tab_model(mm_2_ter_avg_model, transform = NULL, string.est = "Estimate")

# marginal R2 model avg
Actual    = subdata_ter[,y]
Predicted = predict(mm_2_ter_avg_model, type="response", re.form=NA)
Residuals = Actual - Predicted

mm_2_ter_R2_avg_marginal <- efronRSquared(residual = Residuals, 
                                          predicted = Predicted, 
                                          statistic = "EfronRSquared")
mm_2_ter_R2_avg_marginal

# conditional R2 model avg
Actual    = subdata_ter[,y]
Predicted = predict(mm_2_ter_avg_model, type="response")
Residuals = Actual - Predicted

mm_2_ter_R2_avg_conditional <- efronRSquared(residual = Residuals, 
                                             predicted = Predicted, 
                                             statistic = "EfronRSquared")
mm_2_ter_R2_avg_conditional

12.0.2 Marine

var_to_go <- strsplit(mm_2_formula_mar,"~|[+]|[/]|[|]")[[1]]
var_to_go <- gsub(" |[(]|[)]","",var_to_go)
var_to_go <- var_to_go[-which(var_to_go=="1")]

subdata_mar <- mod_data %>%
  filter(Eco=="Mar") %>%
  select(var_to_go) %>%
  na.omit

# fit model
mm_2_mar <- glmmTMB(as.formula(mm_2_formula_mar),
                    family = Gamma(link = "log"),
                    data = subdata_mar)

tab_model(mm_2_mar, transform = NULL, string.est = "Estimate")

# plot(effects::allEffects(mm_2_mar))

# make avg model
clust <- makeCluster(detectCores()-3)
clusterExport(clust, c("mm_2_mar","subdata_mar","glmmTMB"))
mm_2_mar_dredge <- dredge(mm_2_mar, cluster = clust)
stopCluster(clust)

# get best models
# remove models that could not calculate AICc (?)
if(any(is.na(mm_2_mar_dredge$AICc))){
  pos <- which(is.na(mm_2_mar_dredge$AICc))
  mm_2_mar_dredge <- mm_2_mar_dredge[-pos,]
}
mm_2_mar_best_models <- subset(mm_2_mar_dredge, cumsum(weight) <= .95)

# make model avg
mm_2_mar_avg_model <- model.avg(mm_2_mar_best_models, fit = TRUE)

# tab_model(mm_2_mar_avg_model, transform = NULL, string.est = "Estimate")

# marginal R2 model avg
Actual    = subdata_mar[,y]
Predicted = predict(mm_2_mar_avg_model, type="response", re.form=NA)
Residuals = Actual - Predicted

mm_2_mar_R2_avg_marginal <- efronRSquared(residual = Residuals, 
                                          predicted = Predicted, 
                                          statistic = "EfronRSquared")
mm_2_mar_R2_avg_marginal

# conditional R2 model avg
Actual    = subdata_mar[,y]
Predicted = predict(mm_2_mar_avg_model, type="response")
Residuals = Actual - Predicted

mm_2_mar_R2_avg_conditional <- efronRSquared(residual = Residuals, 
                                             predicted = Predicted, 
                                             statistic = "EfronRSquared")
mm_2_mar_R2_avg_conditional

12.0.3 Compare

tab_model(mm_mar,mm_2_mar_avg_model, dv.labels = c("Marine model 1","Marine model 2"))

data.frame(R2_type = c("Marginal","Conditional"),
           R2_model_1 = c(mm_mar_R2_avg_marginal,mm_mar_R2_avg_conditional),
           R2_model_2 = c(mm_2_mar_R2_avg_marginal,mm_2_mar_R2_avg_conditional))
tab_model(mm_ter,mm_2_ter_avg_model, dv.labels = c("Terrestrial model 1","Terrestrial model 2"))

data.frame(R2_type = c("Marginal","Conditional"),
           R2_model_1 = c(mm_ter_R2_avg_marginal,mm_ter_R2_avg_conditional),
           R2_model_2 = c(mm_2_ter_R2_avg_marginal,mm_2_ter_R2_avg_conditional))