### R code and analysis for female dominance replication study ###

## last updated 26-09-2021

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

# load required packages

library(pacman)
pacman::p_load(car, dplyr, glmmTMB, DHARMa, effects, ggplot2, rptR, tidyr, 
               reshape2, ggpubr, patchwork)

# load dataset

dom_data <- dominance_data

# check all is ok
str(dom_data)

## Data exploration

# 1. mean body sizes

# mean and SD for female body size
dom_data %>%
  group_by(Dominance_rank) %>%
  summarise(mean_size = mean(Female_size), size_sd = sd(Female_size)) 

# mean and SD for male body size
dom_data %>%
  group_by(Dominance_rank) %>%
  summarise(mean_size = mean(Male_size), size_sd = sd(Male_size))

# 2. paired t-test to compare body sizes between dominant and subordinate female groups

diff <- t.test(Female_size ~ Dominance_rank, data = dom_data, paired = TRUE)
diff # female sizes not significantly different p=0.255

# difference between males and females

  # since no diff in size between female pairs, subset data to just have dominant females
sizes <- dom_data %>%
        filter(Dominance_rank == "dominant")

fitstudent <- t.test(x = sizes$Female_size, 
                     y = sizes$Male_size, var.equal = FALSE, paired = TRUE)

fitstudent

# mean diff of 10.21 mm between males and females

# 3. centre female body size to the mean for further analysis

STFemale <- scale(dom_data$Female_size, center = TRUE)

# check distribution
hist(STFemale)

# same for male size
STMale <- scale(dom_data$Male_size, center = TRUE)

# check distribution
hist(STMale)

# 4. set "subordinate" as our base level for the model
# (since our hypotheses specifically look for an effect of dominance)

Rank <- factor(dom_data$Dominance_rank, levels = c("subordinate", "dominant"))

## Data analysis
## Trial 1 - Paired Mating Trials

# 1. no. mating attempts 
# Here, we are testing the hypothesis that dominant females will attract more mating attempts than subordinates.
# No. mating attempts will be the outcome variable, with dominance rank (dom vs sub) and female size as our predictors, and Trial number as a random effect.

# we can use the glmmTMB package to build and test different linear models with different model distributions

# gaussian distribution
fit_attempts <- glmmTMB(Nb_attempts ~ Rank + STFemale + (1 | Trial_number), data = dom_data, ziformula=~0, family=gaussian(link="identity"))
summary(fit_attempts)

# poisson distribution
fit_attempts2 <- glmmTMB(Nb_attempts ~ Rank + STFemale + (1 | Trial_number), data = dom_data, ziformula=~0, family=poisson(link="log"))
summary(fit_attempts2)

# poisson distribution with zero-inflation
fit_attempts3 <- glmmTMB(Nb_attempts ~ Rank + STFemale + (1 | Trial_number), data = dom_data, ziformula=~1, family=poisson(link="log"))
summary(fit_attempts3)

# negative binomial distribution
fit_attempts4 <- update(fit_attempts, family=nbinom2(link="log")) 
summary(fit_attempts4) # model with the best fit

# hurdle model - treats zero-count and non-zero outcomes as 2 separate categories
fit_attempts5 <- update(fit_attempts, family=list(family="truncated_nbinom1", link="log"))
summary(fit_attempts5)

# let's compare the three models in an AIC table
bbmle::AICctab(fit_attempts, fit_attempts2, fit_attempts3, fit_attempts4) # model 4 gives a much better fit than the others

# use the DHARMa package to run diagnostics on model fit for model 4
# tutorial here: https://aosmith.rbind.io/2017/12/21/using-dharma-for-residual-checks-of-unsupported-models/#:~:text=be%20comparatively%20straightforward.-,Example%20using%20glmmTMB(),glmmTMB%20objects%20for%20glmmTMB%200.2.
# simulate data
sim_fit_attempts4 = simulate(fit_attempts4, nsim=100)
str(sim_fit_attempts4)

# make a matrix of the simulated dataset
sim_fit_attempts4 = do.call(cbind, sim_fit_attempts4)
head(sim_fit_attempts4) # all good

# pass these simulated datapoints to createDHARMa() along with observed values and model predictions. 
# Set integer response to TRUE as we are working with count data
sim_res_fit_attempts4 = createDHARMa(simulatedResponse = sim_fit_attempts4,
                                     observedResponse = dom_data$Nb_attempts,
                                     fittedPredictedResponse = predict(fit_attempts4), 
                                     integerResponse = TRUE)

