This is a R Markdown Notebook, provided as supporting information for the manuscript “Flight performance and wing morphology in the bat Carollia perspicillata: biophysical models and energetics”.
For proper compilation, all data and function files provided need to be in the same folder.
Start by loading required libraries
#Load required libraries
require(paran)
require(ggplot2)
require(metR)
require(FactoMineR)
require(factoextra)
require(car)
require(rsm)
require(knitr)
Loading required package: knitr
Next, the calculations of heat loss for separate body surfaces during
flight are done, reading data frames and using the function provided in
the file HeatLoss.R.
#Heat Loss calculation for each body part
source("HeatLoss.R")
#Read Body surface data
bodyTA<-read.table("BodyTA.txt",header=T,row.names = 1)
QtBody<-HLoss(bodyTA)
HeadTA<-read.table("HeadTA.txt",header=T,row.names = 1)
QtHead<-HLoss(HeadTA)
WingTA<-read.table("WingTA.txt",header=T,row.names = 1)
QtWing<-HLoss(WingTA)
ArmTA<-read.table("ArmTA.txt",header=T,row.names = 1)
QtArm<-HLoss(ArmTA)
Read wing morphology data, create a data frame with morphology variable for PCA, and calculate derived variables (AR, WL) and the total heat loss summing all body surfaces.
The morphological variable names are:
ID - Animal ID (color and necklace number)
Sex - sex factor: M = males, F = females
B - Wing span (m)
S - Wing Area (m^2) (sum of both sides plus bodyarea)
M - Body Mass (Kg)
ForL - Forearm length (mm)
WTip - Wing tip (Mm)
WLength - Wing length (mm)
DgIIIPh1 - Length of the 3rd digit of the 1st phalange (mm)
DgIIIPh2 - Length of the 3rd digit of the 2nd phalange (mm)
DgIIIPh3 - Length of the 3rd digit of the 3rd phalange (mm)
DgVMt - Length of the 5th digit of the metacarpal (mm)
DgVPh1- Length of the 5th digit of the 1st phalange (mm)
DgVPh2 - Length of the 5th digit of the 2nd phalange (mm)
Dactyl - Dactylopatagium width (mm)
Warea - Wing area (only left side) (mm^2)
DactArea - Dactylopatagium area (mm^2)
#read data, animal IDs are row names
qt<-read.table("WingMorph.txt",header=T,row.names = 1)
qt$Sex<-factor(qt$Sex)
#Separate wing morphology variables for PCA
Wing<-qt[,4:16]
#Calculate aspect ratio
qt$AR<-(qt$B^2)/qt$S
#Calculate wing loading
qt$WL<-(qt$M*9.81)/qt$S
#Add heat loss to main data frame, corrected for mechanical efficiency of 8.7%
qt$Qt<-(QtBody$Qt+QtHead$Qt+QtWing$Qt+QtArm$Qt)/(1-0.087)
Calculate minimum power required to fly, using the function in file ‘PowFlight.R’, and add it to the main data frame.
#Calculation of Pmin (minimum power required to fly horizontally)
source("PowFlight.R")
Powm<-PowFly(qt)
qt$Pmin<-Powm$mP
#MaxR = maximum range, not used in models because it is correlated with Pmin
qt$MaxR<-Powm$MaxR
#Vmp = minimum power speed, not used in models because it is correlated with Pmin
qt$Vmp<-Powm$Vmp
Calculate number of dimensions to retain using parallel analysis
paran(Wing,graph=T,all=T)
Using eigendecomposition of correlation matrix.
Computing: 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
Results of Horn's Parallel Analysis for component retention
390 iterations, using the mean estimate
--------------------------------------------------
Component Adjusted Unadjusted Estimated
Eigenvalue Eigenvalue Bias
--------------------------------------------------
1 4.200816 4.796752 0.595936
2 1.314579 1.754888 0.440309
3 1.085290 1.405174 0.319883
4 0.760734 0.980557 0.219823
5 0.672904 0.804407 0.131503
6 0.671573 0.720502 0.048929
7 0.641264 0.612963 -0.02830
8 0.630732 0.526721 -0.10401
9 0.590322 0.413899 -0.17642
10 0.589626 0.342076 -0.24754
11 0.635438 0.314139 -0.32129
12 0.638933 0.242730 -0.39620
13 0.567783 0.085182 -0.48260
--------------------------------------------------
Adjusted eigenvalues > 1 indicate dimensions to retain.
(3 components retained)
Parallel analysis identified 3 PCs with larger eigenvalues than expected in a random distribution. Next, generate a PCA object with 3 axes.
PCWing<-PCA(Wing,ncp=3)
Description of PCs, based on correlations with variables.
kables(list(kable("**Correlations**",col.names = NULL),kable(PCWing$var$cor),kable("**Contribution (%)**",col.names = NULL),kable(PCWing$var$contrib)),caption = "**Table S1. Description of PCs (Dim.1-Dim.3), based on correlations of scores with variables, and the percentage contribution of each variable to the given component**")
| Correlations |
| Dim.1 | Dim.2 | Dim.3 | |
|---|---|---|---|
| M | 0.3930441 | 0.0357618 | -0.1001526 |
| ForL | 0.7308137 | -0.2824303 | -0.1149222 |
| WTip | 0.6417254 | -0.3058741 | 0.2054238 |
| WLength | 0.7401456 | -0.4213380 | 0.1362644 |
| DgIIIPh1 | 0.7178556 | 0.0489367 | -0.1991975 |
| DgIIIPh2 | 0.3370307 | 0.1107531 | -0.6783921 |
| DgIIIPh3 | -0.0295857 | -0.3541331 | 0.7739853 |
| DgVMt | 0.7557868 | -0.2266024 | -0.0492903 |
| DgVPh1 | 0.6799445 | -0.0313326 | -0.1525218 |
| DgVPh2 | 0.5936091 | 0.2221052 | 0.0231415 |
| Dactyl | 0.4057258 | 0.8122598 | 0.3129717 |
| Warea | 0.7934823 | -0.0766917 | 0.1642200 |
| DactArea | 0.5819228 | 0.7038311 | 0.2665968 |
| Contribution (%) |
| Dim.1 | Dim.2 | Dim.3 | |
|---|---|---|---|
| M | 3.2205882 | 0.0728769 | 0.7138284 |
| ForL | 11.1343815 | 4.5454098 | 0.9398906 |
| WTip | 8.5852130 | 5.3313321 | 3.0031106 |
| WLength | 11.4205482 | 10.1160689 | 1.3214015 |
| DgIIIPh1 | 10.7430312 | 0.1364644 | 2.8238231 |
| DgIIIPh2 | 2.3680544 | 0.6989754 | 32.7515036 |
| DgIIIPh3 | 0.0182481 | 7.1463351 | 42.6319435 |
| DgVMt | 11.9083419 | 2.9260355 | 0.1728990 |
| DgVPh1 | 9.6382804 | 0.0559427 | 1.6555164 |
| DgVPh2 | 7.3460477 | 2.8110460 | 0.0381111 |
| Dactyl | 3.4317673 | 37.5958897 | 6.9707547 |
| Warea | 13.1258434 | 0.3351563 | 1.9192072 |
| DactArea | 7.0596546 | 28.2284672 | 5.0580102 |
#Prepare data frames for biplot
#Save variable coordinates
PCvar<-as.data.frame(PCWing$var$coord[,1:3])
#Invert PC2 variable coordinates for convenience of interpretation
PCvar$Dim.2<--PCvar$Dim.2
#Save individual scores
PCind<-as.data.frame(PCWing$ind$coord[,1:3])
#Invert PC2 individual scores for convenience of interpretation
PCind$Dim.2<--PCind$Dim.2
#PCA Biplot (Figure 3)
#Create sex factor in numeric form to change point shape in plot
Sexpch<-c(16,17)[as.numeric(qt$Sex)]
#Biplot
ggplot(PCind,aes(x=Dim.1,y=Dim.2))+
geom_point(size=4,shape=Sexpch,)+
labs(y="PC2 (13.50%)", x="PC1 (36.90%)")+
geom_text(data=PCvar*4.5,label=variable.names(Wing),colour="darkred",size=5)+
geom_segment(data=PCvar,
aes(x = 0, y = 0, xend = Dim.1*4, yend = Dim.2*4),
arrow = arrow(
length = unit(0.015,"npc"),
type="closed" # Describes arrow head (open or closed)
),
colour = "darkred",
size = 0.8,
)+theme(text = element_text(size=rel(4.5)),panel.border=element_rect(linetype="solid",fill=NA))
Scatterplot for aspect ratio and wing loading
#Scatterplot for aspect ratio and wing loading
ggplot(qt,aes(x=WL,y=AR))+
geom_point(size=4,shape=Sexpch,)+
labs(y="Aspect Ratio", x=expression(paste("Wing Loading "(Nm^-2))))+
theme(text = element_text(size=rel(4.5)),panel.border=element_rect(linetype="solid",fill=NA))
Independent variables in RSMs are standardized, so the model coefficients show changes in the response for each standard deviation of the predictor.
#Send PC scores to qt data frame, standardizing to sd=1
qt$PC1<-scale(PCind$Dim.1)
qt$PC2<-scale(PCind$Dim.2)
qt$PC3<-scale(PCind$Dim.3)
#Standardize AR and WL.
qt$sAR<-scale(qt$AR)
qt$sWL<-scale(qt$WL)
Models fitting Pmin as response, Sex, AR and WL as predictors. We started fitting the model as second order
pwaw.rsm<-rsm(Pmin~Sex+SO(sAR,sWL),data=qt)
kables(list(kable("**Coefficients**",col.names=NULL), kable(summary(pwaw.rsm)$coefficients),kable("**ANOVA**",col.names=NULL), kable(summary(pwaw.rsm)$lof)), caption = "**Table S2. Coefficients and analysis of variance of response surface model with Pmin as response and Sex, AR, and WL as predictors**")
Near-stationary-ridge situation detected -- stationary point altered
Change 'threshold' if this is not what you intend
Near-stationary-ridge situation detected -- stationary point altered
Change 'threshold' if this is not what you intend
| Coefficients |
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | 0.0606634 | 0.0005608 | 108.1674487 | 0.0000000 |
| SexM | -0.0000129 | 0.0006136 | -0.0210137 | 0.9832731 |
| sAR | -0.0037887 | 0.0002961 | -12.7975896 | 0.0000000 |
| sWL | 0.0076974 | 0.0003451 | 22.3049325 | 0.0000000 |
| sAR:sWL | -0.0009239 | 0.0003299 | -2.8007187 | 0.0060338 |
| sAR^2 | 0.0004849 | 0.0002299 | 2.1086880 | 0.0372623 |
| sWL^2 | 0.0004675 | 0.0002813 | 1.6620954 | 0.0993670 |
| ANOVA |
| Df | Sum Sq | Mean Sq | F value | Pr(>F) | |
|---|---|---|---|---|---|
| Sex | 1 | 0.0008487 | 0.0008487 | 100.365161 | 0.0000000 |
| FO(sAR, sWL) | 2 | 0.0055490 | 0.0027745 | 328.110021 | 0.0000000 |
| TWI(sAR, sWL) | 1 | 0.0000236 | 0.0000236 | 2.795881 | 0.0973751 |
| PQ(sAR, sWL) | 2 | 0.0000543 | 0.0000272 | 3.211301 | 0.0441461 |
| Residuals | 109 | 0.0009217 | 0.0000085 | NA | NA |
| Lack of fit | 109 | 0.0009217 | 0.0000085 | NaN | NaN |
| Pure error | 0 | 0.0000000 | NaN | NA | NA |
Model summary coefficients and analysis of variance indicate a quadratic component, so second order model is retained. Sex is removed from the model. It might be collinear with WL.
pwaw.rsm2<-rsm(Pmin~SO(sAR,sWL),data=qt)
kables(list(kable("**Coefficients**", col.names=NULL), kable(summary(pwaw.rsm2)$coefficients),kable("**ANOVA**",col.names=NULL), kable(summary(pwaw.rsm2)$lof)), caption = "**Table S3. Coefficients and analysis of variance of response surface model with Pmin as response and AR and WL as predictors**")
Near-stationary-ridge situation detected -- stationary point altered
Change 'threshold' if this is not what you intend
Near-stationary-ridge situation detected -- stationary point altered
Change 'threshold' if this is not what you intend
| Coefficients |
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | 0.0606556 | 0.0004180 | 145.099172 | 0.0000000 |
| sAR | -0.0037885 | 0.0002945 | -12.862482 | 0.0000000 |
| sWL | 0.0076943 | 0.0003113 | 24.714144 | 0.0000000 |
| sAR:sWL | -0.0009240 | 0.0003284 | -2.813681 | 0.0058032 |
| sAR^2 | 0.0004858 | 0.0002244 | 2.165373 | 0.0325193 |
| sWL^2 | 0.0004680 | 0.0002788 | 1.678789 | 0.0960317 |
| ANOVA |
| Df | Sum Sq | Mean Sq | F value | Pr(>F) | |
|---|---|---|---|---|---|
| FO(sAR, sWL) | 2 | 0.0063967 | 0.0031984 | 381.705934 | 0.0000000 |
| TWI(sAR, sWL) | 1 | 0.0000221 | 0.0000221 | 2.632569 | 0.1075549 |
| PQ(sAR, sWL) | 2 | 0.0000568 | 0.0000284 | 3.390698 | 0.0372431 |
| Residuals | 110 | 0.0009217 | 0.0000084 | NA | NA |
| Lack of fit | 110 | 0.0009217 | 0.0000084 | NaN | NaN |
| Pure error | 0 | 0.0000000 | NaN | NA | NA |
Check model residuals for trends (no trends observed)
plot(predict(pwaw.rsm2),resid(pwaw.rsm2),xlab="Predicted",ylab = "Residuals")
Models fitting Pmin as response, Sex and PC scores as predictors. We started fitting model as second order, including the first three PCs:
pwpc.rsm<-rsm(Pmin~Sex+SO(PC1,PC2,PC3),data=qt)
kables(list(kable("**Coefficients**", col.names=NULL), kable(summary(pwpc.rsm)$coefficients),kable("**ANOVA**",col.names=NULL), kable(summary(pwpc.rsm)$lof)), caption = "**Table S4. Coefficients and analysis of variance of response surface model with Pmin as response and Sex and PC scores as predictors**")
| Coefficients |
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | 0.0568601 | 0.0012349 | 46.0434340 | 0.0000000 |
| SexM | 0.0045790 | 0.0012854 | 3.5622360 | 0.0005544 |
| PC1 | 0.0021145 | 0.0006329 | 3.3408988 | 0.0011573 |
| PC2 | -0.0019698 | 0.0006708 | -2.9363502 | 0.0040813 |
| PC3 | -0.0012024 | 0.0006493 | -1.8517957 | 0.0668648 |
| PC1:PC2 | -0.0026303 | 0.0006671 | -3.9431467 | 0.0001454 |
| PC1:PC3 | 0.0006649 | 0.0006533 | 1.0176791 | 0.3111697 |
| PC2:PC3 | 0.0002733 | 0.0006733 | 0.4059267 | 0.6856225 |
| PC1^2 | -0.0005764 | 0.0005210 | -1.1064029 | 0.2710806 |
| PC2^2 | 0.0012071 | 0.0004385 | 2.7530370 | 0.0069587 |
| PC3^2 | 0.0015462 | 0.0004895 | 3.1586718 | 0.0020701 |
| ANOVA |
| Df | Sum Sq | Mean Sq | F value | Pr(>F) | |
|---|---|---|---|---|---|
| Sex | 1 | 0.0008487 | 0.0008487 | 19.577895 | 0.0000237 |
| FO(PC1, PC2, PC3) | 3 | 0.0005919 | 0.0001973 | 4.551439 | 0.0048649 |
| TWI(PC1, PC2, PC3) | 3 | 0.0005490 | 0.0001830 | 4.221429 | 0.0073385 |
| PQ(PC1, PC2, PC3) | 3 | 0.0008561 | 0.0002854 | 6.582840 | 0.0004038 |
| Residuals | 105 | 0.0045517 | 0.0000433 | NA | NA |
| Lack of fit | 105 | 0.0045517 | 0.0000433 | NaN | NaN |
| Pure error | 0 | 0.0000000 | NaN | NA | NA |
Model summary coefficients and the analysis of variance indicate a quadratic component, so the second order model is retained. PC3 did not contribute to surface (coefficients not statistically significant), so it was excluded.
pwpc.rsm2<-rsm(Pmin~Sex+SO(PC1,PC2),data=qt)
kables(list(kable("**Coefficients**", col.names=NULL), kable(summary(pwpc.rsm2)$coefficients),kable("**ANOVA**",col.names=NULL), kable(summary(pwpc.rsm2)$lof)), caption = "**Table S5. Coefficients and analysis of variance of response surface model with Pmin as response and PC scores as predictors**")
| Coefficients |
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | 0.0582617 | 0.0011466 | 50.8119168 | 0.0000000 |
| SexM | 0.0044604 | 0.0013225 | 3.3726618 | 0.0010313 |
| PC1 | 0.0020258 | 0.0006626 | 3.0573891 | 0.0028090 |
| PC2 | -0.0017650 | 0.0006889 | -2.5622223 | 0.0117657 |
| PC1:PC2 | -0.0020339 | 0.0006784 | -2.9979953 | 0.0033666 |
| PC1^2 | -0.0004974 | 0.0005390 | -0.9229185 | 0.3580882 |
| PC2^2 | 0.0013193 | 0.0004581 | 2.8797220 | 0.0047925 |
| ANOVA |
| Df | Sum Sq | Mean Sq | F value | Pr(>F) | |
|---|---|---|---|---|---|
| Sex | 1 | 0.0008487 | 0.0008487 | 17.743813 | 0.0000522 |
| FO(PC1, PC2) | 2 | 0.0005659 | 0.0002830 | 5.916014 | 0.0036377 |
| TWI(PC1, PC2) | 1 | 0.0003255 | 0.0003255 | 6.805133 | 0.0103648 |
| PQ(PC1, PC2) | 2 | 0.0004438 | 0.0002219 | 4.638899 | 0.0116552 |
| Residuals | 109 | 0.0052135 | 0.0000478 | NA | NA |
| Lack of fit | 109 | 0.0052135 | 0.0000478 | NaN | NaN |
| Pure error | 0 | 0.0000000 | NaN | NA | NA |
Check model residuals for trends (no trends observed)
plot(predict(pwpc.rsm2),resid(pwpc.rsm2),xlab="Predicted",ylab = "Residuals")
Models fitting Qt as response, Sex, AR and WL as predictors. We started fitting model as second order
qtaw.rsm<-rsm(Qt~Sex+SO(sWL,sAR),data=qt)
kables(list(kable("**Coefficients**", col.names=NULL), kable(summary(qtaw.rsm)$coefficients),kable("**ANOVA**",col.names=NULL), kable(summary(qtaw.rsm)$lof)), caption = "**Table S6. Coefficients and analysis of variance of response surface model with Qt as response and Sex, AR, and WL as predictors**")
| Coefficients |
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | 4.3143781 | 0.1640823 | 26.2939892 | 0.0000000 |
| SexM | -0.0137608 | 0.1795265 | -0.0766504 | 0.9390421 |
| sWL | 0.0741225 | 0.1009652 | 0.7341391 | 0.4644403 |
| sAR | 0.2089513 | 0.0866157 | 2.4123937 | 0.0175175 |
| sWL:sAR | -0.0785660 | 0.0965165 | -0.8140157 | 0.4174107 |
| sWL^2 | 0.0634960 | 0.0822901 | 0.7716117 | 0.4420140 |
| sAR^2 | 0.0796838 | 0.0672747 | 1.1844546 | 0.2388095 |
| ANOVA |
| Df | Sum Sq | Mean Sq | F value | Pr(>F) | |
|---|---|---|---|---|---|
| Sex | 1 | 0.2232533 | 0.2232533 | 0.3084403 | 0.5797769 |
| FO(sWL, sAR) | 2 | 7.1417316 | 3.5708658 | 4.9334062 | 0.0088908 |
| TWI(sWL, sAR) | 1 | 0.0061370 | 0.0061370 | 0.0084787 | 0.9268036 |
| PQ(sWL, sAR) | 2 | 1.2993613 | 0.6496806 | 0.8975802 | 0.4105453 |
| Residuals | 109 | 78.8956666 | 0.7238135 | NA | NA |
| Lack of fit | 109 | 78.8956666 | 0.7238135 | NaN | NaN |
| Pure error | 0 | 0.0000000 | NaN | NA | NA |
Model summary coefficients and the analysis of variance do not support sex or a quadratic component, so first order (linear) model is retained
qtaw.rsm2<-rsm(Qt~FO(sWL,sAR),data=qt)
kables(list(kable("**Coefficients**", col.names=NULL), kable(summary(qtaw.rsm2)$coefficients),kable("**ANOVA**",col.names=NULL), kable(summary(qtaw.rsm2)$lof)), caption = "**Table S7. Coefficients and analysis of variance of response surface model with Qt as response, AR and WL as predictors**")
| Coefficients |
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | 4.4212469 | 0.0782646 | 56.490998 | 0.0000000 |
| sWL | 0.1036763 | 0.0843771 | 1.228726 | 0.2217273 |
| sAR | 0.1945450 | 0.0843771 | 2.305661 | 0.0229542 |
| ANOVA |
| Df | Sum Sq | Mean Sq | F value | Pr(>F) | |
|---|---|---|---|---|---|
| FO(sWL, sAR) | 2 | 7.275038 | 3.6375191 | 5.119367 | 0.0074424 |
| Residuals | 113 | 80.291111 | 0.7105408 | NA | NA |
| Lack of fit | 113 | 80.291111 | 0.7105408 | NaN | NaN |
| Pure error | 0 | 0.000000 | NaN | NA | NA |
Checking residuals (no trends observed)
plot(predict(qtaw.rsm2),resid(qtaw.rsm2),xlab = "Predicted", ylab = "Residuals")
Fitting Qt as response, PC scores as predictors. First, fitting model as second order response:
qtpc.rsm<-rsm(Qt~Sex+SO(PC1,PC2,PC3),data=qt)
kables(list(kable("**Coefficients**", col.names=NULL), kable(summary(qtpc.rsm)$coefficients),kable("**ANOVA**",col.names=NULL), kable(summary(qtpc.rsm)$lof)), caption = "**Table S8. Coefficients and analysis of variance of response surface model with Qt as response and Sex and PC scores as predictors**")
| Coefficients |
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | 4.4491746 | 0.1523645 | 29.2008639 | 0.0000000 |
| SexM | 0.1713583 | 0.1585949 | 1.0804779 | 0.2824049 |
| PC1 | 0.0424398 | 0.0780893 | 0.5434777 | 0.5879530 |
| PC2 | 0.2914635 | 0.0827659 | 3.5215398 | 0.0006363 |
| PC3 | -0.0376005 | 0.0801107 | -0.4693564 | 0.6397881 |
| PC1:PC2 | -0.1040224 | 0.0823013 | -1.2639228 | 0.2090565 |
| PC1:PC3 | 0.0393790 | 0.0806052 | 0.4885416 | 0.6261850 |
| PC2:PC3 | -0.1372087 | 0.0830749 | -1.6516262 | 0.1015985 |
| PC1^2 | -0.0676508 | 0.0642771 | -1.0524868 | 0.2949924 |
| PC2^2 | 0.0068314 | 0.0540978 | 0.1262793 | 0.8997523 |
| PC3^2 | -0.0522853 | 0.0603947 | -0.8657258 | 0.3886143 |
| ANOVA |
| Df | Sum Sq | Mean Sq | F value | Pr(>F) | |
|---|---|---|---|---|---|
| Sex | 1 | 0.2232533 | 0.2232533 | 0.3383216 | 0.5620463 |
| FO(PC1, PC2, PC3) | 3 | 11.7852514 | 3.9284171 | 5.9531865 | 0.0008659 |
| TWI(PC1, PC2, PC3) | 3 | 5.0839760 | 1.6946587 | 2.5681130 | 0.0583382 |
| PQ(PC1, PC2, PC3) | 3 | 1.1857680 | 0.3952560 | 0.5989773 | 0.6170768 |
| Residuals | 105 | 69.2879010 | 0.6598848 | NA | NA |
| Lack of fit | 105 | 69.2879010 | 0.6598848 | NaN | NaN |
| Pure error | 0 | 0.0000000 | NaN | NA | NA |
Model summary coefficients and the analysis of variance do not support a quadratic component, so first order model is retained. Sex and PC3 did not contribute to surface (coefficients not statistically significant), so they were excluded from the model.
qtpc.rsm2<-rsm(Qt~FO(PC1,PC2),data=qt)
kables(list(kable("**Coefficients**", col.names=NULL), kable(summary(qtpc.rsm2)$coefficients),kable("**ANOVA**",col.names=NULL), kable(summary(qtpc.rsm2)$lof)), caption = "**Table S9. Coefficients and analysis of variance of response surface model with Qt as response and PC scores as predictors**")
| Coefficients |
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | 4.4212469 | 0.0768040 | 57.5652889 | 0.0000000 |
| PC1 | 0.0697330 | 0.0771372 | 0.9040119 | 0.3679123 |
| PC2 | 0.2901974 | 0.0771372 | 3.7620919 | 0.0002688 |
| ANOVA |
| Df | Sum Sq | Mean Sq | F value | Pr(>F) | |
|---|---|---|---|---|---|
| FO(PC1, PC2) | 2 | 10.24388 | 5.1219409 | 7.485286 | 0.0008855 |
| Residuals | 113 | 77.32227 | 0.6842679 | NA | NA |
| Lack of fit | 113 | 77.32227 | 0.6842679 | NaN | NaN |
| Pure error | 0 | 0.00000 | NaN | NA | NA |
Checking residuals (no trends observed)
plot(predict(qtpc.rsm2),resid(qtpc.rsm2),xlab = "Predicted", ylab = "Residuals")
Generate new variables to predict surface
#Create new dataset based on min max AR and WL to predict rsm. Expanded grid with 50 points
newAW<-expand.grid(sAR=seq(-2.30,2.57,length.out = 50),sWL=seq(-1.79,2.54,length.out = 50))
#Calculate predictions
newAW$Pmin<-predict(pwaw.rsm2,newAW)
#Create new numeric vector to plot sex as different shapes
Sexpch2<-c(1,2)[as.numeric(qt$Sex)]
#Create new dataset based on min max PC scores to predict rsm. Expanded grid with 50 points
newPC<-expand.grid(PC1=seq(-2.47,2.30,length.out = 50),PC2=seq(-2.50,2.80,length.out = 50))
#Calculate predictions for males
newPCM<-newPC
newPCM$Sex<-rep("M",2500)
newPCM$Pmin<-predict(pwpc.rsm2,newPCM)
#Calculate predictions for females
newPCF<-newPC
newPCF$Sex<-rep("F",2500)
newPCF$Pmin<-predict(pwpc.rsm2,newPCF)
#Calculate average prediction
newPC$Pmin<-round((newPCF$Pmin+newPCM$Pmin)/2,digits=5)
#Calculate predictions for Qt models
newAW$Qt<-predict(qtaw.rsm2,newAW)
newPC$Qt<-predict(qtpc.rsm2,newPC)
Generate contour plot for surface. Minimum power required to fly is the response, aspect ratio and wing loading are predictors
ggplot(newAW, aes(sWL,sAR, z = Pmin))+
labs(y="Standardized Aspect Ratio", x="Standardized Wing Loading")+
coord_cartesian(xlim=c(-1.64,2.39), ylim=c(-2.13,2.40))+
geom_raster(aes(fill = Pmin))+
geom_contour(colour = "black")+
geom_text_contour(aes(z = Pmin), nudge_x = 0,nudge_y = 0, colour="black",size=6,breaks=seq(0.05,0.1,by=0.01))+
scale_fill_gradientn(colours=c("red","yellow"))+
geom_point(data=qt,size=4,shape=Sexpch2,mapping=aes(x=sWL,y=sAR))+
theme(legend.position = "none",text = element_text(size=rel(4.5)),panel.border=element_rect(linetype="solid",fill=NA))
Generate contour plot for surface. Minimum power required to fly is the response, PC scores are predictors
ggplot(newPC, aes(PC1,PC2, z = Pmin))+
labs(y="Standardized PC2", x="Standardized PC1")+
coord_cartesian(xlim=c(-2.295,2.13), ylim=c(-2.32,2.62))+
geom_raster(aes(fill = Pmin))+
geom_contour(colour = "black")+
geom_text_contour(aes(z = Pmin), nudge_x = 0,nudge_y = 0, colour="black",size=6,breaks=seq(0.058,0.072,by=0.002))+
scale_fill_gradientn(colours=c("red","yellow"))+
geom_point(data=qt,size=4,shape=Sexpch2,mapping=aes(x=PC1,y=PC2))+
theme(legend.position = "none",text = element_text(size=rel(4.5)),panel.border=element_rect(linetype="solid",fill=NA))
Generate contour plot for surface. Heat loss (Qt) is the response, aspect ratio and wing loading are predictors
ggplot(newAW, aes(sWL,sAR, z = Qt))+
labs(y="Standardized Aspect Ratio", x="Standardized Wing Loading")+
coord_cartesian(xlim=c(-1.64,2.39), ylim=c(-2.13,2.40))+
geom_raster(aes(fill = Qt))+
geom_contour(colour = "black")+
geom_text_contour(aes(z = Qt), nudge_x = 0,nudge_y = 0, colour="black",size=6)+
scale_fill_gradientn(colours=c("red","yellow"))+
geom_point(data=qt,size=4,shape=Sexpch2,mapping=aes(x=sWL,y=sAR))+
theme(legend.position = "none",text = element_text(size=rel(4.5)),panel.border=element_rect(linetype="solid",fill=NA))
Generate contour plot for surface. Heat loss (Qt) is the response, PC scores are predictors
ggplot(newPC, aes(PC1,PC2, z = Qt))+
labs(y="Standardized PC2", x="Standardized PC1")+
coord_cartesian(xlim=c(-2.29,2.13), ylim=c(-2.32,2.63))+
geom_raster(aes(fill = Qt))+
geom_contour(colour = "black")+
geom_text_contour(aes(z = Qt), nudge_x = 0, nudge_y = 0, colour="black",size=6)+
scale_fill_gradientn(colours=c("red","yellow"))+
geom_point(data=qt,size=4,shape=Sexpch2,mapping=aes(x=PC1,y=PC2))+
theme(legend.position = "none",text = element_text(size=rel(4.5)),panel.border=element_rect(linetype="solid",fill=NA))