library(tidyverse)
library(glmmTMB)
library(car)
library(DHARMa)
Standard error function
<- function(x) sd(x)/sqrt(length(x)) se
Total dataset
<-read_csv("data_gasteracantha.csv",col_names=T) tmp_noNA
Treat time as a categorical variable
$Time<-as.character(tmp_noNA$Time) tmp_noNA
Let’s create subset excluding the empty web observations. This will facilitate the comparisons between colour morphs
<-tmp_noNA %>% filter(colour!="empty") tmp_ind
Because the measures are repeated for each individual, lets create a subset with a single observation to explore association between colour morph and the variables measured
<- tmp_noNA %>% distinct(code, .keep_all=T)
unique_ind <-unique_ind %>% filter(colour!="empty") unique_noEmpty
Check the normality of the variables per colour category (including empty web when possible)
#Web height
hist(unique_ind$Web_height)
qqPlot(unique_ind$Web_height,groups=factor(unique_ind$colour))
#opisthosoma width
hist(unique_noEmpty$opisto_w)
qqPlot(unique_noEmpty$opisto_w)
#web Area
hist(log(unique_ind$web_area+10))
qqPlot(log(unique_ind$web_area+10),groups=factor(unique_ind$colour))
It seems that all the variables are following a normal distribution in every colour category
Web height
Run the linear model
<-lm(Web_height~colour,data=unique_ind)
mod_webHeight#plot(mod_webHeight)
Check the significance of the predictor
summary(mod_webHeight)
##
## Call:
## lm(formula = Web_height ~ colour, data = unique_ind)
##
## Residuals:
## Min 1Q Median 3Q Max
## -90.400 -29.238 0.762 30.560 93.790
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 130.400 8.241 15.824 <2e-16 ***
## colourempty -14.352 12.197 -1.177 0.241
## colourwhite -4.190 9.762 -0.429 0.668
## colouryellow -1.162 10.408 -0.112 0.911
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 41.2 on 146 degrees of freedom
## Multiple R-squared: 0.01192, Adjusted R-squared: -0.008382
## F-statistic: 0.5871 on 3 and 146 DF, p-value: 0.6244
anova(mod_webHeight)
## Analysis of Variance Table
##
## Response: Web_height
## Df Sum Sq Mean Sq F value Pr(>F)
## colour 3 2990 996.83 0.5871 0.6244
## Residuals 146 247871 1697.75
Opisthosoma width
Run the linear model
<-lm(opisto_w~colour,data=unique_noEmpty)
mod_opistoW#plot(mod_opistoW)
Check the significance of the predictor
summary(mod_opistoW)
##
## Call:
## lm(formula = opisto_w ~ colour, data = unique_noEmpty)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.2229 -0.8017 0.0826 0.8767 2.2771
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 9.6229 0.2640 36.444 <2e-16 ***
## colourwhite 0.5916 0.3245 1.823 0.0712 .
## colouryellow 0.8945 0.3428 2.609 0.0104 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.294 on 103 degrees of freedom
## (23 observations deleted due to missingness)
## Multiple R-squared: 0.0625, Adjusted R-squared: 0.04429
## F-statistic: 3.433 on 2 and 103 DF, p-value: 0.03603
anova(mod_opistoW)
## Analysis of Variance Table
##
## Response: opisto_w
## Df Sum Sq Mean Sq F value Pr(>F)
## colour 2 11.489 5.7445 3.4331 0.03603 *
## Residuals 103 172.350 1.6733
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Opisthosoma width seems to differ between colour morphs
Web area
Run the linear model
<-lm(sqrt(web_area+10)~colour,data=unique_ind) mod_webArea
Check the assumptions of the linear model
plot(mod_webArea)
shapiro.test(mod_webArea$residuals)
##
## Shapiro-Wilk normality test
##
## data: mod_webArea$residuals
## W = 0.98884, p-value = 0.2767
everything seems ok
Check the significance of the predictor
summary(mod_webArea)
##
## Call:
## lm(formula = sqrt(web_area + 10) ~ colour, data = unique_ind)
##
## Residuals:
## Min 1Q Median 3Q Max
## -8.756 -2.785 -0.096 3.053 9.800
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 19.34362 0.81604 23.704 <2e-16 ***
## colourempty -0.09935 1.20775 -0.082 0.935
## colourwhite -0.63583 0.96666 -0.658 0.512
## colouryellow 0.29297 1.03068 0.284 0.777
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 4.08 on 146 degrees of freedom
## Multiple R-squared: 0.009452, Adjusted R-squared: -0.0109
## F-statistic: 0.4644 on 3 and 146 DF, p-value: 0.7076
anova(mod_webArea)
## Analysis of Variance Table
##
## Response: sqrt(web_area + 10)
## Df Sum Sq Mean Sq F value Pr(>F)
## colour 3 23.19 7.7307 0.4644 0.7076
## Residuals 146 2430.59 16.6478
get the summary value per colour morph
%>% group_by(colour) %>% summarize(num(mean(web_area),digits=2),se(web_area)) unique_ind
## # A tibble: 4 x 3
## colour `num(mean(web_area), digits = 2)` `se(web_area)`
## <chr> <num:.2!> <dbl>
## 1 black 372.07 22.1
## 2 empty 375.58 34.7
## 3 white 360.56 22.2
## 4 yellow 390.76 23.6
%>% group_by(colour) %>% summarize(num(mean(Web_height),digits=2),se(Web_height)) unique_ind
## # A tibble: 4 x 3
## colour `num(mean(Web_height), digits = 2)` `se(Web_height)`
## <chr> <num:.2!> <dbl>
## 1 black 130.40 9.33
## 2 empty 116.05 9.49
## 3 white 126.21 5.45
## 4 yellow 129.24 5.15
%>% filter(colour!="empty") %>% drop_na(opisto_w) %>% group_by(colour) %>% summarize(num(mean(opisto_w),digits=2),se(opisto_w)) unique_ind
## # A tibble: 3 x 3
## colour `num(mean(opisto_w), digits = 2)` `se(opisto_w)`
## <chr> <num:.2!> <dbl>
## 1 black 9.62 0.333
## 2 white 10.21 0.170
## 3 yellow 10.52 0.203
Because we found that the colour morphs differ in their opisthosoma width, we explored if this predictor is associated with prey capture
model with negative binomial distribution
Run the model
<-glmmTMB(formula=total_preys ~ opisto_w + (1|code) + (1|check),
capture_opistoWfamily="nbinom2",REML=T,data=tmp_ind)
Check the uniformity, dispersion and zero inflation of the model
<- simulateResiduals(fittedModel = capture_opistoW, n = 1000)
simulationOutput testDispersion(simulationOutput = simulationOutput, alternative ="two.sided")
##
## DHARMa nonparametric dispersion test via sd of residuals fitted vs.
## simulated
##
## data: simulationOutput
## dispersion = 0.82239, p-value = 0.528
## alternative hypothesis: two.sided
testUniformity(simulationOutput = simulationOutput, alternative ="two.sided")
##
## One-sample Kolmogorov-Smirnov test
##
## data: simulationOutput$scaledResiduals
## D = 0.023038, p-value = 0.3784
## alternative hypothesis: two-sided
testZeroInflation(simulationOutput = simulationOutput, alternative ="two.sided")
##
## DHARMa zero-inflation test via comparison to expected zeros with
## simulation under H0 = fitted model
##
## data: simulationOutput
## ratioObsSim = 1.0024, p-value = 0.946
## alternative hypothesis: two.sided
everything seems ok
Check the significance of the predictor
Anova(capture_opistoW)
## Analysis of Deviance Table (Type II Wald chisquare tests)
##
## Response: total_preys
## Chisq Df Pr(>Chisq)
## opisto_w 0.328 1 0.5668
Because width is not related with prey capture, which is the variable we are interested in, we decided to remove it for the subsequent analyses
Web area and web height present collinearity
Run the model
<-lm(sqrt(web_area+10)~Web_height,data=unique_ind) mod_webArea_Heigth
Check the assumptions of the linear model
plot(mod_webArea_Heigth)
shapiro.test(mod_webArea_Heigth$residuals)
##
## Shapiro-Wilk normality test
##
## data: mod_webArea_Heigth$residuals
## W = 0.99232, p-value = 0.6011
everything seems ok
Check the significance of the predictor
summary(mod_webArea_Heigth)
##
## Call:
## lm(formula = sqrt(web_area + 10) ~ Web_height, data = unique_ind)
##
## Residuals:
## Min 1Q Median 3Q Max
## -8.6118 -2.7954 -0.0652 2.7971 9.7547
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 14.982515 1.017724 14.722 < 2e-16 ***
## Web_height 0.032980 0.007664 4.303 3.05e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.839 on 148 degrees of freedom
## Multiple R-squared: 0.1112, Adjusted R-squared: 0.1052
## F-statistic: 18.52 on 1 and 148 DF, p-value: 3.048e-05
Anova(mod_webArea_Heigth)
## Anova Table (Type II tests)
##
## Response: sqrt(web_area + 10)
## Sum Sq Df F value Pr(>F)
## Web_height 272.85 1 18.516 3.048e-05 ***
## Residuals 2180.93 148
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Light measures are bimodal, in consequences we decided to this variable as binary (high or low). This categorization can be explore
<-c("#636363","#f0f0f0","#ffeda0")
paleta
ggplot(data=tmp_noNA, aes(x=log(luxes*100), group=colour, fill=colour)) +
geom_density(adjust=1.5, alpha=.4) +
scale_fill_manual(values=paleta)+
scale_x_continuous(limits=c(0,12))+
theme_classic()+labs(y="Density",x="Log(lux*100)")
## Warning: Removed 274 rows containing non-finite values (`stat_density()`).
We explore if there were differences between sides in the exposure to a certain light condition
Run the model
<-glmmTMB(formula=b_luxes ~ Side+ (1|code)+(1|day),family="binomial",data=tmp_ind) light_side
Check the significance of the predictor
summary(light_side)
## Family: binomial ( logit )
## Formula: b_luxes ~ Side + (1 | code) + (1 | day)
## Data: tmp_ind
##
## AIC BIC logLik deviance df.resid
## 1516.6 1538.5 -754.3 1508.6 1774
##
## Random effects:
##
## Conditional model:
## Groups Name Variance Std.Dev.
## code (Intercept) 3.9175 1.9793
## day (Intercept) 0.4532 0.6732
## Number of obs: 1778, groups: code, 129; day, 6
##
## Conditional model:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -2.8531 0.3745 -7.618 2.57e-14 ***
## Sideventral 1.5409 0.1504 10.245 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Anova(light_side)
## Analysis of Deviance Table (Type II Wald chisquare tests)
##
## Response: b_luxes
## Chisq Df Pr(>Chisq)
## Side 104.95 1 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
We found that the ventral side is more often expose to conditions of high luminosity. Let’s visualize the results
#Predict the values based on the model
$light_side<-predict(light_side,type="response")
tmp_ind#Colours
<-c("#B84C7A","#BCA7D2")
paleta_side#Plot
ggplot(data = tmp_ind,aes(x=Side,y=light_side, fill=Side))+
scale_y_continuous(limits=c(0,1))+
scale_fill_manual(values=paleta_side)+
scale_colour_manual(values=paleta_side)+
stat_summary(fun = mean,aes(color = Side,group=Side),fun.min = function(x) mean(x) - (2*se(x)),fun.max = function(x) mean(x)+(2*se(x)),geom = "pointrange", position = position_jitterdodge(jitter.width=0.15), size=1.5)+
theme_classic()+labs(x="Spider side",y="Light environment")
We also tested if the colour morphs differ in which side is expose to the different light environments
Run the model with yellow and ventral as fixed levels
$colour<-relevel(as.factor(tmp_ind$colour),"yellow")
tmp_ind$Side<-relevel(as.factor(tmp_ind$Side),"ventral")
tmp_ind<-glmmTMB(formula=b_luxes ~ Side*colour + (1|code) + (1|day) ,family="binomial",data=tmp_ind) colour_light1
Check the significance of the predictor
summary(colour_light1)
## Family: binomial ( logit )
## Formula: b_luxes ~ Side * colour + (1 | code) + (1 | day)
## Data: tmp_ind
##
## AIC BIC logLik deviance df.resid
## 1485.9 1529.7 -734.9 1469.9 1770
##
## Random effects:
##
## Conditional model:
## Groups Name Variance Std.Dev.
## code (Intercept) 3.9748 1.994
## day (Intercept) 0.4597 0.678
## Number of obs: 1778, groups: code, 129; day, 6
##
## Conditional model:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.5977 0.4540 -1.317 0.18800
## Sidedorsal -2.7857 0.2873 -9.696 < 2e-16 ***
## colourblack -1.4535 0.6207 -2.342 0.01919 *
## colourwhite -0.9977 0.4570 -2.183 0.02904 *
## Sidedorsal:colourblack 1.4252 0.4776 2.984 0.00284 **
## Sidedorsal:colourwhite 1.9959 0.3488 5.722 1.05e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Anova(colour_light1,type=3)
## Analysis of Deviance Table (Type III Wald chisquare tests)
##
## Response: b_luxes
## Chisq Df Pr(>Chisq)
## (Intercept) 1.7332 1 0.188
## Side 94.0183 1 < 2.2e-16 ***
## colour 7.1512 2 0.028 *
## Side:colour 32.8057 2 7.522e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Run the model with black and dorsal as fixed levels
$colour<-relevel(as.factor(tmp_ind$colour),"black")
tmp_ind$Side<-relevel(as.factor(tmp_ind$Side),"dorsal")
tmp_ind<-glmmTMB(formula=b_luxes ~ Side*colour + (1|code) + (1|day),
colour_light2family="binomial",data=tmp_ind)
Check the significance of the predictors
summary(colour_light2)
## Family: binomial ( logit )
## Formula: b_luxes ~ Side * colour + (1 | code) + (1 | day)
## Data: tmp_ind
##
## AIC BIC logLik deviance df.resid
## 1485.9 1529.7 -734.9 1469.9 1770
##
## Random effects:
##
## Conditional model:
## Groups Name Variance Std.Dev.
## code (Intercept) 3.9749 1.994
## day (Intercept) 0.4597 0.678
## Number of obs: 1778, groups: code, 129; day, 6
##
## Conditional model:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -3.41165 0.63944 -5.335 9.53e-08 ***
## Sideventral 1.36046 0.38597 3.525 0.000424 ***
## colouryellow 0.02826 0.68811 0.041 0.967236
## colourwhite 1.02645 0.63868 1.607 0.108024
## Sideventral:colouryellow 1.42520 0.47755 2.984 0.002841 **
## Sideventral:colourwhite -0.57068 0.43453 -1.313 0.189072
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Anova(colour_light2,type=3)
## Analysis of Deviance Table (Type III Wald chisquare tests)
##
## Response: b_luxes
## Chisq Df Pr(>Chisq)
## (Intercept) 28.4665 1 9.534e-08 ***
## Side 12.4243 1 0.0004238 ***
## colour 5.1592 2 0.0758037 .
## Side:colour 32.8061 2 7.520e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Let’s visualize the results
#Predict the values based on the model
$predicted_light<-predict(colour_light1,type="response")
tmp_ind#Colours
$colour<-relevel(as.factor(tmp_ind$colour),"white")
tmp_ind$Side<-relevel(as.factor(tmp_ind$Side),"dorsal")
tmp_ind<-c("#f0f0f0","#636363","#ffeda0")
paleta2#Plot
ggplot(data = tmp_ind,aes(x=Side,y=predicted_light, fill=colour))+
scale_y_continuous(limits=c(0,1))+labs(x="Spider side",y="Light environment")+
scale_fill_manual(values=paleta2)+
scale_colour_manual(values=paleta2)+
stat_summary(fun = mean,aes(color = colour,group=colour),fun.min = function(x) mean(x) - (2*se(x)),fun.max = function(x) mean(x)+(2*se(x)),geom = "pointrange", shape=22,col="black",position = position_jitterdodge(jitter.width=0.15), size=1)+
theme_classic()
we compared dorsal and ventral light measures of each individual, where the higher measure was considered as open space and the lower measure as vegetation. We did this for everyday of observation. The following code will create a new dataset.
<-data.frame()
unique_ind2for(d in unique(tmp_ind$day)){
<-tmp_ind %>% filter(day==d & Time==6.3)
sub<-rbind(unique_ind2,sub)
unique_ind2
}<-tibble(code=character(),side=character(),open_space=numeric(),day=numeric())
side_datafor(d in unique(unique_ind2$day)){
<-unique_ind2 %>% filter(day==d)
filtered_day<-tibble(code=character(),side=character(),open_space=numeric(),day=numeric())
tmpfor(ind in unique(filtered_day$code)) {
<-filtered_day %>% filter(code==ind & Side=="dorsal")
dorsal<-filtered_day %>% filter(code==ind & Side=="ventral")
ventralif(nrow(ventral)==0 | nrow(dorsal)==0){next}
else if(ventral$luxes>dorsal$luxes){
<-tibble(code=ind,side="ventral",open_space=1,day=d)
ventral<-tibble(code=ind,side="dorsal",open_space=0,day=d)
dorsal<-rbind(tmp,ventral,dorsal)
tmpelse if(ventral$luxes<dorsal$luxes){
} <-tibble(code=ind,side="ventral",open_space=0,day=d)
ventral<-tibble(code=ind,side="dorsal",open_space=1,day=d)
dorsal<-rbind(tmp,ventral,dorsal)
tmp
}
}<-rbind(side_data,tmp)
side_data }
Let’s evaluate if the new categorization is independent of how the spider position its body towards the different light conditions (High or Low luminosity)
<-chisq.test(factor(unique_ind2$t_luxes),factor(unique_ind2$site_exp))
test_association test_association
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: factor(unique_ind2$t_luxes) and factor(unique_ind2$site_exp)
## X-squared = 2.1355, df = 1, p-value = 0.1439
Because we did not find association, let’s run an independent model
<-glmmTMB(formula=open_space ~ side+ (1|day) + (1|code),family="binomial",data=side_data) #test which side is most open_side
Check the model’s fit
<- simulateResiduals(fittedModel = open_side, n = 1000)
simulationOutput testDispersion(simulationOutput = simulationOutput, alternative ="two.sided")
testUniformity(simulationOutput = simulationOutput, alternative ="two.sided")
Check the significance of the predictor
summary(open_side)
## Family: binomial ( logit )
## Formula: open_space ~ side + (1 | day) + (1 | code)
## Data: side_data
##
## AIC BIC logLik deviance df.resid
## 601.9 618.4 -297.0 593.9 450
##
## Random effects:
##
## Conditional model:
## Groups Name Variance Std.Dev.
## day (Intercept) 1.099e-11 3.315e-06
## code (Intercept) 4.651e-10 2.157e-05
## Number of obs: 454, groups: day, 6; code, 129
##
## Conditional model:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.5700 0.1382 -4.125 3.70e-05 ***
## sideventral 1.1400 0.1954 5.834 5.41e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Anova(open_side)
## Analysis of Deviance Table (Type II Wald chisquare tests)
##
## Response: open_space
## Chisq Df Pr(>Chisq)
## side 34.038 1 5.406e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
We explored the effect of the presence of the presence of the spiders on the web. We also included the presence of silk decorations as a predictor
$colour<-relevel(as.factor(tmp_noNA$colour),"empty")
tmp_noNA$Time<-relevel(as.factor(tmp_noNA$Time),"6.3")
tmp_noNA<-glmmTMB(formula=total_preys ~ colour+sqrt(web_area+10)+presence_decorations + check + (1|code) + (1|day/Time),family="poisson",REML=F,data=tmp_noNA) with_control_model
Check the uniformity, dispersion and zero inflation of the model
<- simulateResiduals(fittedModel = with_control_model, n = 10000)
simulationOutput testDispersion(simulationOutput = simulationOutput, alternative ="two.sided")
##
## DHARMa nonparametric dispersion test via sd of residuals fitted vs.
## simulated
##
## data: simulationOutput
## dispersion = 1.1036, p-value = 0.5726
## alternative hypothesis: two.sided
testUniformity(simulationOutput = simulationOutput, alternative ="two.sided")
##
## One-sample Kolmogorov-Smirnov test
##
## data: simulationOutput$scaledResiduals
## D = 0.055171, p-value = 7.514e-06
## alternative hypothesis: two-sided
testZeroInflation(simulationOutput = simulationOutput, alternative ="two.sided")
##
## DHARMa zero-inflation test via comparison to expected zeros with
## simulation under H0 = fitted model
##
## data: simulationOutput
## ratioObsSim = 1.0595, p-value = 0.1614
## alternative hypothesis: two.sided
Because there is not uniformity of the residuals when using a poisson distribution, we run the model again with a negative binomial distribution
$colour<-relevel(as.factor(tmp_noNA$colour),"empty")
tmp_noNA$Time<-relevel(as.factor(tmp_noNA$Time),"6.3")
tmp_noNA<-glmmTMB(formula=total_preys ~ colour+sqrt(web_area+10)+presence_decorations + check + (1|code) + (1|day/Time),family="nbinom2",REML=F,data=tmp_noNA) with_control_model
Check the uniformity, dispersion and zero inflation of the model
<- simulateResiduals(fittedModel = with_control_model, n = 10000)
simulationOutput testDispersion(simulationOutput = simulationOutput, alternative ="two.sided")
##
## DHARMa nonparametric dispersion test via sd of residuals fitted vs.
## simulated
##
## data: simulationOutput
## dispersion = 0.57703, p-value = 0.4786
## alternative hypothesis: two.sided
testUniformity(simulationOutput = simulationOutput, alternative ="two.sided")
##
## One-sample Kolmogorov-Smirnov test
##
## data: simulationOutput$scaledResiduals
## D = 0.02864, p-value = 0.06903
## alternative hypothesis: two-sided
testZeroInflation(simulationOutput = simulationOutput, alternative ="two.sided")
##
## DHARMa zero-inflation test via comparison to expected zeros with
## simulation under H0 = fitted model
##
## data: simulationOutput
## ratioObsSim = 1.0122, p-value = 0.7122
## alternative hypothesis: two.sided
everything seems ok
Check the significance of the predictors
summary(with_control_model)
## Family: nbinom2 ( log )
## Formula:
## total_preys ~ colour + sqrt(web_area + 10) + presence_decorations +
## check + (1 | code) + (1 | day/Time)
## Data: tmp_noNA
##
## AIC BIC logLik deviance df.resid
## 2135.1 2202.6 -1055.6 2111.1 2040
##
## Random effects:
##
## Conditional model:
## Groups Name Variance Std.Dev.
## code (Intercept) 0.1192 0.3452
## Time:day (Intercept) 0.1922 0.4384
## day (Intercept) 0.2696 0.5193
## Number of obs: 2052, groups: code, 150; Time:day, 23; day, 6
##
## Dispersion parameter for nbinom2 family (): 0.339
##
## Conditional model:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -1.45213 0.48582 -2.989 0.0028 **
## colourblack -1.19340 0.26087 -4.575 4.77e-06 ***
## colourwhite -1.11115 0.21595 -5.145 2.67e-07 ***
## colouryellow -1.18243 0.22258 -5.312 1.08e-07 ***
## sqrt(web_area + 10) 0.03853 0.01995 1.931 0.0534 .
## presence_decorationsyes -0.10909 0.16922 -0.645 0.5192
## checkF 0.00459 0.19537 0.023 0.9813
## checkM -0.18729 0.18275 -1.025 0.3054
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Anova(with_control_model)
## Warning in printHypothesis(L, rhs, names(b)): one or more coefficients in the hypothesis include
## arithmetic operators in their names;
## the printed representation of the hypothesis will be omitted
## Analysis of Deviance Table (Type II Wald chisquare tests)
##
## Response: total_preys
## Chisq Df Pr(>Chisq)
## colour 36.9717 3 4.665e-08 ***
## sqrt(web_area + 10) 3.7301 1 0.05344 .
## presence_decorations 0.4155 1 0.51917
## check 1.4183 2 0.49207
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
the presence of any of the colour morphs on the web seems to reduce the capture of prey
<-c("#648ace","#636363","#f0f0f0","#ffeda0")
paleta2#pdf("dorsal.pdf",height=8,width=10)
$total_response<-predict(with_control_model,type="response")
tmp_noNAggplot(data = tmp_noNA,aes(x=colour,y=total_response))+
geom_point(data = tmp_noNA,aes(x=colour,y=total_preys, fill=colour),shape = 21,size=3, position = position_jitterdodge(jitter.width=0.2,jitter.height=0.1),alpha=0.5)+
scale_fill_manual(values=paleta2)+
geom_violin(aes(x=colour,y=total_response,fill=colour),alpha=0.3,size=0.4)+scale_color_manual(values=paleta2)+
stat_summary(fun = mean,aes(group=colour,col=colour),fun.min = function(x) mean(x) - sd(x),fun.max = function(x) mean(x)+sd(x),geom = "pointrange",linewidth = 2,size=1.5,shape=22,col="black",fill=paleta2)+
theme_classic()+labs(x="Colour",y="Number of prey capture per hour")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## i Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Run the model with white and ventral as fixed levels
$colour<-relevel(as.factor(tmp_ind$colour),"white")
tmp_ind$Side<-relevel(as.factor(tmp_ind$Side),"ventral")
tmp_ind$Time<-relevel(as.factor(tmp_ind$Time),"6.3")
tmp_ind<-glmmTMB::glmmTMB(formula=total_preys ~ Side+colour+t_luxes+sqrt(web_area+10)+ check + (1|code) + (1|day/Time),family="poisson",REML=F,data=tmp_ind) total_model_poisson
<-glmmTMB::glmmTMB(formula=total_preys ~ Side+colour+t_luxes+sqrt(web_area+10)+ check + (1|code) + (1|day/Time),family="poisson",REML=F,data=tmp_ind) total_model_poisson
Test the fit of the model and zero inflation
<- simulateResiduals(fittedModel = total_model_poisson, n = 10000)
simulationOutput testDispersion(simulationOutput = simulationOutput, alternative ="two.sided")
##
## DHARMa nonparametric dispersion test via sd of residuals fitted vs.
## simulated
##
## data: simulationOutput
## dispersion = 1.2804, p-value = 0.3496
## alternative hypothesis: two.sided
testUniformity(simulationOutput = simulationOutput, alternative ="two.sided")
##
## One-sample Kolmogorov-Smirnov test
##
## data: simulationOutput$scaledResiduals
## D = 0.047735, p-value = 0.0006053
## alternative hypothesis: two-sided
testZeroInflation(simulationOutput = simulationOutput, alternative ="two.sided")
##
## DHARMa zero-inflation test via comparison to expected zeros with
## simulation under H0 = fitted model
##
## data: simulationOutput
## ratioObsSim = 1.04, p-value = 0.2346
## alternative hypothesis: two.sided
Because this model has no uniformity; its is necessary to try other model that takes this into account
<-glmmTMB::glmmTMB(formula=total_preys ~ colour+Side+t_luxes+sqrt(web_area+10)+ check + (1|code) + (1|day/Time),family="nbinom2",REML=F,data=tmp_ind) total_model_nb
Test the fit of the model and zero inflation
<- simulateResiduals(fittedModel = total_model_nb, n = 10000)
simulationOutput testDispersion(simulationOutput = simulationOutput, alternative ="two.sided")
##
## DHARMa nonparametric dispersion test via sd of residuals fitted vs.
## simulated
##
## data: simulationOutput
## dispersion = 0.7817, p-value = 0.8058
## alternative hypothesis: two.sided
testUniformity(simulationOutput = simulationOutput, alternative ="two.sided")
##
## One-sample Kolmogorov-Smirnov test
##
## data: simulationOutput$scaledResiduals
## D = 0.018165, p-value = 0.6004
## alternative hypothesis: two-sided
testZeroInflation(simulationOutput = simulationOutput, alternative ="two.sided")
##
## DHARMa zero-inflation test via comparison to expected zeros with
## simulation under H0 = fitted model
##
## data: simulationOutput
## ratioObsSim = 1.0086, p-value = 0.7794
## alternative hypothesis: two.sided
This model seems to be ok, let’s now check the significance of the predictors
summary(total_model_nb)
## Family: nbinom2 ( log )
## Formula:
## total_preys ~ colour + Side + t_luxes + sqrt(web_area + 10) +
## check + (1 | code) + (1 | day/Time)
## Data: tmp_ind
##
## AIC BIC logLik deviance df.resid
## 1625.4 1691.2 -800.7 1601.4 1766
##
## Random effects:
##
## Conditional model:
## Groups Name Variance Std.Dev.
## code (Intercept) 0.2037 0.4513
## Time:day (Intercept) 0.2596 0.5095
## day (Intercept) 0.2066 0.4546
## Number of obs: 1778, groups: code, 129; Time:day, 23; day, 6
##
## Dispersion parameter for nbinom2 family (): 0.387
##
## Conditional model:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -3.10971 0.56554 -5.499 3.83e-08 ***
## colourblack -0.17275 0.25510 -0.677 0.498281
## colouryellow -0.12137 0.20569 -0.590 0.555169
## Sidedorsal 0.18636 0.15710 1.186 0.235528
## t_luxeslow 0.72967 0.22143 3.295 0.000983 ***
## sqrt(web_area + 10) 0.03035 0.02287 1.327 0.184353
## checkF 0.04343 0.23224 0.187 0.851646
## checkM -0.35026 0.20964 -1.671 0.094773 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Anova(total_model_nb,type = 3)
## Warning in printHypothesis(L, rhs, names(b)): one or more coefficients in the hypothesis include
## arithmetic operators in their names;
## the printed representation of the hypothesis will be omitted
## Analysis of Deviance Table (Type III Wald chisquare tests)
##
## Response: total_preys
## Chisq Df Pr(>Chisq)
## (Intercept) 30.2355 1 3.826e-08 ***
## colour 0.6111 2 0.7367028
## Side 1.4072 1 0.2355283
## t_luxes 10.8590 1 0.0009831 ***
## sqrt(web_area + 10) 1.7622 1 0.1843529
## check 3.9086 2 0.1416656
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
To create the plot for the results, we have to predict the values under the model
#Predict values to plot
$response_nb<-predict(total_model_nb,type="response") tmp_ind
With this, we can create two plots, one per side in order to make easy to visualize the results
###Plot dorsal
Create subset
<- tmp_ind %>% filter(Side=="dorsal")
plot_dorsal $colour<-relevel(as.factor(plot_dorsal$colour),"black") plot_dorsal
Plot the results
#Colours
<-c("#636363","#f0f0f0","#ffeda0")
paleta2#plot
#pdf("dorsal.pdf",height=8,width=10)
ggplot(data = plot_dorsal,aes(x=t_luxes,y=response_nb, fill=colour))+
geom_point(data = plot_dorsal,aes(x=t_luxes,y=total_preys, fill=colour),shape = 21,size=4, position = position_jitterdodge(jitter.width=0.15,jitter.height=0.1),alpha=1.0)+
scale_fill_manual(values=paleta2)+
#geom_violin(aes(fill=colour),alpha=0.3,size=0.4)+scale_color_manual(values=paleta2)+
stat_summary(fun = mean,aes(color = colour,group=colour),fun.min = function(x) mean(x) - sd(x),fun.max = function(x) mean(x)+sd(x),geom = "pointrange", position = position_jitterdodge(jitter.width=0.01), linewidth = 2,size=1.5,shape=22, col="black")+
theme_classic()+labs(x="Light environment",y="Number of prey capture per hour")
###Plot ventral
Create subset
<- tmp_ind %>% filter(Side=="ventral")
plot_ventral $colour<-relevel(as.factor(plot_ventral$colour),"black") plot_ventral
Plot the results
#Colours
<-c("#636363","#f0f0f0","#ffeda0")
paleta2#plot
ggplot(data = plot_ventral,aes(x=t_luxes,y=response_nb, fill=colour))+
geom_point(data = plot_ventral,aes(x=t_luxes,y=total_preys, fill=colour),shape = 21,size=4, position = position_jitterdodge(jitter.width=0.15,jitter.height=0.1),alpha=1.0)+
scale_fill_manual(values=paleta2)+
#geom_violin(aes(fill=colour),alpha=0.3,size=0.4)+scale_color_manual(values=paleta2)+
stat_summary(fun = mean,aes(color = colour,group=colour),fun.min = function(x) mean(x) - sd(x),fun.max = function(x) mean(x)+sd(x),geom = "pointrange", position = position_jitterdodge(jitter.width=0.01), linewidth = 2,size=1.5,shape=22, col="black")+
theme_classic()+labs(x="Light environment",y="Number of prey capture per hour")
###Plot by light condition
#Colours
<-c("#c5dd8f","#5db23a")
paleta2#pdf("light_prey.pdf",height=8,width=10)
#plot
ggplot(data = plot_dorsal,aes(x=t_luxes,y=response_nb, fill=t_luxes))+
geom_point(data = plot_dorsal,aes(x=t_luxes,y=total_preys, fill=t_luxes),shape = 21,size=4, position = position_jitterdodge(jitter.width=0.15,jitter.height=0.1),alpha=0.2)+
scale_fill_manual(values=paleta2)+
stat_summary(fun = mean,aes(color = t_luxes,group=t_luxes),fun.min = function(x) mean(x) - sd(x),fun.max = function(x) mean(x)+sd(x),geom = "pointrange", size=1.5, shape=22, col="black")+
theme_classic()+labs(x="Light environment",y="Number of prey capture per hour")
%>% filter(total_preys>0) %>% drop_na(Preys_ID) %>% pull(Preys_ID) %>% table() %>% prop.table() tmp_ind
## .
## coleoptera diptera hemiptera homoptera hymenoptera lepidoptera
## 0.01775148 0.82840237 0.02958580 0.01183432 0.08875740 0.01775148
## neuroptera
## 0.00591716
<-tmp_ind %>% filter(total_preys>0) %>% drop_na(Preys_ID) %>% select(colour,Preys_ID,total_preys) %>% uncount(total_preys)
preys
prop.table(table(preys$Preys_ID))*100
##
## coleoptera diptera hemiptera homoptera hymenoptera lepidoptera
## 1.5094340 86.4150943 2.2641509 0.7547170 7.1698113 1.5094340
## neuroptera
## 0.3773585
<-c("#f0f0f0","#636363","#ffeda0")
paleta2%>% ggplot(aes(x=Preys_ID,fill=colour)) + geom_bar(aes(y = after_stat((count/sum(count))*100)),colour="black") + scale_fill_manual(values=paleta2)+theme_classic()+scale_y_continuous(breaks=seq(0,100,10))+labs(y="Percentage of idenfied",x="Prey order") preys