# plot the simulated residuals
plot(simulateResiduals(fit_attempts4)) # no problems here

# run an ANOVA to get Wald Chi square (Type 2)
glmmTMB:::Anova.glmmTMB(fit_attempts4) # dominance rank is marginally significant

## FEMALE SIZE INTERACTION EXPLORATION ## 

# negative binomial poisson
size_attempts <- glmmTMB(Nb_attempts ~ Rank + STFemale + Rank*STFemale + (1 | Trial_number), data = dom_data, family=nbinom2(link="log"))
summary(size_attempts) # best model with interaction

# gaussian
size_attempts2 <- glmmTMB(Nb_attempts ~ Rank + STFemale + Rank*STFemale + (1 | Trial_number), data = dom_data, ziformula=~0, family=gaussian(link="identity"))
summary(size_attempts2)

# poisson
size_attempts3 <- glmmTMB(Nb_attempts ~ Rank + STFemale + Rank*STFemale + (1 | Trial_number), data = dom_data, ziformula=~0, family=poisson(link="log"))
summary(size_attempts3)

bbmle::AICctab(size_attempts, size_attempts2, size_attempts3) # without female size gives a marginally better fit

plot(simulateResiduals(size_attempts)) # no problems here

glmmTMB:::Anova.glmmTMB(size_attempts, type = "III") # rank and its interaction are significant

anova(fit_attempts4, size_attempts) #interaction model has a slightly better fit, also significantly different

# Trial 2 - Male Mate Choice

# 2. time spent with females

# Here, we are testing the hypothesis that males will prefer to spen more time with dominant than subordinate females.
# Time with female (absolute) will be the outcome variable, with dominance rank (dom vs sub) and female size as our predictors, and Trial number as a random effect.

hist(dom_data$Absolute_Time_with_female)

# gaussian
fit_time1 <- glmmTMB(Absolute_Time_with_female ~ Rank + STFemale + (1 | Trial_number), data = dom_data, family=gaussian(link="log"))
summary(fit_time1) # fits a gaussian distribution best

plot(simulateResiduals(fit_time1))

# gaussian is the way to go
# males spend more time with larger females

glmmTMB:::Anova.glmmTMB(fit_time1) # summary stats

## FEMALE SIZE INTERACTION EXPLORATION ##

# gaussian
size_time <- glmmTMB(Absolute_Time_with_female ~ Rank + STFemale + Rank*STFemale + (1 | Trial_number), data = dom_data, family=gaussian(link="log"))
summary(size_time)

# ANOVA of model to get significance of fixed effects
glmmTMB:::Anova.glmmTMB(size_time, type = "III")

# compare interaction model with fixed effect model
anova(fit_time1, size_time) # interaction model is not better

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

## testing additional (ad hoc) questions ##

# 1. repeatability of female dominance rank within and across days

# need to restructure our dataset so that our measures of individual rank are in a single column but multiple rows
dom_rep <- data.frame(melt(dom_data, id.vars = c("Female_ID", "Group_number"), 
                           measure.vars = c("Dominance_rank", "Dominance_rank_D2"), 
                           variable.name = "Test Day", value.name = "Rank"))

str(dom_rep)

# convert dominance to 1 and subordinates to 0 to make it binary

dom_rep$Rank_binary <- ifelse(dom_rep$Rank == "dominant", 1, 0)


rep1 <- rpt(Rank_binary ~ 1 + (1| Female_ID) + (1| Group_number), 
            grname = c("Female_ID", "Group_number"), data = dom_rep, datatype = "Binary", nboot = 1000, npermut = 0)

summary(rep1) # repeatable within groups

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

## Making plots

## making raincloud plots 
library(devtools)
devtools::install_github("jorvlan/raincloudplots") # raincloud plots

if (!require(remotes)) {
  install.packages("remotes")
}
remotes::install_github('jorvlan/raincloudplots')
library(raincloudplots)

# load dataset that is in the correct format (each trial its own row rather than each female)
data <- paired_mating_trials 

### Number mating attempts ###

# create an array with data
df_array1 <- data_1x1(
  array_1 = data$Nb_attempts_dom[1:30],
  array_2 = data$Nb_attempts_sub[1:30], 
  jit_distance = .09, 
  jit_seed = 321)

# make the plot
raincloud1 <- raincloud_1x1_repmes(
  data = df_array1,
  colors = (c('orangered3', 'royalblue3')),
  fills = (c('orangered3', 'royalblue3')),
  line_color = 'gray',
  line_alpha = .3,
  size = 1,
  alpha = .6,
  align_clouds = FALSE) +
  scale_x_continuous(breaks=c(1,2), labels=c("Dominant", "Subordinate"), limits=c(0, 3)) +
  xlab("Female Dominance Rank") +
  ylab("Number mating attempts") +
  theme_classic()

ggsave("number_attempts.tiff", plot = last_plot(), dpi = 300)
raincloud1

### time with females ###

# create an array with data
df_array2 <- data_1x1(
  array_1 = data$Time_with_Dom[1:30],
  array_2 = data$Time_with_Sub[1:30], 
  jit_distance = .09, 
  jit_seed = 321)

# make the plot
raincloud2 <- raincloud_1x1_repmes(
  data = df_array2,
  colors = (c('orangered3', 'royalblue3')),
  fills = (c('orangered3', 'royalblue3')),
  line_color = 'gray',
  line_alpha = .3,
  size = 1,
  alpha = .6,
  align_clouds = FALSE) +
  scale_x_continuous(breaks=c(1,2), labels=c("Dominant", "Subordinate"), limits=c(0, 3)) +
  xlab("Female Dominance Rank") +
  ylab("Absolute time spent with female (sec)") +
  theme_classic()

raincloud2

# Figure 1 - combining the two plots

ggarrange(raincloud1, raincloud2, labels="auto", hjust = -6.5, ncol = 2, 
          nrow = 2, widths = c(2, 2), heights = c(3, 1), legend = "none", 
          font.label = list(size = 12), align = "hv")

ggsave("fig1.tiff", plot = last_plot(), dpi = 300)

##scatterplots of female size and male mating behaviours in trials 1 and 2

## number mating attempts

p2 <- ggplot(dom_data, aes(x=Female_size, y=Nb_attempts, color=Dominance_rank)) +
  geom_point() + 
  scale_color_manual(values = c('orangered3', 'royalblue3')) +
  geom_smooth(method= 'glm', aes(fill= Dominance_rank), show.legend = FALSE, se = FALSE) + 
  xlab("Female size (mm)") +
  ylab("Number mating attempts") +
  theme_classic()

p2

## time with female

p <- ggplot(dom_data, aes(x=Female_size, y=Absolute_Time_with_female, color=Dominance_rank)) +
  geom_point() + 
  scale_color_manual(values = c('orangered3', 'royalblue3')) +
  geom_smooth(method= 'glm', aes(fill= Dominance_rank), show.legend = FALSE, se = FALSE) + 
  xlab("Female size (mm)") +
  ylab("Absolute time spent with female (sec)") +
  theme_classic()

p

## Figure 2 - combine the two plots together

# set a new window size to fit all 3 of these scatterplots together

dev.new(width = 8, height = 4, unit = "in", noRStudioGD = TRUE)

# arrange the plots  
ggarrange(p2, p, labels="auto", hjust = -6.5, ncol = 2, nrow = 2, 
          widths = c(2, 2), heights = c(2, 1), legend = "none", 
          font.label = list(size = 12), align = "hv")

ggsave("fig2.tiff", plot = last_plot(), dpi = 300)

# plotting mean aggression for each of the five females

# load dataset
aggression <- aggression

# restructure dataset so each observation is its own row
aggression_new <- data.frame(melt(aggression, id.vars = c("Female_ID", "Group_Number", "Dominance_Rank_D1.1"), 
                           measure.vars = c("Absolute_Aggression_D1.1", "Absolute_Aggression_D1.2"), 
                           variable.name = "Observer", value.name = "Aggression"))

str(aggression_new)

# make a boxplot

boxplot <- ggplot(aggression_new, aes(x=Dominance_Rank_D1.1, y=Aggression, group = Dominance_Rank_D1.1)) +
            geom_boxplot(aes(color = Observer), outlier.shape = NA) +
            scale_color_manual(values = c("dodgerblue4", "orangered3")) +
            geom_jitter(aes(colour = Observer), alpha=0.5) +
            labs(x = "Female Dominance Rank", y= "Absolute rates of aggression") +
            theme_classic(base_size = 12)

boxplot + guides(colour="none")

# save plot
ggsave("aggression.tiff", plot = last_plot(), dpi = 300)
