#==============================================================================================================

Data and code from “Mutual mate guarding and limited sexual conflict in a sex-role reversed shorebird” Contributor: Johannes Krietsch
📍 This script runs relative to the project’s root directory and describes how I created all figures (stored in ./OUTPUTS/FIGURES) and performed all statistical analysis (summary tables stored in./OUTPUTS/ESM).

#==============================================================================================================

# Packages
sapply( c('data.table', 'magrittr', 'ggplot2', 'viridis', 'auksRuak', 'foreach', 'sf', 'knitr', 
          'stringr', 'ggnewscale', 'doFuture', 'patchwork', 'activity', 'glmmTMB', 'effects', 'broomExtra',
          'flextable', 'officer', 'dplyr', 'performance', 'ggh4x', 'DHARMa'), 
        require, character.only = TRUE)
##  data.table    magrittr     ggplot2     viridis    auksRuak     foreach          sf       knitr     stringr  ggnewscale    doFuture   patchwork    activity     glmmTMB 
##        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE 
##     effects  broomExtra   flextable     officer       dplyr performance       ggh4x      DHARMa 
##        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE        TRUE
# Lines to run to create html output
opts_knit$set(root.dir = rprojroot::find_rstudio_root_file())
# rmarkdown::render('./R/7_figures_and_statistic.R', output_dir = './OUTPUTS/R_COMPILED')

# Data
dID = fread('./DATA/NANO_TAGS_UNIQUE_BY_DAY.txt', sep = '\t', header = TRUE) %>% data.table
dp  = fread('./DATA/PAIR_WISE_INTERACTIONS_BREEDING_PAIRS.txt', sep = '\t', header = TRUE) %>% data.table
dr  = fread('./DATA/PAIR_WISE_INTERACTIONS_BREEDING_PAIRS_RANDOM.txt', sep = '\t', header = TRUE) %>% data.table
dn  = fread('./DATA/NESTS.txt', sep = '\t', header = TRUE, nThread = 20) %>% data.table
st_transform_DT(dn) # change projection
dn[, initiation_y := as.POSIXct(format(initiation, format = '%m-%d %H:%M:%S'), 
                                format = '%m-%d %H:%M:%S', tz = 'UTC')]
dn = dn[year_ > 2017]

# plot settings
margin_ = unit(c(2, 2, 2, 2), 'pt')
margin_top = unit(c(2, 2, 6, 2), 'pt')
sample_size_label = 2.5
egg_laying_color = 'grey85'

male_col = 'steelblue4'
female_col = 'indianred3'# 'firebrick3'
col1 = '#7aa048' # '#7aa048'
col2 = '#E69F00' 

# assign periods
dp[, period := fcase(
  date_rel_pair >= -5 & date_rel_pair <= -1, "[-5,-1]", 
  date_rel_pair >= 0 & date_rel_pair <= 3,   "[0,3]", 
  date_rel_pair >= 4 & date_rel_pair <= 10,  "[4,10]"
)]

# set order
setorder(dp, pairID, nestID, datetime_1)

# subset data 10 days around clutch initiation
dm = dp[date_rel_pair >= -10 & date_rel_pair <= 10]
dmr = dr[date_rel_pair >= -10 & date_rel_pair <= 10]

# sample size
dm[, .N, pairID] |> nrow()
## [1] 64
dm[, .N, nestID] |> nrow()
## [1] 68
# mean for each day
dpmi = dp[interaction == TRUE, .(N_int = .N), by = .(pairID, nestID, date_rel_pair)]
dpm = unique(dp, by = c('pairID', 'nestID', 'date_rel_pair', 'initiation_rel', 'N', 'year_'))
dpm = merge(dpm, dpmi, by = c('pairID', 'nestID', 'date_rel_pair'), all.x = TRUE)
dpm[is.na(N_int), N_int := 0]
dpm[, interaction_per_day := N_int / N]

dpm[, period := fcase(
  date_rel_pair >= -5 & date_rel_pair <= -1, "[-5,-1]", 
  date_rel_pair >= 0 & date_rel_pair <= 3,   "[0,3]", 
  date_rel_pair >= 4 & date_rel_pair <= 10,  "[4,10]"
)]

setorder(dpm, pairID, nestID, date_rel_pair)

# random pairs
dr[, N := .N, by = .(pairID, nestID, date_rel_pair)]
drmi = dr[interaction == TRUE, .(N_int = .N), by = .(pairID, nestID, date_rel_pair)]
drm = unique(dr, by = c('pairID', 'nestID', 'date_rel_pair', 'initiation_rel', 'N', 'year_'))
drm = merge(drm, drmi, by = c('pairID', 'nestID', 'date_rel_pair'), all.x = TRUE)
drm[is.na(N_int), N_int := 0]
drm[, interaction_per_day := N_int / N]

drm[, period := fcase(
  date_rel_pair >= -5 & date_rel_pair <= -1, "[-5,-1]", 
  date_rel_pair >= 0 & date_rel_pair <= 3,   "[0,3]", 
  date_rel_pair >= 4 & date_rel_pair <= 10,  "[4,10]"
)]

setorder(drm, pairID, nestID, date_rel_pair)

# nest method
dmn = unique(dm, by = 'nestID')
xn = dmn$nestID
dns = dn[nestID %in% xn]
dns = dns[, .N, by = initiation_method]
dns[, N_percentage_total := round(N / nrow(dmn) * 100, 0)]

# start word file for ESM
ESM = read_docx()

# parameter names 
pn = fread("parname;                                                          parameter
            (Intercept);                                                      Intercept 
            sin(hh2rad(HH));                                                  Sinus time
            cos(hh2rad(HH));                                                  Cosinus time
            anyEPYTRUE;                                                       EPP (yes)
            sexM;                                                             Sex (male)
            initiation_rel;                                                   Clutch initiation date
            poly(initiation_rel, 2)1;                                         Clutch initiation date (linear)
            poly(initiation_rel, 2)2;                                         Clutch initiation date (quadratic)
            date_rel_pair;                                                    Day relative to clutch initiation 
            poly(datetime_rel_pair, 2)1;                                      Day relative to clutch initiation (linear)
            poly(datetime_rel_pair, 2)2;                                      Day relative to clutch initiation (quadratic)
            poly(date_rel_pair, 2)1;                                          Day relative to clutch initiation (linear)
            poly(date_rel_pair, 2)2;                                          Day relative to clutch initiation (quadratic)
            year_2019;                                                        Year (2019)
            f_polyandrous_firstTRUE;                                          First clutch of polyandrous female (yes)
            typerandomization;                                                Data type (random pairs)
            date_rel_pair:typerandomization;                                  Day relative to clutch initiation:data type (random pairs)
            poly(datetime_rel_pair0, 2)1:typerandomization;                   Day relative to clutch initiation (linear):data type (random pairs)
            poly(datetime_rel_pair0, 2)2:typerandomization;                   Day relative to clutch initiation (quadratic):data type (random pairs)
            typerandomization:initiation_rel;                                 Clutch initiation date:data type (random pairs)
            typerandomization:poly(initiation_rel, 2)1;                       Clutch initiation date (linear):data type (random pairs)
            typerandomization:poly(initiation_rel, 2)2;                       Clutch initiation date (quadratic):data type (random pairs)
            sd__(Intercept);                                                  Random intercept
            r2marg;                                                           R² marginal
            r2cond;                                                           R² conditional
            
", sep = ';')

Data available relative to clutch initiation

dIDs = unique(dID[date_rel_pair >= -10 & date_rel_pair <= 10], 
              by = c('sex', 'nestID', 'date_rel_pair'))
dIDs = dIDs[, .N, by = .(sex, date_rel_pair, both_tagged_overlapping)]
dIDs
##     sex date_rel_pair both_tagged_overlapping  N
##  1:   F           -10                    TRUE  7
##  2:   F            -9                    TRUE 11
##  3:   F            -8                    TRUE 15
##  4:   F            -7                    TRUE 22
##  5:   F            -6                    TRUE 27
##  6:   M           -10                    TRUE  5
##  7:   M            -9                    TRUE  8
##  8:   M            -8                    TRUE 13
##  9:   M            -7                    TRUE 21
## 10:   M            -6                    TRUE 28
## 11:   M            -5                    TRUE 36
## 12:   M            -4                    TRUE 38
## 13:   M            -3                    TRUE 46
## 14:   M            -8                   FALSE 10
## 15:   M            -7                   FALSE 11
## 16:   M            -6                   FALSE 14
## 17:   M            -5                   FALSE 17
## 18:   M            -4                   FALSE 18
## 19:   F            -5                    TRUE 34
## 20:   F            -4                    TRUE 34
## 21:   F            -3                    TRUE 42
## 22:   F            -2                    TRUE 43
## 23:   F            -1                    TRUE 48
## 24:   F             0                    TRUE 52
## 25:   F             1                    TRUE 59
## 26:   F             2                    TRUE 58
## 27:   M            -2                    TRUE 46
## 28:   M            -1                    TRUE 51
## 29:   M             0                    TRUE 55
## 30:   M             1                    TRUE 60
## 31:   M             2                    TRUE 61
## 32:   M             3                    TRUE 59
## 33:   F            -9                   FALSE  1
## 34:   F            -8                   FALSE  1
## 35:   F            -7                   FALSE  1
## 36:   F            -6                   FALSE  2
## 37:   F            -5                   FALSE  3
## 38:   F            -4                   FALSE  4
## 39:   F            -3                   FALSE  5
## 40:   F            -2                   FALSE  5
## 41:   F            -1                   FALSE  6
## 42:   F             0                   FALSE  8
## 43:   F             1                   FALSE 11
## 44:   F             2                   FALSE 11
## 45:   F             3                   FALSE 11
## 46:   F             3                    TRUE 52
## 47:   F             4                    TRUE 48
## 48:   M             4                    TRUE 55
## 49:   M             5                    TRUE 57
## 50:   M             6                    TRUE 55
## 51:   M             7                    TRUE 51
## 52:   M             8                    TRUE 50
## 53:   M             9                    TRUE 47
## 54:   M            10                    TRUE 45
## 55:   F             5                    TRUE 43
## 56:   M            -3                   FALSE 18
## 57:   F             4                   FALSE  9
## 58:   F             5                   FALSE  7
## 59:   F             6                   FALSE  6
## 60:   F             7                   FALSE  5
## 61:   F             8                   FALSE  5
## 62:   F             9                   FALSE  5
## 63:   F            10                   FALSE  5
## 64:   F             6                    TRUE 34
## 65:   F             7                    TRUE 31
## 66:   F             8                    TRUE 30
## 67:   F             9                    TRUE 27
## 68:   F            10                    TRUE 23
## 69:   M            -2                   FALSE 18
## 70:   M            -1                   FALSE 17
## 71:   M             0                   FALSE 19
## 72:   M             1                   FALSE 19
## 73:   M             2                   FALSE 19
## 74:   M             3                   FALSE 19
## 75:   M             4                   FALSE 18
## 76:   M             5                   FALSE 17
## 77:   M             6                   FALSE 17
## 78:   M             7                   FALSE 16
## 79:   M             8                   FALSE 16
## 80:   M             9                   FALSE 15
## 81:   M            10                   FALSE 15
## 82:   M           -10                   FALSE  6
## 83:   M            -9                   FALSE  6
##     sex date_rel_pair both_tagged_overlapping  N
# pairwise sample size
du = unique(dp, by = c('pairID', 'nestID', 'date_rel_pair'))
dss = unique(du[date_rel_pair >= -10 & date_rel_pair <= 10], 
             by = c('nestID', 'date_rel_pair'))
dss = dss[, .N, by = date_rel_pair]
dss
##     date_rel_pair  N
##  1:           -10  3
##  2:            -9  6
##  3:            -8 11
##  4:            -7 17
##  5:            -6 23
##  6:            -5 30
##  7:            -4 33
##  8:            -3 42
##  9:            -2 40
## 10:            -1 44
## 11:             0 48
## 12:             1 53
## 13:             2 52
## 14:             3 45
## 15:             4 36
## 16:             5 36
## 17:             6 27
## 18:             7 23
## 19:             8 22
## 20:             9 19
## 21:            10 17
##     date_rel_pair  N
# samply size pairs and nests
unique(du, by = 'nestID') |> nrow()
## [1] 68
unique(du, by = 'pairID') |> nrow()
## [1] 64
unique(du, by = 'ID1') |> nrow()
## [1] 63
unique(du, by = 'ID2') |> nrow()
## [1] 60
# plot data available
dIDs[, sex := factor(sex, levels = c('F', 'M', 'pair'))]

# plot by nest
dp[, datetime_rel_pair_min := min(datetime_rel_pair), by = nestID]

du = unique(dp, by = c('nestID'))
setorder(du, by = datetime_rel_pair_min)
dp[, nestID := factor(nestID, levels = c(du$nestID))]

# last interaction
dp[interaction == TRUE, max(datetime_rel_pair)]
## [1] 18.25826
ggplot(data = dp) +
  geom_rect(aes(xmin = 0, xmax = 3, ymin = -Inf, ymax = Inf), fill = egg_laying_color) +
  geom_tile(aes(datetime_rel_pair, nestID, fill = interaction), width = 0.5, show.legend = TRUE) +
  scale_fill_manual(values = c('TRUE' = col1, 'FALSE' = col2), name = '', 
                    labels = c('Not together', 'Together'), drop = FALSE) +
  geom_vline(aes(xintercept = 0), color = 'black', size = 0.2) +
  geom_vline(aes(xintercept = 3), color = 'black', size = 0.2) +
  xlab('Day relative to clutch initiation (= 0)') + ylab('Nest') +
  scale_x_continuous(limits = c(-12, 19), breaks = seq(-12, 19, 1), expand = expansion(add = c(0.2, 0.2))) +
  theme_classic(base_size = 10) + 
  theme(legend.position = c(0.07, 0.95), legend.background = element_blank(), plot.margin = margin_, 
        legend.spacing.y = unit(-0.2, "cm"), legend.title = element_blank())
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
## Warning: Removed 2399 rows containing missing values (`geom_tile()`).

# ggsave('./OUTPUTS/FIGURES/MG_over_season_eachID.tiff', plot = last_plot(),  width = 238, height = 177, 
#        units = c('mm'), dpi = 'print')

dp[, nestID := as.character(nestID)]

Mate guarding intensity in relation to daily patterns

# Function to deal with time
dt2hh <- function(x) {
  h <- as.POSIXlt(x)
  h$hour + h$min / 60 + h$sec / 3600
}

hh2rad <- function(x) {
  x * pi / 12
}

dm[, HH := dt2hh(datetime_1)]


### before clutch initiation
dx = dm[period == "[-5,-1]"]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 51
unique(dx$ID1) |> length() # N males
## [1] 49
unique(dx$ID2) |> length() # N females
## [1] 48
dx |> nrow() # N observations
## [1] 18289
# model
m <- glmmTMB(interaction ~ sin(hh2rad(HH)) + cos(hh2rad(HH)) + 
               poly(initiation_rel, 2) + poly(datetime_rel_pair, 2) +
               (datetime_rel_pair | nestID),
  family = binomial(link = "logit"), 
  data = dx,
  control = glmmTMBControl(parallel = 15)
)

plot(allEffects(m))

summary(m)
##  Family: binomial  ( logit )
## Formula:          interaction ~ sin(hh2rad(HH)) + cos(hh2rad(HH)) + poly(initiation_rel,      2) + poly(datetime_rel_pair, 2) + (datetime_rel_pair | nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   8668.3   8746.4  -4324.1   8648.3    18279 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name              Variance Std.Dev. Corr 
##  nestID (Intercept)       18.299   4.278         
##         datetime_rel_pair  2.506   1.583    0.93 
## Number of obs: 18289, groups:  nestID, 51
## 
## Conditional model:
##                               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                    2.82472    0.25516  11.071  < 2e-16 ***
## sin(hh2rad(HH))                0.31843    0.04469   7.126 1.03e-12 ***
## cos(hh2rad(HH))                0.18539    0.04194   4.421 9.84e-06 ***
## poly(initiation_rel, 2)1      55.91407   30.77934   1.817 0.069277 .  
## poly(initiation_rel, 2)2    -100.62627   28.96458  -3.474 0.000513 ***
## poly(datetime_rel_pair, 2)1  130.97631   46.02796   2.846 0.004433 ** 
## poly(datetime_rel_pair, 2)2  -83.67335    5.59856 -14.946  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)
## DHARMa:testOutliers with type = binomial may have inflated Type I error rates for integer-valued distributions. To get a more exact result, it is recommended to re-run testOutliers with type = 'bootstrap'. See ?testOutliers for details

testDispersion(res)

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.65799, p-value < 2.2e-16
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial') 

# check effect of time of the day
e = effect("sin(hh2rad(HH))", m, xlevels = 100) |>
  data.frame() |>
  setDT()


ggplot(e, aes(y = fit, x = HH)) +
  geom_ribbon(aes(ymin = lower, ymax = upper), alpha = 0.5) + 
  geom_line(linewidth = 1) +
  theme_classic(base_size = 10) +
  xlab("Hour") + 
  ylab("Proportion of time together") 

# check effect size and when min and max
e[, min(fit)]
## [1] 0.9751856
e[, max(fit)]
## [1] 0.9879668
(e[, max(fit)] - e[, min(fit)]) * 100 # not biological relevant
## [1] 1.278118
e[fit == min(fit), .(HH)]
##    HH
## 1: 16
e[fit == max(fit), .(HH)]
##      HH
## 1: 3.88
# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 

setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)] 
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S1. GLMM together and time -5 to -1')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')



### during egg-laying
dx = dm[period == "[0,3]"]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 56
unique(dx$ID1) |> length() # N males
## [1] 53
unique(dx$ID2) |> length() # N females
## [1] 50
dx |> nrow() # N observations
## [1] 19311
# model
m <- glmmTMB(interaction ~ sin(hh2rad(HH)) + cos(hh2rad(HH)) + 
               poly(initiation_rel, 2) + poly(datetime_rel_pair, 2) +
               (datetime_rel_pair | nestID),
             family = binomial(link = "logit"), 
             data = dx,
             control = glmmTMBControl(parallel = 15)
)

plot(allEffects(m))

summary(m)
##  Family: binomial  ( logit )
## Formula:          interaction ~ sin(hh2rad(HH)) + cos(hh2rad(HH)) + poly(initiation_rel,      2) + poly(datetime_rel_pair, 2) + (datetime_rel_pair | nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##  19936.2  20014.8  -9958.1  19916.2    19301 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name              Variance Std.Dev. Corr  
##  nestID (Intercept)       1.1178   1.057          
##         datetime_rel_pair 0.5624   0.750    -0.54 
## Number of obs: 19311, groups:  nestID, 56
## 
## Conditional model:
##                               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                    0.27736    0.14572   1.903   0.0570 .  
## sin(hh2rad(HH))               -0.02875    0.02582  -1.114   0.2654    
## cos(hh2rad(HH))               -0.21515    0.02504  -8.591  < 2e-16 ***
## poly(initiation_rel, 2)1      17.23941   18.94586   0.910   0.3629    
## poly(initiation_rel, 2)2     -74.80918   17.16283  -4.359 1.31e-05 ***
## poly(datetime_rel_pair, 2)1 -175.55415   16.44745 -10.674  < 2e-16 ***
## poly(datetime_rel_pair, 2)2   -5.89177    3.04347  -1.936   0.0529 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 1.0444, p-value = 0.248
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial') 

# check effect of time of the day
e = effect("sin(hh2rad(HH))", m, xlevels = 100) |>
  data.frame() |>
  setDT()


ggplot(e, aes(y = fit, x = HH)) +
  geom_ribbon(aes(ymin = lower, ymax = upper), alpha = 0.5) + 
  geom_line(linewidth = 1) +
  theme_classic(base_size = 10) +
  xlab("Hour") + 
  ylab("Proportion of time together") 

# check effect size and when min and max
e[, min(fit)] * 100
## [1] 61.0468
e[, max(fit)] * 100
## [1] 70.7514
(e[, max(fit)] - e[, min(fit)]) * 100 # biological relevant
## [1] 9.7046
e[fit == min(fit), .(HH, se)]
##       HH         se
## 1: 0.486 0.04124426
e[fit == max(fit), .(HH, se)]
##      HH         se
## 1: 12.6 0.03582247
# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 

setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)] 
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S2. GLMM together and time 0 to 3')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')

Mate guarding intensity in relation year

### before clutch initiation
dx = dpm[period == "[-5,-1]"]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 51
unique(dx$ID1) |> length() # N males
## [1] 49
unique(dx$ID2) |> length() # N females
## [1] 48
dx |> nrow() # N observations
## [1] 189
# by year
dxu = unique(dx, by = c('nestID', 'year_')) 
dxu[, .N, by = year_]
##    year_  N
## 1:  2018  7
## 2:  2019 44
dx[, .N, by = year_]
##    year_   N
## 1:  2018  28
## 2:  2019 161
# beta models only accept proportion in the (0,1) interval
dx[interaction_per_day == 1, interaction_per_day := 0.9999]
dx[interaction_per_day == 0, interaction_per_day := 0.0001]

dx[, year_ := as.character(year_)]

# model
m <- glmmTMB(interaction_per_day ~ poly(date_rel_pair, 2) + poly(initiation_rel, 2) + year_ + 
               (date_rel_pair | nestID),
             family =  beta_family(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)


plot(allEffects(m))

summary(m)
##  Family: beta  ( logit )
## Formula:          interaction_per_day ~ poly(date_rel_pair, 2) + poly(initiation_rel,      2) + year_ + (date_rel_pair | nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   -768.2   -735.8    394.1   -788.2      185 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr 
##  nestID (Intercept)   2.8940   1.7012        
##         date_rel_pair 0.3978   0.6307   0.94 
## Number of obs: 189, groups:  nestID, 51
## 
## Dispersion parameter for beta family (): 4.61 
## 
## Conditional model:
##                          Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                2.3902     0.4556   5.247 1.55e-07 ***
## poly(date_rel_pair, 2)1    5.1467     2.5120   2.049   0.0405 *  
## poly(date_rel_pair, 2)2   -4.9467     1.2217  -4.049 5.14e-05 ***
## poly(initiation_rel, 2)1   1.4986     1.5900   0.943   0.3459    
## poly(initiation_rel, 2)2  -6.7147     1.7232  -3.897 9.75e-05 ***
## year_2019                 -0.4179     0.4022  -1.039   0.2988    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.88419, p-value = 0.448
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning: Model's distribution-specific variance is negative. Results are not reliable.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S3. GLMM together and year -5 to -1')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')

# check effect of time of the day
e = effect("year_", m, xlevels = 2) |>
  data.frame() |>
  setDT()


### during egg-laying
dx = dpm[period == "[0,3]"]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 56
unique(dx$ID1) |> length() # N males
## [1] 53
unique(dx$ID2) |> length() # N females
## [1] 50
dx |> nrow() # N observations
## [1] 198
# by year
dxu = unique(dx, by = c('nestID', 'year_')) 
dxu[, .N, by = year_]
##    year_  N
## 1:  2019 51
## 2:  2018  5
dx[, .N, by = year_]
##    year_   N
## 1:  2019 181
## 2:  2018  17
# beta models only accept proportion in the (0,1) interval
dx[interaction_per_day == 1, interaction_per_day := 0.9999]
dx[interaction_per_day == 0, interaction_per_day := 0.0001]

dx[, year_ := as.character(year_)]

# model
m <- glmmTMB(interaction_per_day ~ date_rel_pair + poly(initiation_rel, 2) + year_ + 
               (date_rel_pair | nestID),
             family =  beta_family(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)


plot(allEffects(m))

summary(m)
##  Family: beta  ( logit )
## Formula:          interaction_per_day ~ date_rel_pair + poly(initiation_rel, 2) +      year_ + (date_rel_pair | nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   -185.1   -155.5    101.6   -203.1      194 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr 
##  nestID (Intercept)   0.3000   0.5477        
##         date_rel_pair 0.1192   0.3453   0.69 
## Number of obs: 198, groups:  nestID, 56
## 
## Dispersion parameter for beta family ():  6.2 
## 
## Conditional model:
##                          Estimate Std. Error z value Pr(>|z|)    
## (Intercept)               1.31478    0.43245   3.040 0.002363 ** 
## date_rel_pair            -0.87742    0.07931 -11.063  < 2e-16 ***
## poly(initiation_rel, 2)1  5.37171    1.91786   2.801 0.005096 ** 
## poly(initiation_rel, 2)2 -5.71412    1.65056  -3.462 0.000536 ***
## year_2019                 0.09730    0.44618   0.218 0.827376    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.83629, p-value = 0.12
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning: mu of 2.3 is too close to zero, estimate of random effect variances may be unreliable.

## Warning: Model's distribution-specific variance is negative. Results are not reliable.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S4. GLMM together and year 0 to 3')) |>  body_add_par('') |>
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')


# Plot time together breeding pairs split by year

# pairwise sample size 2018
dus = unique(dp, by = c('pairID', 'nestID', 'date_rel_pair'))
dss_2018 = unique(dus[year_ == 2018 & date_rel_pair >= -10 & date_rel_pair <= 10], 
                  by = c('nestID', 'date_rel_pair'))
dss_2018 = dss_2018[, .N, by = date_rel_pair]

# pairwise sample size 2019
dus = unique(dp, by = c('pairID', 'nestID', 'date_rel_pair'))
dss_2019 = unique(dus[year_ == 2019 & date_rel_pair >= -10 & date_rel_pair <= 10], 
                  by = c('nestID', 'date_rel_pair'))
dss_2019 = dss_2019[, .N, by = date_rel_pair]

du[, year_ := as.character(year_)]


# merge 
dss = merge(dss_2018[, .(N_2018 = N, date_rel_pair)], 
            dss_2019[, .(N_2019 = N, date_rel_pair)], by = 'date_rel_pair', all = TRUE)
dss[is.na(N_2018), N_2018 := 0]
dss[, N_year_label := paste0(N_2018, '/', N_2019)]

dpm[, year_cha := as.character(year_)]


p1 = 
  ggplot() +
  geom_text(data = dss, aes(date_rel_pair, Inf, label = N_year_label), vjust = 1, size = sample_size_label) +
  geom_rect(aes(xmin = -0.5, xmax = 3.5, ymin = -0.01, ymax = 1), fill = egg_laying_color) +
  geom_boxplot(data = dpm, 
               aes(date_rel_pair, interaction_per_day, group = interaction(date_rel_pair, year_cha), 
                   color = year_cha),
               lwd = 0.3, outlier.size = 0.7, outlier.alpha = 0, 
               position = position_dodge2(preserve = "single")) +
  geom_point(data = dpm, 
             aes(date_rel_pair, interaction_per_day, group = interaction(date_rel_pair, year_cha), 
                 color = year_cha), # shape = data_quality
             position=position_jitterdodge(), size = 0.2) +
  scale_color_manual(values = c(col1, col2), name = '', 
                     labels = c('2018', '2019'), drop = FALSE) +
  scale_x_continuous(limits = c(-10.4, 10.4), breaks = seq(-10, 10, 1), 
                     labels = c('-10', '', '-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10'),
                     expand = expansion(add = c(0.2, 0.2))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0.05))) +
  theme_classic(base_size = 10) +
  theme(legend.position = c(0.93, 0.85), legend.background = element_blank(), plot.margin = margin_, 
        legend.spacing.y = unit(-0.2, "cm"), legend.title = element_blank()) +
  ylab('Proportion of time together') +
  xlab('Day relative to clutch initiation (= 0)')

p1
## Warning: Removed 105 rows containing missing values (`stat_boxplot()`).
## Warning: Removed 105 rows containing missing values (`geom_point()`).

# clutch initiation distribution
di = dn[!is.na(year_) & data_type == 'study_site', .(initiation_mean = mean(initiation, na.rm = TRUE)), 
        by = year_]

dn = merge(dn, di, by = 'year_', all.x = TRUE)
dn[, initiation_rel_ := difftime(initiation, initiation_mean, units = 'days') %>% as.numeric %>% round(., 0)]

dns = dn[data_type == 'study_site' & !is.na(initiation_rel_)]
dns[, year_ := as.character(year_)]

# Sample size
dss = dns[, .(median = median(initiation_rel_), q25 = quantile(initiation_rel_, probs = c(0.25)),
              q75 = quantile(initiation_rel_, probs = c(0.75)), .N, max = max(initiation_rel_)), by = year_]
dss[, year_ := as.character(year_)]

# x axis ticks
x = data.table(seq1 = seq(-16, 16, 1))
y = data.table(seq1 = seq(-16, 16, 2), seq2 = as.character(seq(-16, 16, 2)))
xy = merge(x, y, by = 'seq1', all.x = TRUE)
xy[is.na(seq2), seq2 := '']

p2 =
  ggplot(data = dns) +
  geom_violin(aes(initiation_rel_, year_, color = year_, fill = year_), alpha = 0.2, show.legend = FALSE) +
  geom_point(data = dss, aes(median, year_, color = year_), size = 1.5) +
  geom_linerange(data = dss, aes(y = year_, xmin = q75, xmax = q25, color = year_), size = 0.3) +
  
  geom_text(data = dss, aes(Inf, year_, label = N), hjust = 1, size = sample_size_label) +
  scale_color_manual(values = c(col1, col2), name = '', 
                     labels = c('2018', '2019'), drop = FALSE) +
  scale_fill_manual(values = c(col1, col2), name = '', 
                    labels = c('2018', '2019'), drop = FALSE) +
  scale_x_continuous(limits = c(-16, 16), breaks = seq(-16, 16, 1), 
                     labels = xy$seq2,
                     expand = expansion(add = c(0.5, 0.5))) +
  ylab('Year') + xlab('Clutch initiation date (standardized)') +
  theme_classic(base_size = 10) +
  theme(legend.position = "none")
p2

# merge plots
p1 + p2 + 
  plot_layout(nrow = 2, heights = c(3, 1)) +
  plot_annotation(tag_levels = 'a')
## Warning: Removed 105 rows containing missing values (`stat_boxplot()`).
## Removed 105 rows containing missing values (`geom_point()`).

# ggsave('./OUTPUTS/FIGURES/prop_time_together_season_year.tiff', plot = last_plot(),  width = 177, height = 120, 
#        units = c('mm'), dpi = 'print')

Mate guarding intensity in relation to breeding state

# plot time together

# merge data
du = rbindlist(list(dpm[, .(pairID, nestID, year_, date_rel_pair, prop = interaction_per_day, 
                            type = 'm_f_together')],
                    drm[, .(pairID, nestID, year_, date_rel_pair, prop = interaction_per_day, 
                            type = 'm_f_together_randomized')]
))


# pairwise sample size
ds = unique(dpm, by = c('pairID', 'nestID', 'date_rel_pair'))
dss = unique(ds[date_rel_pair >= -10 & date_rel_pair <= 10], 
             by = c('nestID', 'date_rel_pair'))
dss = dss[, .N, by = date_rel_pair]
dss
##     date_rel_pair  N
##  1:           -10  3
##  2:            -9  6
##  3:            -8 11
##  4:            -7 17
##  5:            -6 23
##  6:            -5 30
##  7:            -4 33
##  8:            -3 42
##  9:            -2 40
## 10:            -1 44
## 11:             0 48
## 12:             1 53
## 13:             2 52
## 14:             3 45
## 15:             4 36
## 16:             5 36
## 17:             6 27
## 18:             7 23
## 19:             8 22
## 20:             9 19
## 21:            10 17
##     date_rel_pair  N
# Plot time together breeding pairs vs. randomized pairs
pa = 
  ggplot() +
  geom_text(data = dss, aes(date_rel_pair, Inf, label = N), vjust = 1, size = sample_size_label) +
  geom_rect(aes(xmin = -0.5, xmax = 3.5, ymin = -0.01, ymax = 1), fill = egg_laying_color) +
  geom_boxplot(data = du, 
               aes(date_rel_pair, prop, group = interaction(date_rel_pair, type), color = type),
               lwd = 0.3, outlier.size = 0.7, outlier.alpha = 0) +
  geom_point(data = du, 
             aes(date_rel_pair, prop, group = interaction(date_rel_pair, type), color = type),
             position=position_jitterdodge(), size = 0.2) +
  # scale_shape_manual(values=c(20, 19)) +
  scale_color_manual(values = c(col1, col2), name = '', 
                     labels = c('Breeding pair', 'Random pair'), drop = FALSE) +
  scale_x_continuous(limits = c(-10.4, 10.4), breaks = seq(-10, 10, 1), 
                     labels = c('-10', '', '-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10'),
                     expand = expansion(add = c(0.2, 0.2))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0.05))) +
  theme_classic(base_size = 10) +
  theme(legend.position = c(0.9, 0.85), legend.background = element_blank(), plot.margin = margin_top, 
        legend.spacing.y = unit(-0.2, "cm"), legend.title = element_blank()) +
  ylab('Proportion of time together') +
  xlab('Day relative to clutch initiation (= 0)')

pa
## Warning: Removed 449 rows containing missing values (`stat_boxplot()`).
## Warning: Removed 449 rows containing missing values (`geom_point()`).

### statistic

### before clutch initiation
dx = dpm[period == "[-5,-1]"]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 51
unique(dx$ID1) |> length() # N males
## [1] 49
unique(dx$ID2) |> length() # N females
## [1] 48
dx |> nrow() # N observations
## [1] 189
# beta models only accept proportion in the (0,1) interval
dx[interaction_per_day == 1, interaction_per_day := 0.9999]
dx[interaction_per_day == 0, interaction_per_day := 0.0001]


# model
m <- glmmTMB(interaction_per_day ~ poly(date_rel_pair, 2) + poly(initiation_rel, 2) + 
               (date_rel_pair | nestID),
             family =  beta_family(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)


plot(allEffects(m))

summary(m)
##  Family: beta  ( logit )
## Formula:          interaction_per_day ~ poly(date_rel_pair, 2) + poly(initiation_rel,      2) + (date_rel_pair | nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   -769.2   -740.0    393.6   -787.2      185 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr 
##  nestID (Intercept)   2.5565   1.599         
##         date_rel_pair 0.3625   0.602    0.95 
## Number of obs: 189, groups:  nestID, 51
## 
## Dispersion parameter for beta family (): 4.11 
## 
## Conditional model:
##                          Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                1.9965     0.1637  12.197  < 2e-16 ***
## poly(date_rel_pair, 2)1    4.7641     2.1455   2.221   0.0264 *  
## poly(date_rel_pair, 2)2   -4.9250     1.1172  -4.408 1.04e-05 ***
## poly(initiation_rel, 2)1   1.5356     1.4499   1.059   0.2896    
## poly(initiation_rel, 2)2  -6.9725     1.5702  -4.441 8.97e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.90071, p-value = 0.512
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning: Model's distribution-specific variance is negative. Results are not reliable.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S5. GLMM together -5 to -1')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')


# descriptive part
x = effect("poly(initiation_rel,2)", m, xlevels = 19) |>
  data.frame() |>
  setDT() |> 
  print()
##     initiation_rel       fit         se     lower     upper
##  1:             -6 0.5455966 0.12734293 0.3035408 0.7678628
##  2:             -5 0.6765325 0.08842456 0.4851747 0.8227487
##  3:             -4 0.7733287 0.05536427 0.6465862 0.8641669
##  4:             -3 0.8390069 0.03412081 0.7599632 0.8955975
##  5:             -2 0.8817228 0.02267445 0.8291883 0.9196652
##  6:             -1 0.9089738 0.01721518 0.8688323 0.9377114
##  7:              0 0.9260696 0.01473584 0.8912122 0.9503799
##  8:              1 0.9363634 0.01360764 0.9036332 0.9584877
##  9:              2 0.9418126 0.01318128 0.9096683 0.9629839
## 10:              3 0.9434168 0.01327367 0.9107812 0.9645788
## 11:              4 0.9414636 0.01391899 0.9071637 0.9635993
## 12:              5 0.9356022 0.01533224 0.8978948 0.9600046
## 13:              6 0.9247544 0.01801982 0.8805707 0.9534560
## 14:              7 0.9068497 0.02303440 0.8504044 0.9434143
## 15:              8 0.8783705 0.03233304 0.7989899 0.9291816
## 16:              9 0.8337927 0.04900487 0.7140400 0.9097356
## 17:             10 0.7654406 0.07665636 0.5842835 0.8834077
## 18:             11 0.6653149 0.11618049 0.4152441 0.8476735
## 19:             12 0.5313916 0.15848562 0.2441706 0.7992177
x[fit > 0.90] 
##    initiation_rel       fit         se     lower     upper
## 1:             -1 0.9089738 0.01721518 0.8688323 0.9377114
## 2:              0 0.9260696 0.01473584 0.8912122 0.9503799
## 3:              1 0.9363634 0.01360764 0.9036332 0.9584877
## 4:              2 0.9418126 0.01318128 0.9096683 0.9629839
## 5:              3 0.9434168 0.01327367 0.9107812 0.9645788
## 6:              4 0.9414636 0.01391899 0.9071637 0.9635993
## 7:              5 0.9356022 0.01533224 0.8978948 0.9600046
## 8:              6 0.9247544 0.01801982 0.8805707 0.9534560
## 9:              7 0.9068497 0.02303440 0.8504044 0.9434143
# before and after peak
x[initiation_rel < -1, .(fit = mean(fit), se = mean(se))] * 100
##         fit      se
## 1: 74.32375 6.55854
x[initiation_rel > 7, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 73.48621 8.653208
x = effect("poly(date_rel_pair,2)", m, xlevels = 5) |>
  data.frame() |>
  setDT() |> 
  print()
##    date_rel_pair       fit         se     lower     upper
## 1:            -5 0.7854713 0.05273188 0.6638354 0.8716075
## 2:            -4 0.9020369 0.02040895 0.8537595 0.9355793
## 3:            -3 0.9378609 0.01364559 0.9048460 0.9599282
## 4:            -2 0.9416035 0.01372853 0.9078566 0.9634879
## 5:            -1 0.9182172 0.02282730 0.8604016 0.9533854
x[, .(fit = mean(fit), se = mean(se))] * 100
##        fit       se
## 1: 89.7038 2.466845
# pairs with more than 95% together
x[fit > 0.90] 
##    date_rel_pair       fit         se     lower     upper
## 1:            -4 0.9020369 0.02040895 0.8537595 0.9355793
## 2:            -3 0.9378609 0.01364559 0.9048460 0.9599282
## 3:            -2 0.9416035 0.01372853 0.9078566 0.9634879
## 4:            -1 0.9182172 0.02282730 0.8604016 0.9533854
dpm[date_rel_pair == -2 & interaction_per_day > 0.90] |> nrow()
## [1] 34
dpm[date_rel_pair == -2] |> nrow()
## [1] 40
# extract effect from model for plot
e = effect("poly(initiation_rel,2)", m, xlevels = 100) |>
  data.frame() |>
  setDT()


# data for points 
dms = dm[period == "[-5,-1]"]
dms = dms[, N_ini := .N, by = .(pairID, nestID)]
du = unique(dms, by = c('pairID', 'nestID', 'initiation_rel'))
du = du[!is.na(N_ini)]
du[, .(min(N_ini), max(N_ini))] # check min and max
##    V1  V2
## 1: 27 686
du[, .(min(initiation_rel), max(initiation_rel))] # check min and max
##    V1 V2
## 1: -6 12
dms = dms[interaction == TRUE & period == "[-5,-1]", .(N_int = .N), by = .(pairID, nestID, initiation_rel)]
du = merge(du, dms, by = c('pairID', 'nestID', 'initiation_rel'), all.x = TRUE)
du[is.na(N_int), N_int := 0]
du[, int_prop := N_int / N_ini]
d0 = copy(du)

# point sizes range
du[, .(min(N_ini), max(N_ini))]
##    V1  V2
## 1: 27 686
pb = 
  ggplot() +
  geom_text(aes(-7.8, Inf, label = 'Day -5 to -1'), vjust = 1, hjust = 0, size = 3.3) +
  geom_point(data = du, aes(initiation_rel, int_prop, size = N_ini), shape = 1, color = col1) +
  geom_line(data = e, aes(y = fit, x = initiation_rel), size = 0.8, color = col1) +
  geom_ribbon(data = e, aes(y = fit, x = initiation_rel, ymin = lower, ymax = upper), alpha = 0.2, 
              fill = col1) +
  scale_x_continuous(limits = c(-8, 12), breaks = seq(-8, 12, 1), 
                     labels = c('-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10', '', '12'),
                     expand = expansion(add = c(0.2, 0.2))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0.05, 0.05))) +
  scale_size_area(max_size = 4, breaks=c(100, 300, 500)) +
  theme_classic(base_size = 10) +
  theme(legend.position = "none", legend.background = element_blank(), plot.margin = margin_, 
        legend.spacing.y = unit(-0.2, "cm"), legend.title = element_blank()) +
  ylab('Proportion of time together') +
  xlab('Clutch initiation date (standardized)')

pb

### during egg-laying
dx = dpm[period == "[0,3]"]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 56
unique(dx$ID1) |> length() # N males
## [1] 53
unique(dx$ID2) |> length() # N females
## [1] 50
dx |> nrow() # N observations
## [1] 198
# beta models only accept proportion in the (0,1) interval
dx[interaction_per_day == 1, interaction_per_day := 0.9999]
dx[interaction_per_day == 0, interaction_per_day := 0.0001]

dx[, year_ := as.character(year_)]

# model
m <- glmmTMB(interaction_per_day ~ date_rel_pair + poly(initiation_rel, 2) + 
               (date_rel_pair | nestID),
             family =  beta_family(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)


plot(allEffects(m))

summary(m)
##  Family: beta  ( logit )
## Formula:          interaction_per_day ~ date_rel_pair + poly(initiation_rel, 2) +      (date_rel_pair | nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   -186.9   -160.5    101.4   -202.9      194 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr 
##  nestID (Intercept)   0.2872   0.5359        
##         date_rel_pair 0.1185   0.3442   0.71 
## Number of obs: 198, groups:  nestID, 56
## 
## Dispersion parameter for beta family (): 6.18 
## 
## Conditional model:
##                          Estimate Std. Error z value Pr(>|z|)    
## (Intercept)               1.40471    0.13026  10.784  < 2e-16 ***
## date_rel_pair            -0.87830    0.07912 -11.100  < 2e-16 ***
## poly(initiation_rel, 2)1  5.34767    1.90590   2.806 0.005018 ** 
## poly(initiation_rel, 2)2 -5.63191    1.61186  -3.494 0.000476 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.85907, p-value = 0.208
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning: mu of 2.3 is too close to zero, estimate of random effect variances may be unreliable.
## Warning: Model's distribution-specific variance is negative. Results are not reliable.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S6. GLMM together and year 0 to 3')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')


# descriptive part
effect("date_rel_pair", m, xlevels = 4) |>
  data.frame() |>
  setDT() |> 
  print() * 100
##    date_rel_pair       fit         se     lower     upper
## 1:             0 0.8432725 0.02078156 0.7978097 0.8800499
## 2:             1 0.6909330 0.03293572 0.6225287 0.7518819
## 3:             2 0.4815553 0.04695502 0.3906101 0.5737393
## 4:             3 0.2784609 0.04900092 0.1926146 0.3843540
##    date_rel_pair      fit       se    lower    upper
## 1:             0 84.32725 2.078156 79.78097 88.00499
## 2:           100 69.09330 3.293572 62.25287 75.18819
## 3:           200 48.15553 4.695502 39.06101 57.37393
## 4:           300 27.84609 4.900092 19.26146 38.43540
x = effect("poly(initiation_rel,2)", m, xlevels = 22) |>
  data.frame() |>
  setDT() |> 
  print() 
##     initiation_rel       fit         se      lower     upper
##  1:          -8.00 0.1188473 0.05521910 0.04550561 0.2761908
##  2:          -7.00 0.1710422 0.06114130 0.08100722 0.3256826
##  3:          -6.10 0.2265871 0.06230326 0.12687634 0.3713329
##  4:          -5.10 0.2944725 0.05907007 0.19239586 0.4223819
##  5:          -4.20 0.3572608 0.05351710 0.25981421 0.4681404
##  6:          -3.20 0.4244436 0.04689673 0.33555293 0.5185063
##  7:          -2.30 0.4794718 0.04243316 0.39711938 0.5629552
##  8:          -1.30 0.5322917 0.04001219 0.45322861 0.6097659
##  9:          -0.38 0.5721997 0.03969050 0.49276112 0.6480824
## 10:           0.57 0.6045098 0.04037406 0.52279087 0.6807796
## 11:           1.50 0.6276571 0.04145708 0.54297246 0.7051705
## 12:           2.50 0.6436558 0.04291416 0.55533561 0.7231781
## 13:           3.40 0.6505374 0.04468024 0.55818037 0.7328292
## 14:           4.40 0.6500552 0.04764191 0.55137538 0.7373682
## 15:           5.30 0.6422928 0.05179469 0.53511907 0.7369063
## 16:           6.30 0.6252752 0.05880573 0.50425083 0.7324319
## 17:           7.20 0.6020369 0.06782391 0.46397254 0.7255735
## 18:           8.20 0.5669508 0.08113706 0.40555758 0.7152872
## 19:           9.10 0.5267975 0.09578817 0.34286251 0.7037354
## 20:          10.00 0.4787146 0.11195805 0.27487221 0.6899008
## 21:          11.00 0.4171046 0.12944062 0.20025546 0.6715838
## 22:          12.00 0.3494116 0.14290573 0.13453013 0.6498161
##     initiation_rel       fit         se      lower     upper
# extract effect from model for plot
e = effect("poly(initiation_rel,2)", m, xlevels = 100) |>
  data.frame() |>
  setDT()

# data for points 
dms = dm[period == "[0,3]"]
dms = dms[, N_ini := .N, by = .(pairID, nestID)]
du = unique(dms, by = c('pairID', 'nestID', 'initiation_rel'))
du = du[!is.na(N_ini)]
du[, .(min(N_ini), max(N_ini))] # check min and max
##    V1  V2
## 1: 14 559
du[, .(min(initiation_rel), max(initiation_rel))] # check min and max
##    V1 V2
## 1: -8 12
dms = dms[interaction == TRUE & period == "[0,3]", .(N_int = .N), by = .(pairID, nestID, initiation_rel)]
du = merge(du, dms, by = c('pairID', 'nestID', 'initiation_rel'), all.x = TRUE)
du[is.na(N_int), N_int := 0]
du[, int_prop := N_int / N_ini]
d0 = copy(du)

# point sizes range
du[, .(min(N_ini), max(N_ini))]
##    V1  V2
## 1: 14 559
pc = 
  ggplot() +
  geom_text(aes(-7.8, Inf, label = 'Day 0 to 3'), vjust = 1, hjust = 0, size = 3.3) +
  geom_point(data = du, aes(initiation_rel, int_prop, size = N_ini), shape = 1, color = col1) +
  geom_line(data = e, aes(y = fit, x = initiation_rel), size = 0.8, color = col1) +
  geom_ribbon(data = e, aes(y = fit, x = initiation_rel, ymin = lower, ymax = upper), alpha = 0.2, 
              fill = col1) +
  scale_x_continuous(limits = c(-8, 12), breaks = seq(-8, 12, 1), 
                     labels = c('-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10', '', '12'),
                     expand = expansion(add = c(0.4, 0.4))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0.05, 0.05))) +
  scale_size_area(max_size = 4, breaks=c(100, 300, 500)) +
  theme_classic(base_size = 10) +
  theme(legend.position = "none", legend.background = element_blank(), plot.margin = margin_, 
        legend.spacing.y = unit(-0.2, "cm"), legend.title = element_blank()) +
  ylab('') +
  xlab('Clutch initiation date (standardized)')

pc

# merge plots
pa + pb + pc +
  plot_layout(design = "
  11
  23
") +
  plot_annotation(tag_levels = 'a')
## Warning: Removed 449 rows containing missing values (`stat_boxplot()`).
## Warning: Removed 449 rows containing missing values (`geom_point()`).

# ggsave('./OUTPUTS/FIGURES/male_female_together.tiff', plot = last_plot(),  width = 177, height = 177, 
#        units = c('mm'), dpi = 'print')

Mate guarding intensity in relation to breeding state breeders vs. random pairs

# Statistic together breeding pairs vs. random pairs

# assign random pairs nestID as pairID
dmr[, nestID := pairID]

# merge data
dprm = rbindlist(list(dpm[, .(pairID, nestID, ID1, ID2, year_, date_rel_pair, initiation_rel, interaction_per_day, 
                              period, type = 'breeder')],
                      drm[, .(pairID, nestID, ID1, ID2, year_, date_rel_pair, initiation_rel, interaction_per_day, 
                              period, type = 'randomization')]
))


### before clutch initiation
dx = dprm[period == "[-5,-1]"]

# sample size
unique(dx$pairID) |> length() # N nests
## [1] 228
unique(dx$ID1) |> length() # N males
## [1] 57
unique(dx$ID2) |> length() # N females
## [1] 54
dx |> nrow() # N observations
## [1] 428
# by type
dxu = unique(dx, by = c('nestID', 'type')) 
dxu[, .N, by = type]
##             type  N
## 1:       breeder 51
## 2: randomization 44
dx[, .N, by = type]
##             type   N
## 1:       breeder 189
## 2: randomization 239
dxu = unique(dx, by = c('pairID', 'type')) 
dxu[, .N, by = type]
##             type   N
## 1:       breeder  50
## 2: randomization 178
dx[, .N, by = type]
##             type   N
## 1:       breeder 189
## 2: randomization 239
# beta models only accept proportion in the (0,1) interval
dx[interaction_per_day == 1, interaction_per_day := 0.9999]
dx[interaction_per_day == 0, interaction_per_day := 0.0001]

# model
m <- glmmTMB(interaction_per_day ~ poly(date_rel_pair, 2) * type + poly(initiation_rel, 2) * type + 
               (date_rel_pair | nestID),
             family =  beta_family(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)


plot(allEffects(m))

summary(m)
##  Family: beta  ( logit )
## Formula:          interaction_per_day ~ poly(date_rel_pair, 2) * type + poly(initiation_rel,      2) * type + (date_rel_pair | nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##  -1345.0  -1288.2    686.5  -1373.0      424 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr 
##  nestID (Intercept)   1.0597   1.0294        
##         date_rel_pair 0.2139   0.4624   0.98 
## Number of obs: 428, groups:  nestID, 59
## 
## Dispersion parameter for beta family (): 5.63 
## 
## Conditional model:
##                                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                                  2.0286     0.1148  17.664  < 2e-16 ***
## poly(date_rel_pair, 2)1                      7.6921     2.4854   3.095 0.001969 ** 
## poly(date_rel_pair, 2)2                     -7.8189     1.4913  -5.243 1.58e-07 ***
## typerandomization                           -4.1261     0.1497 -27.570  < 2e-16 ***
## poly(initiation_rel, 2)1                     9.2074     2.1132   4.357 1.32e-05 ***
## poly(initiation_rel, 2)2                   -14.2893     2.0705  -6.901 5.15e-12 ***
## poly(date_rel_pair, 2)1:typerandomization   -4.1259     2.3597  -1.749 0.080376 .  
## poly(date_rel_pair, 2)2:typerandomization    6.8911     2.0248   3.403 0.000666 ***
## typerandomization:poly(initiation_rel, 2)1  -7.9776     2.5538  -3.124 0.001785 ** 
## typerandomization:poly(initiation_rel, 2)2  13.2206     2.4283   5.444 5.20e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.9235, p-value = 0.656
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning in fitTMB(TMBStruc): Model convergence problem; singular convergence (7). See vignette('troubleshooting')
## Warning: mu of 1.1 is too close to zero, estimate of random effect variances may be unreliable.
## Warning: Model's distribution-specific variance is negative. Results are not reliable.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S7. GLMM together vs. randomized -5 to -1')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')

# descriptive part
effect("type", m, xlevels = 2) |>
  data.frame() |>
  setDT() |> 
  print() * 100
## NOTE: type is not a high-order term in the model
##             type       fit          se      lower     upper
## 1:       breeder 0.9499649 0.007163943 0.93385284 0.9623107
## 2: randomization 0.1182364 0.014231329 0.09299892 0.1491961
## Warning in Ops.factor(left, right): '*' ist nicht sinnvoll für Faktoren
##    type      fit        se     lower    upper
## 1:   NA 94.99649 0.7163943 93.385284 96.23107
## 2:   NA 11.82364 1.4231329  9.299892 14.91961
### during egg-laying
dx = dprm[period == "[0,3]"]

# sample size
unique(dx$pairID) |> length() # N nests
## [1] 198
unique(dx$ID1) |> length() # N males
## [1] 58
unique(dx$ID2) |> length() # N females
## [1] 54
dx |> nrow() # N observations
## [1] 384
# by type
dxu = unique(dx, by = c('nestID', 'type')) 
dxu[, .N, by = type]
##             type  N
## 1:       breeder 56
## 2: randomization 45
dx[, .N, by = type]
##             type   N
## 1:       breeder 198
## 2: randomization 186
dxu = unique(dx, by = c('pairID', 'type')) 
dxu[, .N, by = type]
##             type   N
## 1:       breeder  53
## 2: randomization 145
dx[, .N, by = type]
##             type   N
## 1:       breeder 198
## 2: randomization 186
# beta models only accept proportion in the (0,1) interval
dx[interaction_per_day == 1, interaction_per_day := 0.9999]
dx[interaction_per_day == 0, interaction_per_day := 0.0001]

# model
m <- glmmTMB(interaction_per_day ~ date_rel_pair * type + poly(initiation_rel, 2) * type + 
               (date_rel_pair | nestID),
             family =  beta_family(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)
## Warning in fitTMB(TMBStruc): Model convergence problem; singular convergence (7). See vignette('troubleshooting')
plot(allEffects(m))

summary(m)
##  Family: beta  ( logit )
## Formula:          interaction_per_day ~ date_rel_pair * type + poly(initiation_rel,      2) * type + (date_rel_pair | nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   -586.6   -539.2    305.3   -610.6      380 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr 
##  nestID (Intercept)   0.23271  0.4824        
##         date_rel_pair 0.03029  0.1740   1.00 
## Number of obs: 384, groups:  nestID, 61
## 
## Dispersion parameter for beta family (): 5.99 
## 
## Conditional model:
##                                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                                 1.35189    0.12258  11.029  < 2e-16 ***
## date_rel_pair                              -0.85909    0.06176 -13.910  < 2e-16 ***
## typerandomization                          -3.39124    0.17227 -19.686  < 2e-16 ***
## poly(initiation_rel, 2)1                    5.18865    2.11600   2.452 0.014202 *  
## poly(initiation_rel, 2)2                   -7.04362    1.94987  -3.612 0.000303 ***
## date_rel_pair:typerandomization             0.81175    0.08775   9.250  < 2e-16 ***
## typerandomization:poly(initiation_rel, 2)1  0.18971    2.60351   0.073 0.941911    
## typerandomization:poly(initiation_rel, 2)2  6.30402    2.64381   2.384 0.017105 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.9083, p-value = 0.448
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning: mu of 0.5 is too close to zero, estimate of random effect variances may be unreliable.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S8. GLMM together vs. randomized 0 to 3')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')

# descriptive part
effect("type", m, xlevels = 2) |>
  data.frame() |>
  setDT() |> 
  print() * 100
## NOTE: type is not a high-order term in the model
##             type       fit         se      lower     upper
## 1:       breeder 0.5791374 0.03224322 0.51477540 0.6409174
## 2: randomization 0.1106463 0.01525525 0.08401653 0.1443862
## Warning in Ops.factor(left, right): '*' ist nicht sinnvoll für Faktoren
##    type      fit       se     lower    upper
## 1:   NA 57.91374 3.224322 51.477540 64.09174
## 2:   NA 11.06463 1.525525  8.401653 14.43862
### after egg-laying
dx = dprm[period == "[4,10]"]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 49
unique(dx$ID1) |> length() # N males
## [1] 48
unique(dx$ID2) |> length() # N females
## [1] 46
dx |> nrow() # N observations
## [1] 489
# by type
dxu = unique(dx, by = c('nestID', 'type')) 
dxu[, .N, by = type]
##             type  N
## 1:       breeder 38
## 2: randomization 42
dx[, .N, by = type]
##             type   N
## 1:       breeder 180
## 2: randomization 309
dxu = unique(dx, by = c('pairID', 'type')) 
dxu[, .N, by = type]
##             type   N
## 1:       breeder  38
## 2: randomization 174
dx[, .N, by = type]
##             type   N
## 1:       breeder 180
## 2: randomization 309
# beta models only accept proportion in the (0,1) interval
dx[interaction_per_day == 1, interaction_per_day := 0.9999]
dx[interaction_per_day == 0, interaction_per_day := 0.0001]

# model
m <- glmmTMB(interaction_per_day ~ date_rel_pair * type + initiation_rel * type + 
               (date_rel_pair | nestID),
             family =  beta_family(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)


plot(allEffects(m))

summary(m)
##  Family: beta  ( logit )
## Formula:          interaction_per_day ~ date_rel_pair * type + initiation_rel *      type + (date_rel_pair | nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##  -1346.4  -1304.5    683.2  -1366.4      485 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr  
##  nestID (Intercept)   0.553349 0.7439         
##         date_rel_pair 0.005791 0.0761   -0.71 
## Number of obs: 489, groups:  nestID, 49
## 
## Dispersion parameter for beta family (): 4.69 
## 
## Conditional model:
##                                  Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                      -1.29720    0.29399  -4.412 1.02e-05 ***
## date_rel_pair                    -0.14772    0.04431  -3.334 0.000857 ***
## typerandomization                -0.56922    0.37637  -1.512 0.130434    
## initiation_rel                   -0.15517    0.03120  -4.973 6.59e-07 ***
## date_rel_pair:typerandomization   0.12122    0.05494   2.206 0.027365 *  
## typerandomization:initiation_rel  0.15830    0.03040   5.207 1.91e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 1.0094, p-value = 0.952
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning: mu of 0.1 is too close to zero, estimate of random effect variances may be unreliable.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S9. GLMM together vs. randomized 4 to 10')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')

# descriptive part
effect("type", m, xlevels = 2) |>
  data.frame() |>
  setDT() |> 
  print() * 100
## NOTE: type is not a high-order term in the model
##             type       fit         se      lower     upper
## 1:       breeder 0.1031824 0.01109636 0.08332741 0.1271122
## 2: randomization 0.1142535 0.01188839 0.09289099 0.1397718
## Warning in Ops.factor(left, right): '*' ist nicht sinnvoll für Faktoren
##    type      fit       se    lower    upper
## 1:   NA 10.31824 1.109636 8.332741 12.71122
## 2:   NA 11.42535 1.188839 9.289099 13.97718

Female moves away

# Proportion of split events
dms = dm[split == TRUE, .(N_split = .N), by = .(pairID, nestID, date_rel_pair)]
du = unique(dm[split == TRUE], by = c('pairID', 'nestID', 'date_rel_pair'))
du = merge(du, dms, by = c('pairID', 'nestID', 'date_rel_pair'), all.x = TRUE)
du[is.na(N_split), N_split := 0]
du[, split_prop := N_split / N]
d1 = copy(du)

dm = merge(dm, du[, .(pairID, nestID, date_rel_pair, N_split)], by = c('pairID', 'nestID', 'date_rel_pair'),
           all.x = TRUE)

# Times females split
dms = dm[split == TRUE & IDsplitting == 'ID2', .(N_f_split = .N), by = .(pairID, nestID, date_rel_pair)]
du = unique(dm[split == TRUE], by = c('pairID', 'nestID', 'date_rel_pair'))
du = merge(du, dms, by = c('pairID', 'nestID', 'date_rel_pair'), all.x = TRUE)
du[is.na(N_f_split), N_f_split := 0]
du[, f_split_prop := N_f_split /N_split]

# for plot later with EPY
dusm = copy(du)

# pairwise sample size
dus = unique(dp[split == TRUE], by = c('pairID', 'nestID', 'date_rel_pair'))
dss = unique(dus[date_rel_pair >= -10 & date_rel_pair <= 10], 
             by = c('nestID', 'date_rel_pair'))
dss = dss[, .N, by = date_rel_pair]
dss
##     date_rel_pair  N
##  1:           -10  3
##  2:            -7 13
##  3:            -5 23
##  4:            -4 23
##  5:             0 47
##  6:             1 51
##  7:             2 48
##  8:             3 39
##  9:            -3 24
## 10:            -2 23
## 11:            -1 33
## 12:             4 27
## 13:             5 23
## 14:             6 18
## 15:             7 16
## 16:             8 13
## 17:             9 13
## 18:            10 10
## 19:            -8  6
## 20:            -6 20
## 21:            -9  3
##     date_rel_pair  N
# plot splits females 
pa = 
  ggplot() +
  geom_text(data = dss, aes(date_rel_pair, Inf, label = N), vjust = 1, size = sample_size_label) +
  geom_rect(aes(xmin = -0.5, xmax = 3.5, ymin = -0.01, ymax = 1), fill = egg_laying_color) +
  geom_boxplot(data = du, 
               aes(date_rel_pair, f_split_prop, group = interaction(date_rel_pair)), colour = col1,
               lwd = 0.4, outlier.size = 0.7, outlier.alpha = 0) +
  geom_jitter(data = du, aes(date_rel_pair, f_split_prop), colour = col1, size = 0.5) + 
  scale_x_continuous(limits = c(-10.4, 10.4), breaks = seq(-10, 10, 1), 
                     labels = c('-10', '', '-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10'),
                     expand = expansion(add = c(0.2, 0.2))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0.05))) +
  theme_classic(base_size = 11) +
  theme(legend.position = c(0.9, 0.15), legend.background = element_blank(), plot.margin = margin_top) +
  ylab('Proportion female moves away') +
  xlab('Day relative to clutch initiation (= 0)')

pa

### Models 

# Statistic females moving away

### before clutch initiation
dx = dp[split == TRUE & period == "[-5,-1]"]
dx[, IDsplitting := ifelse(IDsplitting == 'ID1', 0, 1)] # males = 0

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 46
unique(dx$ID1) |> length() # N males
## [1] 46
unique(dx$ID2) |> length() # N females
## [1] 44
dx |> nrow() # N observations
## [1] 355
# model
m <- glmmTMB(IDsplitting ~ date_rel_pair + initiation_rel + 
               (date_rel_pair | nestID),
             family =  binomial(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)
## Warning in fitTMB(TMBStruc): Model convergence problem; non-positive-definite Hessian matrix. See vignette('troubleshooting')
## Warning in fitTMB(TMBStruc): Model convergence problem; singular convergence (7). See vignette('troubleshooting')
plot(allEffects(m))

summary(m)
##  Family: binomial  ( logit )
## Formula:          IDsplitting ~ date_rel_pair + initiation_rel + (date_rel_pair |      nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##       NA       NA       NA       NA      352 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr 
##  nestID (Intercept)   0.568258 0.75383       
##         date_rel_pair 0.004046 0.06361  1.00 
## Number of obs: 355, groups:  nestID, 46
## 
## Conditional model:
##                Estimate Std. Error z value Pr(>|z|)   
## (Intercept)    -0.30403    0.28709  -1.059  0.28959   
## date_rel_pair  -0.08690    0.08475  -1.025  0.30518   
## initiation_rel -0.12401    0.04799  -2.584  0.00976 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.97876, p-value = 0.624
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 


setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S10. GLMM female moving away -5 to -1')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')


# descriptive part
x = effect("date_rel_pair", m, xlevels = 4) |>
  data.frame() |>
  setDT() |> 
  print() 
##    date_rel_pair       fit         se     lower     upper
## 1:            -5 0.4979504 0.05819991 0.3859224 0.6101846
## 2:            -4 0.4762425 0.04429049 0.3909982 0.5628939
## 3:            -2 0.4331753 0.04201998 0.3533538 0.5166224
## 4:            -1 0.4119740 0.05401498 0.3115623 0.5202898
x[, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 45.48355 4.963134
x = effect("initiation_rel", m, xlevels = 16) |>
  data.frame() |>
  setDT() |> 
  print() 
##     initiation_rel       fit         se     lower     upper
##  1:             -6 0.6639446 0.08036431 0.4937456 0.8000911
##  2:             -5 0.6357374 0.07348464 0.4837470 0.7647421
##  3:             -4 0.6065656 0.06590450 0.4729339 0.7259494
##  4:             -3 0.5766135 0.05799943 0.4608918 0.6844992
##  5:             -2 0.5460874 0.05032813 0.4469327 0.6417162
##  6:             -1 0.5152109 0.04370025 0.4299492 0.5995964
##  7:              0 0.4842179 0.03917629 0.4083979 0.5607714
##  8:              1 0.4533458 0.03775115 0.3809013 0.5278216
##  9:              2 0.4228283 0.03965974 0.3475814 0.5018352
## 10:              3 0.3928888 0.04412442 0.3105063 0.4818536
## 11:              4 0.3637332 0.04997871 0.2724037 0.4660688
## 12:              5 0.3355454 0.05625287 0.2354623 0.4529649
## 13:              6 0.3084829 0.06229789 0.2010724 0.4415589
## 14:              7 0.2826746 0.06771400 0.1699821 0.4312600
## 15:              8 0.2582191 0.07226966 0.1424915 0.4217138
## 16:              9 0.2351857 0.07584677 0.1186047 0.4127026
# before and after peak
x[initiation_rel <= -1, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 59.06932 6.196354
x[initiation_rel >= 0, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 35.37122 5.450715
# extract effect from model for plot
e = effect("initiation_rel", m, xlevels = 100) |>
  data.frame() |>
  setDT()


# data for points 
dms = dm[split == TRUE & period == "[-5,-1]"]
dms[, N_splits_season := .N, by = .(pairID, nestID, initiation_rel)]
du = unique(dms[!is.na(N_splits_season)], by = c('pairID', 'nestID', 'initiation_rel'))
du[, .(min(N_splits_season), max(N_splits_season))] # check min and max
##    V1 V2
## 1:  1 30
du[, .(min(initiation_rel), max(initiation_rel))] # check min and max
##    V1 V2
## 1: -6  9
# Proportion of split events
dms = dm[split == TRUE & IDsplitting == 'ID2' & period == "[-5,-1]", 
         .(N_split_female = .N), by = .(pairID, nestID, initiation_rel)]
du = merge(du, dms, by = c('pairID', 'nestID', 'initiation_rel'), all.x = TRUE)
du[is.na(N_split_female), N_split_female := 0]
du[, split_prop := N_split_female / N_splits_season]
d1 = copy(du)

# point sizes range
du[, .(min(N_splits_season), max(N_splits_season))]
##    V1 V2
## 1:  1 30
pb = 
  ggplot() +
  geom_text(aes(-7.8, Inf, label = 'Day -5 to -1'), vjust = 1, hjust = 0, size = 3.3) +
  geom_hline(yintercept = 0.5, color = 'black', linetype = 'dashed') +
  geom_point(data = du, aes(initiation_rel, split_prop, size = N_splits_season), shape = 1, 
             color = col1) +
  geom_line(data = e, aes(y = fit, x = initiation_rel), size = 0.8, color = col1) +
  geom_ribbon(data = e, aes(y = fit, x = initiation_rel, ymin = lower, ymax = upper), alpha = 0.2, 
              fill = col1) +
  scale_x_continuous(limits = c(-8, 12), breaks = seq(-8, 12, 1), 
                     labels = c('-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10', '', '12'),
                     expand = expansion(add = c(0.4, 0.4))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0.05, 0.05))) +
  scale_size_area(max_size = 4, breaks=c(10, 20, 30)) +
  theme_classic(base_size = 10) +
  theme(legend.position = 'none', legend.background = element_blank(), plot.margin = margin_, 
        legend.spacing.y = unit(-0.2, "cm"), legend.title = element_blank()) +
  ylab('Proportion female moves away') +
  xlab('Clutch initiation date (standardized)')

pb

### during egg-laying
dx = dp[split == TRUE & period == "[0,3]"]
dx[, IDsplitting := ifelse(IDsplitting == 'ID1', 0, 1)] # males = 0

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 56
unique(dx$ID1) |> length() # N males
## [1] 53
unique(dx$ID2) |> length() # N females
## [1] 50
dx |> nrow() # N observations
## [1] 906
# model
m <- glmmTMB(IDsplitting ~ date_rel_pair + initiation_rel + 
               (date_rel_pair | nestID),
             family =  binomial(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)


plot(allEffects(m))

summary(m)
##  Family: binomial  ( logit )
## Formula:          IDsplitting ~ date_rel_pair + initiation_rel + (date_rel_pair |      nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   1252.7   1281.6   -620.4   1240.7      903 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr  
##  nestID (Intercept)   0.50412  0.7100         
##         date_rel_pair 0.02779  0.1667   -0.94 
## Number of obs: 906, groups:  nestID, 56
## 
## Conditional model:
##                Estimate Std. Error z value Pr(>|z|)
## (Intercept)    -0.05260    0.16403  -0.321    0.748
## date_rel_pair   0.08633    0.07868   1.097    0.273
## initiation_rel  0.04534    0.02759   1.643    0.100
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 1.0018, p-value = 0.856
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 


setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S11. GLMM female moving away 0 to 3')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')


# descriptive part
x = effect("initiation_rel", m, xlevels = 16) |>
  data.frame() |>
  setDT() |> 
  print() 
##     initiation_rel       fit         se     lower     upper
##  1:           -8.0 0.4277411 0.06061992 0.3150828 0.5484266
##  2:           -6.7 0.4422266 0.05311757 0.3420438 0.5473424
##  3:           -5.3 0.4579364 0.04519115 0.3715739 0.5469028
##  4:           -4.0 0.4726000 0.03823406 0.3988252 0.5475911
##  5:           -2.7 0.4873110 0.03208413 0.4249552 0.5500642
##  6:           -1.3 0.5031775 0.02714329 0.4501418 0.5561418
##  7:            0.0 0.5179057 0.02508641 0.4687226 0.5667442
##  8:            1.3 0.5326028 0.02607878 0.4813261 0.5831999
##  9:            2.7 0.5483667 0.03012947 0.4889098 0.6064742
## 10:            4.0 0.5629189 0.03567601 0.4922061 0.6311636
## 11:            5.3 0.5773636 0.04214007 0.4933716 0.6571085
## 12:            6.7 0.5927721 0.04957493 0.4932303 0.6852392
## 13:            8.0 0.6069192 0.05661682 0.4923115 0.7108503
## 14:            9.3 0.6208890 0.06361410 0.4909096 0.7355590
## 15:           11.0 0.6388561 0.07251393 0.4886007 0.7660985
## 16:           12.0 0.6492499 0.07755384 0.4870675 0.7829989
# before and after peak
x[initiation_rel <= -1, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 46.51654 4.273169
x[initiation_rel >= 0, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 58.47844 4.789844
x = effect("date_rel_pair", m, xlevels = 4) |>
  data.frame() |>
  setDT() |> 
  print() 
##    date_rel_pair       fit         se     lower     upper
## 1:             0 0.4890901 0.04086899 0.4099418 0.5687892
## 2:             1 0.5106699 0.02786685 0.4561416 0.5649454
## 3:             2 0.5322100 0.02551729 0.4820410 0.5817361
## 4:             3 0.5536307 0.03577435 0.4829120 0.6222434
x[, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 52.14002 3.250687
# extract effect from model for plot
e = effect("initiation_rel", m, xlevels = 100) |>
  data.frame() |>
  setDT()

# data for points 
dms = dm[split == TRUE & period == "[0,3]"]
dms[, N_splits_season := .N, by = .(pairID, nestID, initiation_rel)]
du = unique(dms[!is.na(N_splits_season)], by = c('pairID', 'nestID', 'initiation_rel'))
du[, .(min(N_splits_season), max(N_splits_season))] # check min and max
##    V1 V2
## 1:  1 37
du[, .(min(initiation_rel), max(initiation_rel))] # check min and max
##    V1 V2
## 1: -8 12
# Proportion of split events
dms = dm[split == TRUE & IDsplitting == 'ID2' & period == "[0,3]", 
         .(N_split_female = .N), by = .(pairID, nestID, initiation_rel)]
du = merge(du, dms, by = c('pairID', 'nestID', 'initiation_rel'), all.x = TRUE)
du[is.na(N_split_female), N_split_female := 0]
du[, split_prop := N_split_female / N_splits_season]
d1 = copy(du)

# point sizes range
du[, .(min(N_splits_season), max(N_splits_season))]
##    V1 V2
## 1:  1 37
pc = 
  ggplot() +
  geom_text(aes(-7.8, Inf, label = 'Day 0 to 3'), vjust = 1, hjust = 0, size = 3.3) +
  geom_hline(yintercept = 0.5, color = 'black', linetype = 'dashed') +
  geom_point(data = du, aes(initiation_rel, split_prop, size = N_splits_season), shape = 1, 
             color = col1) +
  geom_line(data = e, aes(y = fit, x = initiation_rel), size = 0.8, color = col1) +
  geom_ribbon(data = e, aes(y = fit, x = initiation_rel, ymin = lower, ymax = upper), alpha = 0.2, 
              fill = col1) +
  scale_x_continuous(limits = c(-8, 12), breaks = seq(-8, 12, 1), 
                     labels = c('-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10', '', '12'),
                     expand = expansion(add = c(0.4, 0.4))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0.05, 0.05))) +
  scale_size_area(max_size = 4, breaks=c(10, 20, 30)) +
  theme_classic(base_size = 10) +
  theme(legend.position = 'none', legend.background = element_blank(), plot.margin = margin_, 
        legend.spacing.y = unit(-0.2, "cm"), legend.title = element_blank()) +
  ylab('') +
  xlab('Clutch initiation date (standardized)')

pc

# merge plots
pa + pb + pc +
  plot_layout(design = "
  11
  23
") +
  plot_annotation(tag_levels = 'a')

# ggsave('./OUTPUTS/FIGURES/female_moving_away.tiff', plot = last_plot(),  width = 177, height = 177, 
#        units = c('mm'), dpi = 'print')

Number of separating flights

# subset data
dms = unique(dm, by = c('pairID', 'nestID', 'date_rel_pair'))
dms[is.na(N_split),  N_split := 0]

# descriptive statistic 
dms[period == "[-5,-1]", .(mean = mean(N_split), min = min(N_split), max = max(N_split))]
##        mean min max
## 1: 1.878307   0   9
dms[period == "[0,3]", .(mean = mean(N_split), min = min(N_split),max = max(N_split))]
##        mean min max
## 1: 4.575758   0  17
# pairwise sample size
dus = unique(dp, by = c('pairID', 'nestID', 'date_rel_pair'))
dss = unique(dus[date_rel_pair >= -10 & date_rel_pair <= 10], 
             by = c('nestID', 'date_rel_pair'))
dss = dss[, .N, by = date_rel_pair]
dss
##     date_rel_pair  N
##  1:           -10  3
##  2:            -9  6
##  3:            -8 11
##  4:            -7 17
##  5:            -6 23
##  6:            -5 30
##  7:            -4 33
##  8:            -3 42
##  9:            -2 40
## 10:            -1 44
## 11:             0 48
## 12:             1 53
## 13:             2 52
## 14:             3 45
## 15:             4 36
## 16:             5 36
## 17:             6 27
## 18:             7 23
## 19:             8 22
## 20:             9 19
## 21:            10 17
##     date_rel_pair  N
ggplot() +
  geom_rect(aes(xmin = -0.5, xmax = 3.5, ymin = -0.3, ymax = 16.1), fill = egg_laying_color) +
  geom_text(data = dss, aes(date_rel_pair, Inf, label = N), vjust = 1, size = sample_size_label) +
  geom_boxplot(data = dms, 
               aes(date_rel_pair, N_split, group = interaction(date_rel_pair)),
               lwd = 0.4, outlier.size = 0.7, outlier.alpha = 0, color = col1) +
  geom_point(data = dms, 
             aes(date_rel_pair, N_split, group = interaction(date_rel_pair)), color = col1, 
             position=position_jitter(height = 0), size = 0.2) +
  scale_x_continuous(limits = c(-10.4, 10.4), breaks = seq(-10, 10, 1), 
                     labels = c('-10', '', '-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10'),
                     expand = expansion(add = c(0.2, 0.2))) +
  scale_y_continuous(limits = c(-0.3, 16.7), breaks = seq(0, 16, 1),
                     labels = c('0', '', '2', '', '4', '', '6', '', '8', '', '10', '', '12', '', '14', '', '16'),
                     expand = expansion(add = c(0, 0))) +
  theme_classic(base_size = 10) +
  theme(legend.position = c(0.87, 0.94), legend.background = element_blank(), plot.margin = margin_) +
  ylab('Number of separating flights') +
  xlab('Day relative to clutch initiation (= 0)')
## Warning: Removed 1 rows containing non-finite values (`stat_boxplot()`).
## Warning: Removed 1 rows containing missing values (`geom_point()`).

# ggsave('./OUTPUTS/FIGURES/male_female_split_events_number.tiff', plot = last_plot(),  width = 177, height = 89, 
#        units = c('mm'), dpi = 'print')

Distance moved away by sex

# moved away
dms = dm[split == TRUE]

# merge male and female data for plot
dms_m = dms[IDsplitting == 'ID1', .(pairID, nestID, ID1, ID2, date_rel_pair, period, initiation_rel, sex = sex1, 
                                     split_distance = distance1_before, stay_distance = distance2_before)]
dms_f = dms[IDsplitting == 'ID2', .(pairID, nestID, ID1, ID2, date_rel_pair, period, initiation_rel, sex = sex2, 
                                     split_distance = distance2_before, stay_distance = distance1_before)]

dms = rbindlist(list(dms_m, dms_f))

# how often did the other ID stay within 30 m?
ggplot(data = dms) +
  geom_histogram(aes(x = stay_distance)) +
  theme_classic(base_size = 10)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

dms[, median(stay_distance)]
## [1] 14.83902
dms[stay_distance < 30] |> nrow() / nrow(dms) * 100
## [1] 71.94929
# how much was the differences when the other ID moved too?
dms[, delta_split := split_distance - stay_distance]

dms[stay_distance > 30, median(delta_split)]
## [1] 64.09144
dms[stay_distance > 30, min(delta_split)]
## [1] 0.2025201
dms[stay_distance > 30, max(delta_split)]
## [1] 4034.475
ggplot(data = dms[stay_distance > 30]) +
  geom_histogram(aes(x = delta_split)) +
  theme_classic(base_size = 10)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# pairwise sample size
du = unique(dm[split == TRUE], by = c('pairID', 'nestID', 'date_rel_pair'))
dss_m = unique(du[IDsplitting == 'ID1'], by = c('nestID', 'date_rel_pair'))
dss_m = dss_m[, .N, by = date_rel_pair]

# pairwise sample size
dss_f = unique(du[IDsplitting == 'ID2'], by = c('nestID', 'date_rel_pair'))
dss_f = dss_f[, .N, by = date_rel_pair]

# merge 
dss = merge(dss_m[, .(N_m = N, date_rel_pair)], dss_f[, .(N_f = N, date_rel_pair)], by = 'date_rel_pair', 
            all.x = TRUE)
dss[, N_label := paste0(N_f, '/', N_m)]


# adjust distance above 1000 m
dms[, split_distance1000 := split_distance]
dms[split_distance > 1000, split_distance1000 := 1000]

ggplot() +
  geom_rect(aes(xmin = -0.5, xmax = 3.5, ymin = -0.01, ymax = 1005), fill = egg_laying_color) +
  geom_text(data = dss, aes(date_rel_pair, Inf, label = N_label), vjust = 1, size = sample_size_label) +
  geom_boxplot(data = dms, 
               aes(date_rel_pair, split_distance1000, group = interaction(date_rel_pair, sex), 
                   color = sex),
               lwd = 0.4, outlier.size = 0.7, outlier.alpha = 0) +
  geom_point(data = dms, 
             aes(date_rel_pair, split_distance1000, group = interaction(date_rel_pair, sex), 
                 color = sex), position=position_jitterdodge(), size = 0.2) +
  scale_color_manual(values = c(female_col, male_col), name = '',
                     labels = c('Female moves away', 'Male moves away'), drop = FALSE) +
  scale_x_continuous(limits = c(-10.4, 10.4), breaks = seq(-10, 10, 1), 
                     labels = c('-10', '', '-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10'),
                     expand = expansion(add = c(0.2, 0.2))) +
  scale_y_continuous(expand = expansion(add = c(0, 50))) +
  theme_classic(base_size = 10) +
  theme(legend.position = c(0.87, 0.92), legend.background = element_blank(), plot.margin = margin_) +
  ylab('Distance moved when separated (m)') +
  xlab('Day relative to clutch initiation (= 0)')

# ggsave('./OUTPUTS/FIGURES/male_female_split_events_distance_moved.tiff', plot = last_plot(),  width = 177, 
#        height = 89, units = c('mm'), dpi = 'print')




# statistic

### before clutch initiation
dx = dms[period == "[-5,-1]"]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 46
unique(dx$ID1) |> length() # N males
## [1] 46
unique(dx$ID2) |> length() # N females
## [1] 44
dx |> nrow() # N observations
## [1] 355
# by sex
dxu = unique(dx, by = c('nestID', 'sex')) 
dxu[, .N, by = sex]
##    sex  N
## 1:   M 40
## 2:   F 43
dx[, .N, by = sex]
##    sex   N
## 1:   M 196
## 2:   F 159
m <- glmmTMB(split_distance ~ sex + date_rel_pair + initiation_rel + (date_rel_pair | nestID),
               family = gaussian, data = dx, REML = TRUE,
               control = glmmTMBControl(parallel = 15)
)
## Warning in fitTMB(TMBStruc): Model convergence problem; non-positive-definite Hessian matrix. See vignette('troubleshooting')
plot(allEffects(m))

summary(m)
##  Family: gaussian  ( identity )
## Formula:          split_distance ~ sex + date_rel_pair + initiation_rel + (date_rel_pair |      nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##       NA       NA       NA       NA      351 
## 
## Random effects:
## 
## Conditional model:
##  Groups   Name          Variance Std.Dev. Corr  
##  nestID   (Intercept)     201.8   14.20         
##           date_rel_pair   304.9   17.46   -1.00 
##  Residual               20245.5  142.29         
## Number of obs: 355, groups:  nestID, 46
## 
## Dispersion estimate for gaussian family (sigma^2): 2.02e+04 
## 
## Conditional model:
##                Estimate Std. Error z value Pr(>|z|)    
## (Intercept)     176.404     20.272   8.702   <2e-16 ***
## sexM            -29.511     16.525  -1.786   0.0741 .  
## date_rel_pair     4.284      6.687   0.641   0.5218    
## initiation_rel    4.556      3.440   1.325   0.1853    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.9405, p-value = 0.504
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 


setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S12. GLMM split distance -5 to -1')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')

# descriptive part 
x = effect("sex", m, xlevels = 2) |>
  data.frame() |>
  setDT() |> 
  print()
##    sex      fit       se    lower    upper
## 1:   F 169.6253 15.77300 138.6038 200.6468
## 2:   M 140.1139 15.21246 110.1948 170.0329
x = effect("date_rel_pair", m, xlevels = 9) |>
  data.frame() |>
  setDT() |> 
  print()
##    date_rel_pair      fit       se     lower    upper
## 1:          -5.0 143.7870 23.59875  97.37422 190.1997
## 2:          -4.5 145.9288 20.78034 105.05916 186.7984
## 3:          -4.0 148.0706 18.14108 112.39173 183.7495
## 4:          -3.5 150.2124 15.77119 119.19453 181.2304
## 5:          -3.0 152.3543 13.81005 125.19343 179.5151
## 6:          -2.5 154.4961 12.45229 130.00561 178.9866
## 7:          -2.0 156.6379 11.90617 133.22151 180.0543
## 8:          -1.5 158.7798 12.28046 134.62722 182.9323
## 9:          -1.0 160.9216 13.49880 134.37287 187.4703
### during egg-laying
dx = dms[period == "[0,3]"]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 56
unique(dx$ID1) |> length() # N males
## [1] 53
unique(dx$ID2) |> length() # N females
## [1] 50
dx |> nrow() # N observations
## [1] 906
# by sex
dxu = unique(dx, by = c('nestID', 'sex')) 
dxu[, .N, by = sex]
##    sex  N
## 1:   M 55
## 2:   F 52
dx[, .N, by = sex]
##    sex   N
## 1:   M 438
## 2:   F 468
m <- glmmTMB(split_distance ~ sex + date_rel_pair + initiation_rel + (date_rel_pair | nestID),
             family = gaussian, data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)
## Warning in fitTMB(TMBStruc): Model convergence problem; non-positive-definite Hessian matrix. See vignette('troubleshooting')
plot(allEffects(m))
## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced
## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

summary(m)
##  Family: gaussian  ( identity )
## Formula:          split_distance ~ sex + date_rel_pair + initiation_rel + (date_rel_pair |      nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##       NA       NA       NA       NA      902 
## 
## Random effects:
## 
## Conditional model:
##  Groups   Name          Variance  Std.Dev.  Corr 
##  nestID   (Intercept)   2.877e+04 1.696e+02      
##           date_rel_pair 9.320e-07 9.654e-04 0.30 
##  Residual               4.814e+04 2.194e+02      
## Number of obs: 906, groups:  nestID, 56
## 
## Dispersion estimate for gaussian family (sigma^2): 4.81e+04 
## 
## Conditional model:
##                Estimate Std. Error z value Pr(>|z|)    
## (Intercept)     222.160     28.174   7.885 3.13e-15 ***
## sexM            -21.889     15.438  -1.418    0.156    
## date_rel_pair    -4.178      7.743  -0.540    0.590    
## initiation_rel   -2.538      6.249  -0.406    0.685    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.79839, p-value = 0.024
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced
## Warning: Can't compute random effect variances. Some variance components equal zero. Your model may suffer from singularity (see `?lme4::isSingular` and
##   `?performance::check_singularity`).
##   Solution: Respecify random structure! You may also decrease the `tolerance` level to enforce the calculation of random effect variances.
## Random effect variances not available. Returned R2 does not account for random effects.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S13. GLMM split distance 0 to 3')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')

# descriptive part
x = effect("sex", m, xlevels = 2) |>
  data.frame() |>
  setDT() |> 
  print()
## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced
## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced
##    sex      fit       se    lower    upper
## 1:   F 215.6459 25.75691 165.0955 266.1964
## 2:   M 193.7566 25.78813 143.1449 244.3683
x = effect("date_rel_pair", m, xlevels = 9) |>
  data.frame() |>
  setDT() |> 
  print()
## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced

## Warning in sqrt(as.numeric(object$diag.cov.random)): NaNs produced
##    date_rel_pair      fit       se    lower    upper
## 1:          0.00 211.0768 26.87443 158.3331 263.8204
## 2:          0.38 209.4892 25.82757 158.8001 260.1783
## 3:          0.75 207.9434 25.09943 158.6833 257.2035
## 4:          1.10 206.4812 24.69842 158.0081 254.9542
## 5:          1.50 204.8100 24.60034 156.5295 253.0906
## 6:          1.90 203.1389 24.89029 154.2893 251.9885
## 7:          2.20 201.8856 25.35508 152.1237 251.6474
## 8:          2.60 200.2144 26.28317 148.6312 251.7977
## 9:          3.00 198.5433 27.53026 144.5125 252.5741

Nest attendance by sex

# assign parameters
dm[, m_at_nest := at_nest1 == TRUE | at_nest2 == TRUE & interaction == TRUE]
dm[, f_at_nest := at_nest2 == TRUE | at_nest1 == TRUE & interaction == TRUE]
dm[, both_at_nest := at_nest1 == TRUE & interaction == TRUE | at_nest2 == TRUE & interaction == TRUE]
dm[, m_alone_at_nest := at_nest1 == TRUE & interaction == FALSE]
dm[, f_alone_at_nest := at_nest2 == TRUE & interaction == FALSE]

# First nest location visit
ds1 = dm[, .(first_pairwise_location = min(datetime_rel_pair)), by = nestID]
ds2 = dm[m_at_nest == TRUE | f_at_nest == TRUE, .(first_nest_visit = min(datetime_rel_pair)), by = nestID]
ds = merge(ds1, ds2, by = 'nestID')

# how many days with data before?
ds[, days_data_before_nest_visit := first_pairwise_location - first_nest_visit]

# subset pairs with at least one day of data before
dss = ds[days_data_before_nest_visit < -1]

# summary (relative to clutch initiation)
dss |> nrow()
## [1] 28
dss[, .(mean = mean(first_nest_visit),
        min = min(first_nest_visit),
        max = max(first_nest_visit))]
##         mean       min      max
## 1: -2.581659 -6.768299 0.127662
# Male and female together
dms = dm[interaction == TRUE, .(N_int = .N), by = .(pairID, nestID, date_rel_pair)]
du = unique(dm, by = c('pairID', 'nestID', 'date_rel_pair'))
du = merge(du, dms, by = c('pairID', 'nestID', 'date_rel_pair'), all.x = TRUE)
du[is.na(N_int), N_int := 0]
du[, int_prop := N_int / N]
d0 = copy(du)

# Proportion of time males at nest
dms = dm[m_at_nest == TRUE, .(N_m_at_nest = .N), by = .(pairID, nestID, date_rel_pair)]
du = unique(dm, by = c('pairID', 'nestID', 'date_rel_pair'))
du = merge(du, dms, by = c('pairID', 'nestID', 'date_rel_pair'), all.x = TRUE)
du[is.na(N_m_at_nest), N_m_at_nest := 0]
du[, m_at_nest_prop := N_m_at_nest / N]
d1 = copy(du)

# Proportion of time females at nest
dms = dm[f_at_nest == TRUE, .(N_f_at_nest = .N), by = .(pairID, nestID, date_rel_pair)]
du = unique(dm, by = c('pairID', 'nestID', 'date_rel_pair'))
du = merge(du, dms, by = c('pairID', 'nestID', 'date_rel_pair'), all.x = TRUE)
du[is.na(N_f_at_nest), N_f_at_nest := 0]
du[, f_at_nest_prop := N_f_at_nest / N]
d2 = copy(du)

# Proportion of time both at nest
dms = dm[both_at_nest == TRUE, .(N_both_at_nest = .N), by = .(pairID, nestID, date_rel_pair)]
du = unique(dm, by = c('pairID', 'nestID', 'date_rel_pair'))
du = merge(du, dms, by = c('pairID', 'nestID', 'date_rel_pair'), all.x = TRUE)
du[is.na(N_both_at_nest), N_both_at_nest := 0]
du[, both_at_nest_prop := N_both_at_nest / N]
d3 = copy(du)

# Proportion of time male alone at nest
dms = dm[m_alone_at_nest == TRUE, .(N_m_alone_at_nest = .N), by = .(pairID, nestID, date_rel_pair)]
du = unique(dm, by = c('pairID', 'nestID', 'date_rel_pair'))
du = merge(du, dms, by = c('pairID', 'nestID', 'date_rel_pair'), all.x = TRUE)
du[is.na(N_m_alone_at_nest), N_m_alone_at_nest := 0]
du[, m_alone_at_nest_prop := N_m_alone_at_nest / N]
d4 = copy(du)

# Proportion of time female alone at nest
dms = dm[f_alone_at_nest == TRUE, .(N_f_alone_at_nest = .N), by = .(pairID, nestID, date_rel_pair)]
du = unique(dm, by = c('pairID', 'nestID', 'date_rel_pair'))
du = merge(du, dms, by = c('pairID', 'nestID', 'date_rel_pair'), all.x = TRUE)
du[is.na(N_f_alone_at_nest), N_f_alone_at_nest := 0]
du[, f_alone_at_nest_prop := N_f_alone_at_nest / N]
d5 = copy(du)

# male alone and not at the nest
d6 = merge(d0[, .(pairID, nestID, ID1, ID2, date_rel_pair, int_prop)], 
           d4[, .(pairID, nestID, ID1, ID2, date_rel_pair, m_alone_at_nest_prop)], 
           by = c('pairID', 'nestID', 'ID1', 'ID2','date_rel_pair'), all.x = TRUE)
d6[, m_alone_prop := 1 - c(int_prop + m_alone_at_nest_prop)]

d6[, total := m_alone_prop + int_prop + m_alone_at_nest_prop]

# female alone and not at the nest
d7 = merge(d0[, .(pairID, nestID, ID1, ID2, date_rel_pair, int_prop)], 
           d5[, .(pairID, nestID, ID1, ID2, date_rel_pair, f_alone_at_nest_prop)], 
           by = c('pairID', 'nestID', 'ID1', 'ID2', 'date_rel_pair'), all.x = TRUE)
d7[, f_alone_prop := 1 - c(int_prop + f_alone_at_nest_prop)]

d7[, total := f_alone_prop + int_prop + f_alone_at_nest_prop]



# merge data
du = rbindlist(list(d0[, .(pairID, nestID, ID1, ID2, date_rel_pair, prop = int_prop, type = 'm_f_together')],
                    d1[, .(pairID, nestID, ID1, ID2, date_rel_pair, prop = m_at_nest_prop, type = 'm_at_nest_prop')],
                    d2[, .(pairID, nestID, ID1, ID2, date_rel_pair, prop = f_at_nest_prop, type = 'f_at_nest_prop')],
                    d3[, .(pairID, nestID, ID1, ID2, date_rel_pair, prop = both_at_nest_prop, type = 'both_at_nest_prop')],
                    d4[, .(pairID, nestID, ID1, ID2, date_rel_pair, prop = m_alone_at_nest_prop, type = 'm_alone_at_nest_prop')],
                    d5[, .(pairID, nestID, ID1, ID2, date_rel_pair, prop = f_alone_at_nest_prop, type = 'f_alone_at_nest_prop')],
                    d6[, .(pairID, nestID, ID1, ID2, date_rel_pair, prop = m_alone_prop, type = 'm_alone_prop')],
                    d7[, .(pairID, nestID, ID1, ID2, date_rel_pair, prop = f_alone_prop, type = 'f_alone_prop')]
))



# descriptive statistic

# day before clutch initiation
du[type == 'f_at_nest_prop' & date_rel_pair == -1, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##       50%       25%       75% 
## 10.072464  6.700938 18.914625
du[type == 'm_at_nest_prop' & date_rel_pair == -1, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##       50%       25%       75% 
## 11.084746  6.719141 18.658088
# at clutch initiation
du[type == 'f_at_nest_prop' & date_rel_pair == 0, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##      50%      25%      75% 
## 15.53886 10.00000 23.25013
du[type == 'm_at_nest_prop' & date_rel_pair == 0, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##      50%      25%      75% 
## 20.39513 14.38519 26.82687
# at clutch last day of egg laying
du[type == 'f_at_nest_prop' & date_rel_pair == 3, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##        50%        25%        75% 
##  6.9767442  0.7194245 25.3333333
du[type == 'm_at_nest_prop' & date_rel_pair == 3, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##      50%      25%      75% 
## 65.74074 47.36842 75.75758
## without partner at nest
# clutch initiation 
du[type == 'f_alone_at_nest_prop' & date_rel_pair == 0, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##      50%      25%      75% 
## 0.000000 0.000000 1.471429
du[type == 'm_alone_at_nest_prop' & date_rel_pair == 0, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##      50%      25%      75% 
## 4.375000 1.969462 8.352804
# at clutch last day of egg laying
du[type == 'f_alone_at_nest_prop' & date_rel_pair == 3, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
## 50% 25% 75% 
##   0   0   0
du[type == 'm_alone_at_nest_prop' & date_rel_pair == 3, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##      50%      25%      75% 
## 46.42857 35.86957 69.87952
### without partner away from nest
# clutch initiation 
du[type == 'f_alone_prop' & date_rel_pair == 0, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##       50%       25%       75% 
## 12.038867  8.034188 19.743590
du[type == 'm_alone_prop' & date_rel_pair == 0, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##       50%       25%       75% 
##  8.874074  3.502747 13.965116
# at clutch last day of egg laying
du[type == 'f_alone_prop' & date_rel_pair == 3, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##      50%      25%      75% 
## 70.83333 54.34783 93.52518
du[type == 'm_alone_prop' & date_rel_pair == 3, quantile(prop, c(0.5, 0.25, 0.75), na.rm = TRUE)] * 100
##      50%      25%      75% 
## 18.54839 10.94891 27.90698
# pairwise sample size
dus = unique(dp, by = c('pairID', 'nestID', 'date_rel_pair'))
dss = unique(dus[datetime_rel_pair >= -10 & datetime_rel_pair <= 10], 
             by = c('nestID', 'date_rel_pair'))
dss = dss[, .N, by = date_rel_pair]
dss
##     date_rel_pair  N
##  1:           -10  2
##  2:            -9  6
##  3:            -8 11
##  4:            -7 17
##  5:            -6 23
##  6:            -5 30
##  7:            -4 33
##  8:            -3 42
##  9:            -2 40
## 10:            -1 44
## 11:             0 48
## 12:             1 53
## 13:             2 52
## 14:             3 45
## 15:             4 36
## 16:             5 36
## 17:             6 27
## 18:             7 23
## 19:             8 22
## 20:             9 19
## 21:            10 14
##     date_rel_pair  N
# order
dus = du[type == 'm_at_nest_prop' | type == 'f_at_nest_prop']
dus[, type := factor(type, levels = c('m_at_nest_prop', 'f_at_nest_prop'))]


# Males and females at the nest
pa = 
ggplot() +
  geom_text(data = dss, aes(date_rel_pair, Inf, label = N), vjust = 1, size = sample_size_label) +
  geom_rect(aes(xmin = -0.5, xmax = 3.5, ymin = -0.01, ymax = 1), fill = egg_laying_color) +
  geom_boxplot(data = dus, 
               aes(date_rel_pair, prop, group = interaction(date_rel_pair, type), color = type),
               lwd = 0.3, outlier.size = 0.7, outlier.alpha = 0) +
  geom_point(data = dus, 
             aes(date_rel_pair, prop, group = interaction(date_rel_pair, type), color = type), 
             position=position_jitterdodge(), size = 0.2) +
  scale_color_manual(values = c(male_col, female_col), name = '', 
                     labels = c('Male', 'Female'), drop = FALSE) +
  scale_x_continuous(limits = c(-10.4, 10.4), breaks = seq(-10, 10, 1), 
                     labels = c('-10', '', '-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10'),
                     expand = expansion(add = c(0.2, 0.2))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0.05))) +
  theme_classic(base_size = 10) +
  theme(legend.position = c(0.07, 0.9), legend.background = element_blank(), plot.margin = margin_top) +
  ylab('Proportion of time at nest') +
  xlab('Day relative to clutch initiation (= 0)')

pa

# Males alone and alone at nest
pd = 
  ggplot() +
  geom_text(aes(-5.2, Inf, label = 'Male'), vjust = 1, hjust = 0, size = 3.3) +
  geom_rect(aes(xmin = -0.5, xmax = 3.5, ymin = -0.01, ymax = 1), fill = egg_laying_color) +
  geom_boxplot(data = du[type == 'm_alone_prop' | type == 'm_alone_at_nest_prop'], 
               aes(date_rel_pair, prop, group = interaction(date_rel_pair, type), color = type),
               lwd = 0.3, outlier.size = 0.7, outlier.alpha = 0) +
  geom_point(data = du[type == 'm_alone_prop' | type == 'm_alone_at_nest_prop'], 
             aes(date_rel_pair, prop, group = interaction(date_rel_pair, type), color = type), 
             position=position_jitterdodge(), size = 0.2) +
  scale_color_manual(values = c(male_col, col2), name = '', 
                     labels = c('at nest', 'not at nest'), drop = FALSE) +
  scale_x_continuous(limits = c(-5.4, 5.4), breaks = seq(-5, 5, 1), 
                     labels = c('', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', ''),
                     expand = expansion(add = c(0.2, 0.2))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0.05))) +
  theme_classic(base_size = 10) +
  theme(legend.position = c(0.18, 0.9), legend.background = element_blank(), plot.margin = margin_top) +
  ylab('Proportion of time alone') +
  xlab('Day relative to clutch initiation (= 0)')

pd
## Warning: Removed 336 rows containing missing values (`stat_boxplot()`).
## Warning: Removed 336 rows containing missing values (`geom_point()`).

# Female alone and alone at nest
pe = 
  ggplot() +
  geom_text(aes(-5.2, Inf, label = 'Female'), vjust = 1, hjust = 0, size = 3.3) +
  geom_rect(aes(xmin = -0.5, xmax = 3.5, ymin = -0.01, ymax = 1), fill = egg_laying_color) +
  geom_boxplot(data = du[type == 'f_alone_prop' | type == 'f_alone_at_nest_prop'], 
               aes(date_rel_pair, prop, group = interaction(date_rel_pair, type), color = type),
               lwd = 0.3, outlier.size = 0.7, outlier.alpha = 0) +
  geom_point(data = du[type == 'f_alone_prop' | type == 'f_alone_at_nest_prop'], 
             aes(date_rel_pair, prop, group = interaction(date_rel_pair, type), color = type), 
             position=position_jitterdodge(), size = 0.2) +
  scale_color_manual(values = c(female_col, col2), name = '', 
                     labels = c('at nest', 'not at nest'), drop = FALSE) +
  scale_x_continuous(limits = c(-5.4, 5.4), breaks = seq(-5, 5, 1), 
                     labels = c('', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', ''),
                     expand = expansion(add = c(0.2, 0.2))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0.05))) +
  theme_classic(base_size = 10) +
  theme(legend.position = c(0.18, 0.9), legend.background = element_blank(), plot.margin = margin_top) +
  ylab('') +
  xlab('Day relative to clutch initiation (= 0)')

pe
## Warning: Removed 336 rows containing missing values (`stat_boxplot()`).
## Removed 336 rows containing missing values (`geom_point()`).

# statistic 

# merge du with clutch initiation date
dni = unique(dp[, .(nestID, initiation_rel)], by = 'nestID')
du = merge(du, dni, by = 'nestID', all.x = TRUE)

### during egg-laying male
dx = du[type == 'm_at_nest_prop' & date_rel_pair >= 0 & date_rel_pair <= 3]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 56
unique(dx$ID1) |> length() # N males
## [1] 53
unique(dx$ID2) |> length() # N females
## [1] 50
dx |> nrow() # N observations
## [1] 198
# beta models only accept proportion in the (0,1) interval
dx[prop == 1, prop := 0.9999]
dx[prop == 0, prop := 0.0001]

# model
m <- glmmTMB(prop ~ date_rel_pair + initiation_rel + 
               (date_rel_pair | nestID),
             family =  beta_family(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)


plot(allEffects(m))

summary(m)
##  Family: beta  ( logit )
## Formula:          prop ~ date_rel_pair + initiation_rel + (date_rel_pair | nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   -187.3   -164.3    100.7   -201.3      194 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr  
##  nestID (Intercept)   0.2125   0.4610         
##         date_rel_pair 0.1805   0.4248   -0.11 
## Number of obs: 198, groups:  nestID, 56
## 
## Dispersion parameter for beta family (): 14.9 
## 
## Conditional model:
##                Estimate Std. Error z value Pr(>|z|)    
## (Intercept)    -1.31409    0.09689 -13.562  < 2e-16 ***
## date_rel_pair   0.55305    0.07133   7.753 8.97e-15 ***
## initiation_rel  0.03929    0.02280   1.723   0.0849 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.64663, p-value < 2.2e-16
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning: mu of 0.4 is too close to zero, estimate of random effect variances may be unreliable.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S14. GLMM male at nest 0 to 3')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')


# descriptive part
x = effect("initiation_rel", m, xlevels = 22) |>
  data.frame() |>
  setDT() |> 
  print() 
##     initiation_rel       fit         se     lower     upper
##  1:          -8.00 0.3072924 0.04692959 0.2231132 0.4066091
##  2:          -7.00 0.3157188 0.04340265 0.2369031 0.4067783
##  3:          -6.10 0.3234078 0.04024640 0.2495714 0.4072345
##  4:          -5.10 0.3320643 0.03682160 0.2638064 0.4081910
##  5:          -4.20 0.3399536 0.03388728 0.2766082 0.4095918
##  6:          -3.20 0.3488247 0.03090763 0.2905805 0.4119639
##  7:          -2.30 0.3568994 0.02861248 0.3026513 0.4150833
##  8:          -1.30 0.3659675 0.02668240 0.3151081 0.4200017
##  9:          -0.38 0.3743950 0.02566880 0.3252949 0.4262246
## 10:           0.57 0.3831780 0.02554497 0.3342029 0.4346448
## 11:           1.50 0.3918506 0.02639521 0.3411920 0.4449508
## 12:           2.50 0.4012526 0.02832834 0.3468768 0.4581727
## 13:           3.40 0.4097773 0.03084445 0.3506002 0.4716877
## 14:           4.40 0.4193128 0.03432674 0.3535130 0.4881130
## 15:           5.30 0.4279469 0.03793651 0.3552929 0.5038470
## 16:           6.30 0.4375918 0.04234209 0.3565760 0.5220791
## 17:           7.20 0.4463130 0.04657245 0.3572625 0.5389479
## 18:           8.20 0.4560419 0.05148884 0.3576364 0.5580033
## 19:           9.10 0.4648269 0.05605548 0.3577057 0.5752943
## 20:          10.00 0.4736337 0.06071733 0.3575792 0.5926088
## 21:          11.00 0.4834381 0.06597192 0.3572584 0.6117657
## 22:          12.00 0.4932553 0.07127192 0.3567878 0.6307354
##     initiation_rel       fit         se     lower     upper
# before and after peak
x[initiation_rel <= 0, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 34.05026 3.479543
x[initiation_rel >= 0, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 43.75707 4.444587
x = effect("date_rel_pair", m, xlevels = 4) |>
  data.frame() |>
  setDT() |> 
  print() 
##    date_rel_pair       fit         se     lower     upper
## 1:             0 0.2136641 0.01614057 0.1835551 0.2472166
## 2:             1 0.3208376 0.02006158 0.2826203 0.3616178
## 3:             2 0.4509405 0.03312643 0.3868102 0.5167430
## 4:             3 0.5881159 0.04691009 0.4935642 0.6765822
x[, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 39.33895 2.905967
# extract effect from model for plot
e = effect("initiation_rel", m, xlevels = 100) |>
  data.frame() |>
  setDT()


# data for points 
dms = dm[period == "[0,3]"]
dms[, N_nest_season := .N, by = .(pairID, nestID, initiation_rel)]
dus = unique(dms[!is.na(N_nest_season)], by = c('pairID', 'nestID', 'initiation_rel'))
dus[, .(min(N_nest_season), max(N_nest_season))] # check min and max
##    V1  V2
## 1: 14 559
dus[, .(min(initiation_rel), max(initiation_rel))] # check min and max
##    V1 V2
## 1: -8 12
dms = dm[m_at_nest == TRUE & period == "[0,3]", 
         .(N_m_at_nest = .N), by = .(pairID, nestID, initiation_rel)]
dus = merge(dus, dms, by = c('pairID', 'nestID', 'initiation_rel'), all.x = TRUE)
dus[is.na(N_m_at_nest), N_m_at_nest := 0]
dus[, m_at_nest_prop := N_m_at_nest / N_nest_season]
d1 = copy(dus)

# point sizes range
dus[, .(min(N_nest_season), max(N_nest_season))]
##    V1  V2
## 1: 14 559
pb = 
  ggplot() +
  geom_text(aes(-7.8, Inf, label = 'Day 0 to 3 (Male)'), vjust = 1, hjust = 0, size = 3.3) +
  geom_point(data = dus, aes(initiation_rel, m_at_nest_prop, size = N_nest_season), shape = 1, 
             color = male_col) +
  geom_line(data = e, aes(y = fit, x = initiation_rel), size = 0.8, color = male_col) +
  geom_ribbon(data = e, aes(y = fit, x = initiation_rel, ymin = lower, ymax = upper), alpha = 0.2, 
              fill = male_col) +
  scale_x_continuous(limits = c(-8, 12), breaks = seq(-8, 12, 1), 
                     labels = c('-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10', '', '12'),
                     expand = expansion(add = c(0.4, 0.4))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0.05, 0.05))) +
  scale_size_area(max_size = 4, breaks=c(100, 300, 500)) +
  theme_classic(base_size = 10) +
  theme(legend.position = 'none', legend.background = element_blank(), plot.margin = margin_, 
        legend.spacing.y = unit(-0.2, "cm"), legend.title = element_blank()) +
  ylab('Proportion of time at nest') +
  xlab('Clutch initiation date (standardized)')

pb

### during egg-laying female
dx = du[type == 'f_at_nest_prop' & date_rel_pair >= 0 & date_rel_pair <= 3]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 56
unique(dx$ID1) |> length() # N males
## [1] 53
unique(dx$ID2) |> length() # N females
## [1] 50
dx |> nrow() # N observations
## [1] 198
# beta models only accept proportion in the (0,1) interval
dx[prop == 1, prop := 0.9999]
dx[prop == 0, prop := 0.0001]

# model
m <- glmmTMB(prop ~ date_rel_pair + poly(initiation_rel, 2) + 
               (date_rel_pair | nestID),
             family =  beta_family(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)


plot(allEffects(m))

summary(m)
##  Family: beta  ( logit )
## Formula:          prop ~ date_rel_pair + poly(initiation_rel, 2) + (date_rel_pair |      nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   -500.1   -473.8    258.0   -516.1      194 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr 
##  nestID (Intercept)   0.1898   0.4357        
##         date_rel_pair 0.1220   0.3493   0.25 
## Number of obs: 198, groups:  nestID, 56
## 
## Dispersion parameter for beta family (): 14.3 
## 
## Conditional model:
##                          Estimate Std. Error z value Pr(>|z|)    
## (Intercept)              -1.59367    0.10112 -15.761  < 2e-16 ***
## date_rel_pair            -0.25078    0.06831  -3.671 0.000241 ***
## poly(initiation_rel, 2)1  4.68538    1.43945   3.255 0.001134 ** 
## poly(initiation_rel, 2)2 -3.94660    1.31607  -2.999 0.002711 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.69202, p-value = 0.12
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning: mu of 0.2 is too close to zero, estimate of random effect variances may be unreliable.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S15. GLMM female at nest 0 to 3')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')


# descriptive part
x = effect("poly(initiation_rel,2)", m, xlevels = 22) |>
  data.frame() |>
  setDT() |> 
  print() 
##     initiation_rel        fit         se      lower      upper
##  1:          -8.00 0.02692465 0.01112447 0.01183428 0.06008728
##  2:          -7.00 0.03653727 0.01224275 0.01874102 0.07002663
##  3:          -6.10 0.04693322 0.01286012 0.02717278 0.07988372
##  4:          -5.10 0.06033331 0.01310202 0.03911158 0.09196774
##  5:          -4.20 0.07382885 0.01304209 0.05188287 0.10403915
##  6:          -3.20 0.08997902 0.01297415 0.06745903 0.11905710
##  7:          -2.30 0.10503700 0.01324833 0.08162817 0.13417807
##  8:          -1.30 0.12164419 0.01417781 0.09633238 0.15248455
##  9:          -0.38 0.13612313 0.01556571 0.10823123 0.16983404
## 10:           0.57 0.14957880 0.01727286 0.11860389 0.18692757
## 11:           1.50 0.16067413 0.01894130 0.12672479 0.20161864
## 12:           2.50 0.16973554 0.02055354 0.13294672 0.21418969
## 13:           3.40 0.17496910 0.02185119 0.13594851 0.22230799
## 14:           4.40 0.17726425 0.02331197 0.13584360 0.22798264
## 15:           5.30 0.17606877 0.02490214 0.13218599 0.23064773
## 16:           6.30 0.17117898 0.02724155 0.12390201 0.23172397
## 17:           7.20 0.16377235 0.02993627 0.11289114 0.23159917
## 18:           8.20 0.15259314 0.03341431 0.09761105 0.23063014
## 19:           9.10 0.14034291 0.03664432 0.08230101 0.22909940
## 20:          10.00 0.12655623 0.03956163 0.06675604 0.22690120
## 21:          11.00 0.11014350 0.04195900 0.05051708 0.22357616
## 22:          12.00 0.09337895 0.04304786 0.03640644 0.21922415
##     initiation_rel        fit         se      lower      upper
x[fit > 0.15]
##    initiation_rel       fit         se      lower     upper
## 1:            1.5 0.1606741 0.01894130 0.12672479 0.2016186
## 2:            2.5 0.1697355 0.02055354 0.13294672 0.2141897
## 3:            3.4 0.1749691 0.02185119 0.13594851 0.2223080
## 4:            4.4 0.1772642 0.02331197 0.13584360 0.2279826
## 5:            5.3 0.1760688 0.02490214 0.13218599 0.2306477
## 6:            6.3 0.1711790 0.02724155 0.12390201 0.2317240
## 7:            7.2 0.1637724 0.02993627 0.11289114 0.2315992
## 8:            8.2 0.1525931 0.03341431 0.09761105 0.2306301
# before and after peak
x[initiation_rel <= 1, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 8.469194 1.356103
x[initiation_rel >= 2 & initiation_rel <= 5, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 17.39896 2.190557
x[initiation_rel >= 6, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 13.68523 3.597213
x = effect("date_rel_pair", m, xlevels = 4) |>
  data.frame() |>
  setDT() |> 
  print() 
##    date_rel_pair       fit         se      lower     upper
## 1:             0 0.1980059 0.01817284 0.16458406 0.2362951
## 2:             1 0.1611645 0.01615073 0.13179168 0.1956087
## 3:             2 0.1300661 0.01781148 0.09878116 0.1693969
## 4:             3 0.1042229 0.01972076 0.07124198 0.1500062
x[, .(fit = mean(fit), se = mean(se))] * 100
##         fit       se
## 1: 14.83649 1.796395
# extract effect from model for plot
e = effect("poly(initiation_rel,2)", m, xlevels = 100) |>
  data.frame() |>
  setDT()


# data for points 
dms = dm[date_rel_pair >= 0 & date_rel_pair <= 3]
dms[, N_nest_season := .N, by = .(pairID, nestID, initiation_rel)]
dus = unique(dms[!is.na(N_nest_season)], by = c('pairID', 'nestID', 'initiation_rel'))
dus[, .(min(N_nest_season), max(N_nest_season))] # check min and max
##    V1  V2
## 1: 14 559
dus[, .(min(initiation_rel), max(initiation_rel))] # check min and max
##    V1 V2
## 1: -8 12
dms = dm[f_at_nest == TRUE & date_rel_pair >= 0 & date_rel_pair <= 3, 
         .(N_f_at_nest = .N), by = .(pairID, nestID, initiation_rel)]
dus = merge(dus, dms, by = c('pairID', 'nestID', 'initiation_rel'), all.x = TRUE)
dus[is.na(N_f_at_nest), N_f_at_nest := 0]
dus[, f_at_nest_prop := N_f_at_nest / N_nest_season]
d1 = copy(du)

# point sizes range
dus[, .(min(N_nest_season), max(N_nest_season))]
##    V1  V2
## 1: 14 559
pc = 
  ggplot() +
  geom_text(aes(-7.8, Inf, label = 'Day 0 to 3 (Female)'), vjust = 1, hjust = 0, size = 3.3) +
  geom_point(data = dus, aes(initiation_rel, f_at_nest_prop, size = N_nest_season), shape = 1, 
             color = female_col) +
  geom_line(data = e, aes(y = fit, x = initiation_rel), size = 0.8, color = female_col) +
  geom_ribbon(data = e, aes(y = fit, x = initiation_rel, ymin = lower, ymax = upper), alpha = 0.2, 
              fill = female_col) +
  scale_x_continuous(limits = c(-8, 12), breaks = seq(-8, 12, 1), 
                     labels = c('-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10', '', '12'),
                     expand = expansion(add = c(0.4, 0.4))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0.05, 0.05))) +
  scale_size_area(max_size = 4, breaks=c(100, 300, 500)) +
  theme_classic(base_size = 10) +
  theme(legend.position = 'none', legend.background = element_blank(), plot.margin = margin_, 
        legend.spacing.y = unit(-0.2, "cm"), legend.title = element_blank()) +
  ylab('') +
  xlab('Clutch initiation date (standardized)')

pc

# merge plots
pa + pb + pc + pd + pe +
  plot_layout(design = "
  11
  23
  45
") +
  # plot_layout(heights = c(1, 4, 4)) +
  plot_annotation(tag_levels = 'a')
## Warning: Removed 336 rows containing missing values (`stat_boxplot()`).
## Removed 336 rows containing missing values (`geom_point()`).
## Warning: Removed 336 rows containing missing values (`stat_boxplot()`).
## Warning: Removed 336 rows containing missing values (`geom_point()`).

# ggsave('./OUTPUTS/FIGURES/male_female_at_nest.tiff', plot = last_plot(),  width = 177, height = 238,
#        units = c('mm'), dpi = 'print')

Mate guarding intensity and extra-pair paternity

# pairwise sample size
du = unique(dp, by = c('pairID', 'nestID', 'date_rel_pair'))
dss = unique(du[anyEPY == FALSE & date_rel_pair >= -10 & date_rel_pair <= 10], 
             by = c('nestID', 'date_rel_pair'))
dss = dss[, .N, by = date_rel_pair]

# pairwise sample size
dss_epy = unique(du[anyEPY == TRUE & date_rel_pair >= -10 & date_rel_pair <= 10], 
             by = c('nestID', 'date_rel_pair'))
dss_epy = dss_epy[, .N, by = date_rel_pair]
dss_epy
##     date_rel_pair N
##  1:            -7 1
##  2:            -6 1
##  3:            -5 2
##  4:            -4 3
##  5:            -3 4
##  6:            -2 4
##  7:            -1 5
##  8:             0 5
##  9:             1 6
## 10:             2 6
## 11:             3 6
## 12:             4 4
## 13:             5 4
## 14:             6 2
## 15:             7 2
## 16:             8 2
## 17:             9 2
## 18:            10 2
# merge 
dss = merge(dss, dss_epy[, .(N_epy = N, date_rel_pair)], by = 'date_rel_pair', all.x = TRUE)
dss[, N_epy_label := paste0(N, '/', N_epy)]

# Proportion of time together breeders
dps = dp[interaction == TRUE, .(N_int = .N), by = .(pairID, nestID, date_rel_pair)]
du = unique(dp, by = c('pairID', 'nestID', 'date_rel_pair'))
du = merge(du, dps, by = c('pairID', 'nestID', 'date_rel_pair'), all.x = TRUE)
du[is.na(N_int), N_int := 0]
du[, int_prop := N_int / N]

# N 
du[, .N, by = pairID] |> nrow()
## [1] 64
du[, .N, by = nestID] |> nrow()
## [1] 68
du = du[date_rel_pair >= -10 & date_rel_pair <= 10]

# median per day
dmd = du[, .(int_prop_median = median(int_prop)), by = date_rel_pair]

# order
du[, any_EPY_plot := ifelse(anyEPY == TRUE, 'EPY', 'No EPY')]
du[, any_EPY_plot := factor(any_EPY_plot, levels = c('No EPY', 'EPY'))]

### plot proportion of time together 
pa = 
ggplot() +
  geom_text(data = dss, aes(date_rel_pair, Inf, label = N_epy_label), vjust = 1, size = sample_size_label) +
  geom_rect(aes(xmin = -0.5, xmax = 3.5, ymin = -0.01, ymax = 1), fill = egg_laying_color) +
  geom_boxplot(data = du[!is.na(anyEPY)], 
               aes(date_rel_pair, int_prop, group = interaction(date_rel_pair, any_EPY_plot), 
                   color = any_EPY_plot),
               lwd = 0.3, outlier.size = 0.7, outlier.alpha = 0) +
  geom_point(data = du[!is.na(anyEPY)], 
             aes(date_rel_pair, int_prop, group = interaction(date_rel_pair, any_EPY_plot), 
                 color = any_EPY_plot), 
             position=position_jitterdodge(), size = 0.2) +
  scale_color_manual(values = c(col1, col2), name = '', 
                     labels = c('No EPP', 'EPP'), drop = FALSE) +
  scale_x_continuous(limits = c(-5.4, 5.4), breaks = seq(-5, 5, 1), 
                     labels = c('', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', ''),
                     expand = expansion(add = c(0.2, 0.2))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0.05))) +
  theme_classic(base_size = 10) +
  theme(legend.position = c(0.18, 0.14), legend.background = element_blank(), plot.margin = margin_) +
  ylab('Proportion of time together') +
  xlab('Day relative to clutch initiation (= 0)')

pa
## Warning: Removed 168 rows containing missing values (`stat_boxplot()`).
## Warning: Removed 10 rows containing missing values (`geom_text()`).
## Warning: Removed 168 rows containing missing values (`geom_point()`).

# descriptive statistic

# fertile period 
du[anyEPY == TRUE & date_rel_pair >= -5 & date_rel_pair <= 2, quantile(int_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##       50%       25%       75% 
## 0.7826087 0.6575682 0.9580420
du[anyEPY == FALSE & date_rel_pair >= -5 & date_rel_pair <= 2, quantile(int_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##       50%       25%       75% 
## 0.8787879 0.6331382 0.9744107
# before clutch initiation period 
du[anyEPY == TRUE & date_rel_pair >= -5 & date_rel_pair <= -1, quantile(int_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##       50%       25%       75% 
## 0.9027559 0.6818182 0.9950000
du[anyEPY == FALSE & date_rel_pair >= -5 & date_rel_pair <= -1, quantile(int_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##       50%       25%       75% 
## 0.9583333 0.8897059 1.0000000
# after clutch initiation period 
du[anyEPY == TRUE & date_rel_pair >= 0 & date_rel_pair <= 3, quantile(int_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##       50%       25%       75% 
## 0.6612903 0.4802294 0.8231225
du[anyEPY == FALSE & date_rel_pair >= 0 & date_rel_pair <= 3, quantile(int_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##       50%       25%       75% 
## 0.5977011 0.2888849 0.8176772
### before clutch initiation
dx = du[!is.na(anyEPY) & period == "[-5,-1]"]
dx[, prop := int_prop]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 49
unique(dx$ID1) |> length() # N males
## [1] 47
unique(dx$ID2) |> length() # N females
## [1] 46
dx |> nrow() # N observations
## [1] 183
# by anyEPY
dxu = unique(dx, by = c('nestID', 'anyEPY')) 
dxu[, .N, by = anyEPY]
##    anyEPY  N
## 1:  FALSE 44
## 2:   TRUE  5
dx[, .N, by = anyEPY]
##    anyEPY   N
## 1:  FALSE 165
## 2:   TRUE  18
# beta models only accept proportion in the (0,1) interval
dx[prop == 1, prop := 0.9999]
dx[prop == 0, prop := 0.0001]

# model
m <- glmmTMB(prop ~ poly(date_rel_pair, 2) + poly(initiation_rel, 2) + anyEPY + 
               (date_rel_pair | nestID),
             family =  beta_family(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)


plot(allEffects(m))

summary(m)
##  Family: beta  ( logit )
## Formula:          prop ~ poly(date_rel_pair, 2) + poly(initiation_rel, 2) + anyEPY +      (date_rel_pair | nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   -746.9   -714.8    383.5   -766.9      179 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr 
##  nestID (Intercept)   2.9049   1.704         
##         date_rel_pair 0.3981   0.631    0.94 
## Number of obs: 183, groups:  nestID, 49
## 
## Dispersion parameter for beta family (): 4.26 
## 
## Conditional model:
##                          Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                2.0252     0.1793  11.295  < 2e-16 ***
## poly(date_rel_pair, 2)1    4.7759     2.2607   2.113   0.0346 *  
## poly(date_rel_pair, 2)2   -4.7494     1.1244  -4.224 2.40e-05 ***
## poly(initiation_rel, 2)1   1.0120     1.5770   0.642   0.5211    
## poly(initiation_rel, 2)2  -6.7902     1.6612  -4.088 4.36e-05 ***
## anyEPYTRUE                -0.2078     0.4092  -0.508   0.6116    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.88534, p-value = 0.488
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning: Model's distribution-specific variance is negative. Results are not reliable.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S16. GLMM together and EPY -5 to -1')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')


# extract effect from model for plot
e1 = effect("anyEPY", m, xlevels = 2) |>
  data.frame() |>
  setDT()



### during egg-laying fertile period
dx = du[!is.na(anyEPY) & date_rel_pair >= 0 & date_rel_pair <= 2]
dx[, prop := int_prop]

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 54
unique(dx$ID1) |> length() # N males
## [1] 51
unique(dx$ID2) |> length() # N females
## [1] 48
dx |> nrow() # N observations
## [1] 147
# by anyEPY
dxu = unique(dx, by = c('nestID', 'anyEPY')) 
dxu[, .N, by = anyEPY]
##    anyEPY  N
## 1:  FALSE 48
## 2:   TRUE  6
dx[, .N, by = anyEPY]
##    anyEPY   N
## 1:  FALSE 130
## 2:   TRUE  17
# beta models only accept proportion in the (0,1) interval
dx[prop == 1, prop := 0.9999]
dx[prop == 0, prop := 0.0001]

# model
m <- glmmTMB(prop ~ date_rel_pair + poly(initiation_rel, 2) + anyEPY + 
               (date_rel_pair | nestID),
             family =  beta_family(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)
## Warning in fitTMB(TMBStruc): Model convergence problem; singular convergence (7). See vignette('troubleshooting')
plot(allEffects(m))

summary(m)
##  Family: beta  ( logit )
## Formula:          prop ~ date_rel_pair + poly(initiation_rel, 2) + anyEPY + (date_rel_pair |      nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   -140.6   -113.7     79.3   -158.6      143 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr 
##  nestID (Intercept)   0.38363  0.6194        
##         date_rel_pair 0.09925  0.3150   1.00 
## Number of obs: 147, groups:  nestID, 54
## 
## Dispersion parameter for beta family (): 10.1 
## 
## Conditional model:
##                          Estimate Std. Error z value Pr(>|z|)    
## (Intercept)               1.44422    0.14059  10.272  < 2e-16 ***
## date_rel_pair            -0.93535    0.08982 -10.414  < 2e-16 ***
## poly(initiation_rel, 2)1  4.09314    1.56979   2.607 0.009122 ** 
## poly(initiation_rel, 2)2 -5.31044    1.47013  -3.612 0.000304 ***
## anyEPYTRUE                0.50542    0.41272   1.225 0.220720    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.92423, p-value = 0.552
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 
## Warning: mu of 3.7 is too close to zero, estimate of random effect variances may be unreliable.
## Warning: Model's distribution-specific variance is negative. Results are not reliable.
setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S17. GLMM together and EPY 0 to 2')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')


# extract effect from model for plot
e2 = effect("anyEPY", m, xlevels = 2) |>
  data.frame() |>
  setDT()


# plot EPY effect

# merge data
e1[, type := '-5 to -1']
e2[, type := '0 to 2']

e = rbind(e1, e2)

# pairwise sample size
du = unique(dp, by = c('pairID', 'nestID', 'date_rel_pair'))
du = du[date_rel_pair >= -5 & date_rel_pair <= 2]
du[, type := ifelse(date_rel_pair >= 0, '0 to 2', '-5 to -1')]
dsss = unique(du[anyEPY == FALSE], by = c('nestID', 'type'))
dsss = dsss[, .N, by = type]

dsss_epy = unique(du[anyEPY == TRUE], by = c('nestID', 'type'))
dsss_epy = dsss_epy[, .N, by = type]

# merge 
dsss = merge(dsss, dsss_epy[, .(N_epy = N, type)], by = 'type', all.x = TRUE)
dsss[, N_epy_label := paste0(N, '/', N_epy)]

# p values
dsp = data.table(type = c( '-5 to -1', '0 to 2'),
                 p_value = c('p = 0.61', 'p = 0.22'))


p1 =
  ggplot() +
  geom_point(data = e, aes(type, fit, group = interaction(anyEPY, type), color = anyEPY), 
             position = position_dodge(width = 0.5)) +
  geom_linerange(data = e, aes(x = type, ymin = upper, ymax = lower, color = anyEPY), size = 0.3, 
                 position = position_dodge(width = 0.5)) +
  scale_color_manual(values = c(col1, col2), name = '', 
                       labels = c('No EPP', 'EPP'), drop = FALSE) +
  geom_text(data = dsss, aes(type, Inf, label = N_epy_label), vjust = 1, size = sample_size_label) +
  geom_text(data = dsp, aes(type, c(0.8, 0.55), label = p_value), vjust = 1, size = sample_size_label) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                   labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                   expand = expansion(add = c(0, 0.05))) +
  theme_classic(base_size = 10) +
  theme(legend.position = c(0.3, 0.15), legend.background = element_blank(), 
        plot.margin = unit(c(2, 2, 0, 2), 'pt'), axis.title.x = element_blank()) +
  ylab('Proportion of time together') +
  xlab('')

p1

Split events and extra-pair paternity

# pairwise sample size
du = unique(dp[split == TRUE], by = c('pairID', 'nestID', 'date_rel_pair'))
dss = unique(du[anyEPY == FALSE & date_rel_pair >= -10 & date_rel_pair <= 10], 
             by = c('nestID', 'date_rel_pair'))
dss = dss[, .N, by = date_rel_pair]

# pairwise sample size
dss_epy = unique(du[anyEPY == TRUE & date_rel_pair >= -10 & date_rel_pair <= 10], 
                 by = c('nestID', 'date_rel_pair'))
dss_epy = dss_epy[, .N, by = date_rel_pair]
dss_epy
##     date_rel_pair N
##  1:            -6 1
##  2:            -5 1
##  3:            -4 3
##  4:            -3 4
##  5:             0 5
##  6:             1 6
##  7:             2 6
##  8:             3 4
##  9:             4 2
## 10:             5 3
## 11:             6 2
## 12:             7 2
## 13:             8 2
## 14:             9 2
## 15:            10 2
## 16:            -2 2
## 17:            -1 3
# merge 
dss = merge(dss, dss_epy[, .(N_epy = N, date_rel_pair)], by = 'date_rel_pair', all.x = TRUE)
dss[, N_epy_label := paste0(N, '/', N_epy)]

# plot splits and merges females 
dus = dusm[!is.na(anyEPY)]

# order
dus[, any_EPY_plot := ifelse(anyEPY == TRUE, 'EPY', 'No EPY')]
dus[, any_EPY_plot := factor(any_EPY_plot, levels = c('No EPY', 'EPY'))]


pb = 
ggplot() +
  geom_text(data = dss, aes(date_rel_pair, Inf, label = N_epy_label), vjust = 1, size = sample_size_label) +
  geom_rect(aes(xmin = -0.5, xmax = 3.5, ymin = -0.01, ymax = 1), fill = egg_laying_color) +
  geom_boxplot(data = dus, 
               aes(date_rel_pair, f_split_prop, group = interaction(date_rel_pair, any_EPY_plot), 
                   color = any_EPY_plot),
               lwd = 0.3, outlier.size = 0.7, outlier.alpha = 0) +
  geom_point(data = dus, 
             aes(date_rel_pair, f_split_prop, group = interaction(date_rel_pair, any_EPY_plot), 
                 color = any_EPY_plot), 
             position=position_jitterdodge(), size = 0.2) +
  scale_color_manual(values = c(col1, col2), name = '', 
                     labels = c('No EPP', 'EPP'), drop = FALSE) +
  scale_x_continuous(limits = c(-5.4, 5.4), breaks = seq(-10, 10, 1), 
                     labels = c('-10', '', '-8', '', '-6', '', '-4', '', '-2', '', '0', 
                                '', '2', '', '4', '', '6', '', '8', '', '10'),
                     expand = expansion(add = c(0.2, 0.2))) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0.05))) +
  theme_classic(base_size = 10) +
  theme(legend.position = c(10.86, 10.12), legend.background = element_blank(), plot.margin = margin_) +
  ylab('Proportion female moves away') +
  xlab('Day relative to clutch initiation (= 0)')


# merge plots
pa + pb + 
  plot_layout(ncol = 2) +
  plot_annotation(tag_levels = 'a')
## Warning: Removed 168 rows containing missing values (`stat_boxplot()`).
## Warning: Removed 10 rows containing missing values (`geom_text()`).
## Warning: Removed 168 rows containing missing values (`geom_point()`).
## Warning: Removed 115 rows containing missing values (`stat_boxplot()`).
## Warning: Removed 10 rows containing missing values (`geom_text()`).
## Warning: Removed 115 rows containing missing values (`geom_point()`).

# ggsave('./OUTPUTS/FIGURES/male_female_together_epy.tiff', plot = last_plot(),  width = 177, height = 89, 
#        units = c('mm'), dpi = 'print')



# descriptive statistic

# movements away fertile period 
dus[anyEPY == TRUE & date_rel_pair >= -5 & date_rel_pair <= 2, quantile(f_split_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##   50%   25%   75% 
## 0.500 0.400 0.875
dus[anyEPY == TRUE & date_rel_pair >= -5 & date_rel_pair <= 2, mean(f_split_prop, na.rm = TRUE)]
## [1] 0.6111111
dus[anyEPY == FALSE & date_rel_pair >= -5 & date_rel_pair <= 2, quantile(f_split_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##       50%       25%       75% 
## 0.5000000 0.1666667 0.7329545
dus[anyEPY == FALSE & date_rel_pair >= -5 & date_rel_pair <= 2, mean(f_split_prop, na.rm = TRUE)]
## [1] 0.4764009
# movements before clutch initiation
dus[anyEPY == TRUE & date_rel_pair >= -5 & date_rel_pair <= -1, quantile(f_split_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##       50%       25%       75% 
## 0.6666667 0.5000000 0.8750000
dus[anyEPY == TRUE & date_rel_pair >= -5 & date_rel_pair <= -1, mean(f_split_prop, na.rm = TRUE)]
## [1] 0.6576923
dus[anyEPY == FALSE & date_rel_pair >= -5 & date_rel_pair <= -1, quantile(f_split_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##       50%       25%       75% 
## 0.5000000 0.0000000 0.6666667
dus[anyEPY == FALSE & date_rel_pair >= -5 & date_rel_pair <= -1, mean(f_split_prop, na.rm = TRUE)]
## [1] 0.4302763
# movements away after clutch initiation
dus[anyEPY == TRUE & date_rel_pair >= 0 & date_rel_pair <= 3, quantile(f_split_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##       50%       25%       75% 
## 0.5000000 0.3333333 0.7500000
dus[anyEPY == TRUE & date_rel_pair >= 0 & date_rel_pair <= 3, mean(f_split_prop, na.rm = TRUE)]
## [1] 0.5484127
dus[anyEPY == FALSE & date_rel_pair >= -5 & date_rel_pair <= 3, quantile(f_split_prop, c(0.5, 0.25, 0.75), na.rm = TRUE)]
##       50%       25%       75% 
## 0.5000000 0.1666667 0.7500000
dus[anyEPY == FALSE & date_rel_pair >= -5 & date_rel_pair <= 3, mean(f_split_prop, na.rm = TRUE)]
## [1] 0.4835055
### Models 

# Statistic females moving away

### before clutch initiation
dx = dp[!is.na(anyEPY) & split == TRUE & period == "[-5,-1]"]
dx[, IDsplitting := ifelse(IDsplitting == 'ID1', 0, 1)] # males = 0

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 44
unique(dx$ID1) |> length() # N males
## [1] 44
unique(dx$ID2) |> length() # N females
## [1] 42
dx |> nrow() # N observations
## [1] 346
# by anyEPY
dxu = unique(dx, by = c('nestID', 'anyEPY')) 
dxu[, .N, by = anyEPY]
##    anyEPY  N
## 1:  FALSE 39
## 2:   TRUE  5
dx[, .N, by = anyEPY]
##    anyEPY   N
## 1:  FALSE 290
## 2:   TRUE  56
# model
m <- glmmTMB(IDsplitting ~ date_rel_pair + initiation_rel + anyEPY +
               (date_rel_pair | nestID),
             family =  binomial(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)
## Warning in fitTMB(TMBStruc): Model convergence problem; singular convergence (7). See vignette('troubleshooting')
plot(allEffects(m))

summary(m)
##  Family: binomial  ( logit )
## Formula:          IDsplitting ~ date_rel_pair + initiation_rel + anyEPY + (date_rel_pair |      nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##    466.3    493.2   -226.1    452.3      343 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr 
##  nestID (Intercept)   0.646337 0.80395       
##         date_rel_pair 0.008897 0.09432  1.00 
## Number of obs: 346, groups:  nestID, 44
## 
## Conditional model:
##                Estimate Std. Error z value Pr(>|z|)  
## (Intercept)    -0.30856    0.30216  -1.021   0.3072  
## date_rel_pair  -0.05577    0.08811  -0.633   0.5268  
## initiation_rel -0.12042    0.05087  -2.367   0.0179 *
## anyEPYTRUE      0.69207    0.45497   1.521   0.1282  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 0.99005, p-value = 0.808
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 


setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S18. GLMM female moves away and EPY -5 to -1')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')


# extract effect from model for plot
e1 = effect("anyEPY", m, xlevels = 2) |>
  data.frame() |>
  setDT()


### during egg-laying
dx = dp[!is.na(anyEPY) & split == TRUE & date_rel_pair >= 0 & date_rel_pair <= 2]
dx[, IDsplitting := ifelse(IDsplitting == 'ID1', 0, 1)] # males = 0

# sample size
unique(dx$nestID) |> length() # N nests
## [1] 53
unique(dx$ID1) |> length() # N males
## [1] 50
unique(dx$ID2) |> length() # N females
## [1] 48
dx |> nrow() # N observations
## [1] 715
# by anyEPY
dxu = unique(dx, by = c('nestID', 'anyEPY')) 
dxu[, .N, by = anyEPY]
##    anyEPY  N
## 1:  FALSE 47
## 2:   TRUE  6
dx[, .N, by = anyEPY]
##    anyEPY   N
## 1:  FALSE 624
## 2:   TRUE  91
# model
m <- glmmTMB(IDsplitting ~ date_rel_pair + initiation_rel + anyEPY +
               (date_rel_pair | nestID),
             family =  binomial(link = "logit"), data = dx, REML = TRUE,
             control = glmmTMBControl(parallel = 15)
)


plot(allEffects(m))

summary(m)
##  Family: binomial  ( logit )
## Formula:          IDsplitting ~ date_rel_pair + initiation_rel + anyEPY + (date_rel_pair |      nestID)
## Data: dx
## 
##      AIC      BIC   logLik deviance df.resid 
##   1003.7   1035.7   -494.9    989.7      712 
## 
## Random effects:
## 
## Conditional model:
##  Groups Name          Variance Std.Dev. Corr  
##  nestID (Intercept)   0.56470  0.7515         
##         date_rel_pair 0.09633  0.3104   -0.89 
## Number of obs: 715, groups:  nestID, 53
## 
## Conditional model:
##                Estimate Std. Error z value Pr(>|z|)
## (Intercept)    0.070258   0.184321   0.381    0.703
## date_rel_pair  0.002277   0.111585   0.020    0.984
## initiation_rel 0.023183   0.030247   0.766    0.443
## anyEPYTRUE     0.112732   0.313026   0.360    0.719
res <-simulateResiduals(m, plot = T)

testDispersion(res) 

## 
##  DHARMa nonparametric dispersion test via sd of residuals fitted vs. simulated
## 
## data:  simulationOutput
## dispersion = 1.0036, p-value = 0.664
## alternative hypothesis: two.sided
acf(resid(m), type = 'partial')

# create clean summary table
y = tidy(m) |> data.table()
x = r2(m) |> data.table() 


setnames(x, c('estimate'))
x[, estimate := as.numeric(estimate)]
x[, term :=  c('r2cond', 'r2marg')]
y = rbindlist(list(y, x), use.names = TRUE, fill = TRUE)
y[, row_order := rownames(y) |> as.numeric()]
y = merge(y, pn, by.x = 'term', by.y = 'parname')
setorder(y, row_order)
y = y[, .(Parameter = parameter, Estimate = estimate, SE = std.error, Statistic = statistic, p = p.value)]
y = y %>% mutate_if(is.numeric, ~round(., 3)) # round all numeric columns 

# save table in word
ft = flextable(y) |> autofit()
ft = bold(ft, bold = TRUE, part = "header")
ESM = ESM |> body_add_par(paste0('Table S19. GLMM female moves away and EPY 0 to 2')) |>  body_add_par('') |> 
  body_add_flextable(ft)
ESM = ESM |> body_add_break(pos = 'after')


# extract effect from model for plot
e2 = effect("anyEPY", m, xlevels = 2) |>
  data.frame() |>
  setDT()



# plot EPY effect

# merge data
e1[, type := '-5 to -1']
e2[, type := '0 to 2']

e = rbind(e1, e2)

# pairwise sample size
du = unique(dp[split == TRUE], by = c('pairID', 'nestID', 'date_rel_pair'))
du = du[date_rel_pair >= -5 & date_rel_pair <= 2]
du[, type := ifelse(date_rel_pair >= 0, '0 to 2', '-5 to -1')]
dsss = unique(du[anyEPY == FALSE], by = c('nestID', 'type'))
dsss = dsss[, .N, by = type]

dsss_epy = unique(du[anyEPY == TRUE], by = c('nestID', 'type'))
dsss_epy = dsss_epy[, .N, by = type]

# merge 
dsss = merge(dsss, dsss_epy[, .(N_epy = N, type)], by = 'type', all.x = TRUE)
dsss[, N_epy_label := paste0(N, '/', N_epy)]

# p values
dsp = data.table(type = c( '-5 to -1', '0 to 2'),
                 p_value = c('p = 0.13', 'p = 0.72'))

p2 =
ggplot() +
  geom_hline(yintercept = 0.5, color = 'black', linetype = 'dashed') +
  geom_point(data = e, aes(type, fit, group = interaction(anyEPY, type), color = anyEPY), 
             position = position_dodge(width = 0.5)) +
  geom_linerange(data = e, aes(x = type, ymin = upper, ymax = lower, color = anyEPY), size = 0.3, 
                 position = position_dodge(width = 0.5)) +
  scale_color_manual(values = c(col1, col2), name = '', 
                     labels = c('No EPP', 'EPP'), drop = FALSE) +
  geom_text(data = dsss, aes(type, Inf, label = N_epy_label), vjust = 1, size = sample_size_label) +
  geom_text(data = dsp, aes(type, c(0.3, 0.35), label = p_value), vjust = 1, size = sample_size_label) +
  scale_y_continuous(limits = c(-0.01, 1.01), breaks = seq(0, 1, 0.1),
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0.05))) +
  theme_classic(base_size = 10) +
  theme(legend.position = 'none', legend.background = element_blank(), 
        plot.margin = unit(c(2, 2, 0, 2), 'pt'), axis.title.x = element_blank()) +
  ylab('Proportion female moves away') +
  xlab('Day relative to clutch initiation (= 0)')

p2

# merge plots
library(grid)
library(gridExtra)
## 
## Attache Paket: 'gridExtra'
## Das folgende Objekt ist maskiert 'package:dplyr':
## 
##     combine
p <- p1 + p2 + 
  plot_layout(ncol = 2) +
  plot_annotation(tag_levels = 'a')

gt = patchworkGrob(p)
g = arrangeGrob(gt, bottom = textGrob('          Day relative to clutch initiation (= 0)', gp = gpar(fontsize = 10)))


# ggsave('./OUTPUTS/FIGURES/male_female_together_female_moving_epy.tiff', plot = g,  width = 89, height = 89, 
#        units = c('mm'), dpi = 'print')

Mate guarding intensity of polyandrous females

# Proportion of time together breeders
dps = dp[interaction == TRUE, .(N_int = .N), by = .(pairID, nestID, date_)]
du = unique(dp, by = c('pairID', 'nestID', 'date_'))
du = merge(du, dps, by = c('pairID', 'nestID', 'date_'), all.x = TRUE)
du[is.na(N_int), N_int := 0]
du[, int_prop := N_int / N]

# how many nests with polyandrous first clutch 
du[f_polyandrous_first == TRUE, .N, by = .(nestID)]
##     nestID  N
## 1: R211_19  8
## 2: R207_19 29
## 3: R405_19 13
## 4: R901_19  2
du[, f_polyandrous_first_plot := ifelse(f_polyandrous_first == TRUE, '1st mate (polyandrous)', 'Other')]

# point sizes range
du[, .(min(N), max(N))]
##    V1  V2
## 1:  1 142
# polyandrous females single plots

p1 = 
  ggplot() +
  geom_rect(aes(xmin = as.Date('2019-06-11'), xmax = as.Date('2019-06-14'), ymin = -0.07, ymax = 1.07), 
            fill = egg_laying_color) +
  geom_rect(aes(xmin = as.Date('2019-06-20'), xmax = as.Date('2019-06-23'), ymin = -0.07, ymax = 1.07), 
            fill = egg_laying_color) +
  geom_path(data = du[ID2 == 273145121], aes(date_, int_prop, group = nestID, 
                                             color = f_polyandrous_first_plot), linewidth = 1) +
  scale_color_manual(values = c(col1, col2), name = '',
                     labels = c(bquote("1"^st~ mate), bquote("2"^nd~ mate))) +
  geom_point(data = du[ID2 == 273145121], aes(date_, int_prop, color = f_polyandrous_first_plot, size = N)) +
  scale_size_area(max_size = 4, breaks=c(10, 50, 100)) +
  scale_y_continuous(limits = c(-0.07, 1.07), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0))) +
  scale_x_date(date_breaks = '2 day', date_labels = '%d',  #  %b to add month
               limits = c(as.Date('2019-06-11'), as.Date('2019-07-01')), guide = "axis_minor" ) +
  theme_classic(base_size = 10) +
  theme(legend.position = c(0.9, 0.88), legend.background = element_blank(), plot.margin = margin_, 
        legend.spacing.y = unit(-0.2, "cm"), legend.title = element_blank(), ggh4x.axis.ticks.length.minor = rel(1)) +
  guides(size = "none") +
  ylab('') +
  xlab('')

p1
## Warning: Removed 15 rows containing missing values (`geom_path()`).
## Warning: Removed 15 rows containing missing values (`geom_point()`).

p2 = 
  ggplot() +
  geom_rect(aes(xmin = as.Date('2019-06-09'), xmax = as.Date('2019-06-12'), ymin = -0.07, ymax = 1.07), 
            fill = egg_laying_color) +
  geom_rect(aes(xmin = as.Date('2019-06-18'), xmax = as.Date('2019-06-21'), ymin = -0.07, ymax = 1.07), 
            fill = egg_laying_color) +
  geom_path(data = du[ID2 == 270170935 & nestID == 'R405_19' | nestID == 'R406_19'], 
            aes(date_, int_prop, group = nestID, color = f_polyandrous_first_plot), linewidth = 1) +
  scale_color_manual(values = c(col1, col2), name = '',
                     labels = c('1st mate', '2nd mate')) +
  geom_point(data = du[ID2 == 270170935 & nestID == 'R405_19' | nestID == 'R406_19'], 
             aes(date_, int_prop, color = f_polyandrous_first_plot, size = N)) +
  scale_size_area(max_size = 4, breaks=c(10, 50, 100)) +
  scale_y_continuous(limits = c(-0.07, 1.07), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0))) +
  scale_x_date(date_breaks = '2 day', date_labels = '%d',guide = "axis_minor") +
  theme_classic(base_size = 10) +
  theme(legend.position = 'none', legend.background = element_blank(), plot.margin = margin_) +
  ylab('') +
  xlab('')

p2

p3 = 
  ggplot() +
  geom_rect(aes(xmin = as.Date('2019-06-11'), xmax = as.Date('2019-06-13'), ymin = -0.07, ymax = 1.07), 
            fill = egg_laying_color) +
  geom_rect(aes(xmin = as.Date('2019-06-15'), xmax = as.Date('2019-06-16'), ymin = -0.07, ymax = 1.07), 
            fill = egg_laying_color) +
  geom_path(data = du[ID2 == 273145036], 
            aes(date_, int_prop, group = nestID, color = f_polyandrous_first_plot), linewidth = 1) +
  scale_color_manual(values = c(col1, col2), name = '',
                     labels = c('1st mate', '2nd mate')) +
  geom_point(data = du[ID2 == 273145036], aes(date_, int_prop, color = f_polyandrous_first_plot, size = N)) +
  scale_size_area(max_size = 4, breaks=c(10, 50, 100)) +
  scale_y_continuous(limits = c(-0.07, 1.07), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0))) +
  scale_x_date(date_breaks = '2 day', date_labels = '%d', guide = "axis_minor") +
  theme_classic(base_size = 10) +
  theme(legend.position = 'none', legend.background = element_blank(), plot.margin = margin_) +
  ylab('') +
  xlab('')
p3

p4 = 
  ggplot() +
  geom_rect(aes(xmin = as.Date('2019-06-06'), xmax = as.Date('2019-06-09'), ymin = -0.07, ymax = 1.07), 
            fill = egg_laying_color) +
  geom_rect(aes(xmin = as.Date('2019-06-15'), xmax = as.Date('2019-06-18'), ymin = -0.07, ymax = 1.07), 
            fill = egg_laying_color) +
  geom_path(data = du[ID2 == 273145109], 
            aes(date_, int_prop, group = nestID, color = f_polyandrous_first_plot), linewidth = 1) +
  scale_color_manual(values = c(col1, col2), name = '',
                     labels = c('1st mate', '2nd mate')) +
  geom_point(data = du[ID2 == 273145109], aes(date_, int_prop, color = f_polyandrous_first_plot, size = N)) +
  scale_size_area(max_size = 4, breaks=c(10, 50, 100)) +
  scale_y_continuous(limits = c(-0.07, 1.07), breaks = seq(0, 1, 0.1), 
                     labels = c('0.0', '', '0.2', '', '0.4', '', '0.6', '', '0.8', '', '1.0'),
                     expand = expansion(add = c(0, 0))) +
  scale_x_date(date_breaks = '2 day', date_labels = '%d', guide = "axis_minor") +
  theme_classic(base_size = 10) +
  theme(legend.position = 'none', legend.background = element_blank(), plot.margin = margin_) +
  ylab('Proportion of time together') +
  xlab('Date (June)')

p4

# merge plots
p1 + p2 + p3 + p4 +
  plot_layout(nrow = 4, ncol = 1) +
  plot_annotation(tag_levels = 'a')
## Warning: Removed 15 rows containing missing values (`geom_path()`).
## Removed 15 rows containing missing values (`geom_point()`).

# ggsave('./OUTPUTS/FIGURES/MG_over_season_polyandrous_4_females.tiff', plot = last_plot(),  width = 129, 
#        height = 200, units = c('mm'), dpi = 'print')



# save word file
# print(ESM, target = "./OUTPUTS/ESM/ESM_REPH_PAIRS.docx")

Behavioural observations

# Data
d = fread('./DATA/OBSERVATIONS.txt', sep = '\t', header = TRUE) %>% data.table

### Following flights

# Total observations
unique(d, by = 'obs_id') |> nrow()
## [1] 5524
# How many ID at observations?
d[, N_ind_int := .N, by = obs_id]

# How many observations with at least two IDs and a flight?
d[, any_flights := any(flight %like% 'F'), by = obs_id]

# Total with at least 2 IDs
unique(d[N_ind_int > 1], by = 'obs_id') |> nrow()
## [1] 2876
# Total with a flight initiator scored
d[, any_F1 := any(flight == 'F1'), by = obs_id]
d[, any_F0 := any(flight == 'F0'), by = obs_id]

# subset relevant data
ds = d[!is.na(sex) & N_ind_int > 1 & any_F1 == TRUE]

# Flight imitator scored
ds[flight == 'F1'] |> nrow()
## [1] 153
# Female initiating
ds[sex == 'F' & flight == 'F1'] |> nrow()
## [1] 88
# Any male following?
ds[, any_male_F0 := any(flight == 'F0' & sex == 'M'), by = obs_id]
unique(ds[N_ind_int > 1 & sex == 'F' & flight == 'F1' & any_male_F0 == TRUE], by = 'obs_id') |> nrow()
## [1] 72
# Male initiating
ds[sex == 'M' & flight == 'F1'] |> nrow()
## [1] 65
# Any female following?
ds[, any_female_F0 := any(flight == 'F0' & sex == 'F'), by = obs_id]
unique(ds[N_ind_int > 1 & sex == 'M' & flight == 'F1' & any_female_F0 == TRUE], by = 'obs_id') |> nrow()
## [1] 49
# Summary  
round(88/153 * 100, 0) # percent of females initiating when scored
## [1] 58
round(72/88 * 100, 0)  # percent male following 
## [1] 82
round(65/153 * 100, 0) # percent of males initiating when scored
## [1] 42
round(49/65 * 100, 0)  # percent female following 
## [1] 75
### Aggressive interactions 

# How many observations with at least two IDs and a aggression?
d[, any_aggres := any(!is.na(aggres)), by = obs_id]

# Total with at least 2 IDs
unique(d[N_ind_int > 1], by = 'obs_id') |> nrow()
## [1] 2876
# Total with a aggression
unique(d[N_ind_int > 1 & any_aggres == TRUE], by = 'obs_id') |> nrow()
## [1] 148
148/2876 * 100
## [1] 5.146036
unique(d[N_ind_int > 2 & any_aggres == TRUE], by = 'obs_id') |> nrow()
## [1] 72
72/2876 * 100
## [1] 2.503477
# Total with a aggression initiator scored
d[, any_1_obs_id := any(aggres %like% '1'), by = obs_id]
d[, any_0_obs_id := any(aggres %like% '0'), by = obs_id]

# for each aggression
d[, any_1 := any(aggres %like% '1'), by = 1:nrow(d)]
d[, any_0 := any(aggres %like% '0'), by = 1:nrow(d)]

# both sexes aggressive in one observation
d[, pair_1 := any(any_1 == TRUE & sex == 'F') & any(any_1 == TRUE & sex == 'M'), by = obs_id]

# Which sex was target?
d[, any_female_0 := any(aggres %like% '0' & sex == 'F'), by = obs_id]
d[, any_male_0 := any(aggres %like% '0' & sex == 'M'), by = obs_id]

# subset relevant data
ds = d[!is.na(sex) & N_ind_int > 1 & any_1_obs_id == TRUE]

# Aggression imitator scored
ds[any_1 == TRUE] |> nrow()
## [1] 144
# Male initiating
ds[sex == 'M' & any_1 == TRUE] |> nrow()
## [1] 62
# Female initiating
ds[sex == 'F' & any_1 == TRUE] |> nrow()
## [1] 82
# Pair initiating
ds[pair_1 == TRUE & any_1 == TRUE] |> nrow()
## [1] 9
# Direction of aggression
ds[sex == 'M' & any_1 == TRUE & any_female_0 == TRUE] |> nrow()
## [1] 40
ds[sex == 'M' & any_1 == TRUE & any_male_0 == TRUE] |> nrow()
## [1] 25
ds[sex == 'F' & any_1 == TRUE & any_female_0 == TRUE] |> nrow()
## [1] 46
ds[sex == 'F' & any_1 == TRUE & any_male_0 == TRUE] |> nrow()
## [1] 34
# Summary 
round(62/144 * 100, 0) # male initiated
## [1] 43
round(40/61 * 100, 0) # percent of male aggression against females
## [1] 66
round(25/61 * 100, 0) # percent of male aggression against males
## [1] 41
round(82/144 * 100, 0) # female initiated
## [1] 57
round(46/80 * 100, 0) # percent of female aggression against females
## [1] 57
round(34/80 * 100, 0) # percent of female aggression against males
## [1] 42
round(9/144 * 100, 0) # pair initiated
## [1] 6
### Copulations

# subset data
ds = d[!is.na(cop)]

# initiators
ds[, initiator := like(cop, '1')]
ds[, .(cop, initiator)]
##      cop initiator
##   1:  A0     FALSE
##   2:  A1      TRUE
##   3:  A0     FALSE
##   4:  A1      TRUE
##   5:  S1      TRUE
##  ---              
## 577:   S     FALSE
## 578:   A     FALSE
## 579:   A     FALSE
## 580:  A0     FALSE
## 581:  A1      TRUE
# N observations 
ds |> nrow()
## [1] 581
ds[initiator == TRUE] |> nrow()
## [1] 113
ds[sex == 'M' & initiator == TRUE] |> nrow()
## [1] 82
ds[sex == 'F' & initiator == TRUE] |> nrow()
## [1] 31
# Summary
round(82/113 * 100, 0) # Male initiated copulation
## [1] 73
round(31/113 * 100, 0) # Female initiated copulation
## [1] 27
# version information
sessionInfo()
## R version 4.2.2 (2022-10-31 ucrt)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 19045)
## 
## Matrix products: default
## 
## locale:
## [1] LC_COLLATE=German_Germany.utf8  LC_CTYPE=German_Germany.utf8    LC_MONETARY=German_Germany.utf8 LC_NUMERIC=C                    LC_TIME=German_Germany.utf8    
## 
## attached base packages:
## [1] grid      stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] gridExtra_2.3      DHARMa_0.4.6       ggh4x_0.2.3        performance_0.10.2 dplyr_1.1.0        officer_0.5.2      flextable_0.8.5    broomExtra_5.0.0  
##  [9] effects_4.2-2      carData_3.0-5      glmmTMB_1.1.5      activity_1.3.2     patchwork_1.1.2    doFuture_0.12.2    future_1.31.0      ggnewscale_0.4.8  
## [17] stringr_1.5.0      knitr_1.42         sf_1.0-13          foreach_1.5.2      auksRuak_0.1.0     viridis_0.6.2      viridisLite_0.4.2  ggplot2_3.4.3     
## [25] magrittr_2.0.3     data.table_1.14.8 
## 
## loaded via a namespace (and not attached):
##   [1] backports_1.4.1     uuid_1.1-0          systemfonts_1.0.4   plyr_1.8.8          TMB_1.9.2           splines_4.2.2       listenv_0.9.0       gap.datasets_0.0.5 
##   [9] TH.data_1.1-2       digest_0.6.31       htmltools_0.5.4     fansi_1.0.4         memoise_2.0.1       doParallel_1.0.17   globals_0.16.2      sandwich_3.0-2     
##  [17] askpass_1.1         timechange_0.2.0    gfonts_0.2.0        colorspace_2.1-0    mitools_2.4         xfun_0.40           crayon_1.5.2        jsonlite_1.8.4     
##  [25] lme4_1.1-31         survival_3.4-0      zoo_1.8-11          iterators_1.0.14    glue_1.6.2          gtable_0.3.4        emmeans_1.8.4-1     scales_1.2.1       
##  [33] mvtnorm_1.1-3       DBI_1.1.3           Rcpp_1.0.10         xtable_1.8-4        units_0.8-2         proxy_0.4-27        survey_4.1-1        datawizard_0.6.5   
##  [41] ellipsis_0.3.2      farver_2.1.1        pkgconfig_2.0.3     qgam_1.3.4          sass_0.4.5          nnet_7.3-18         utf8_1.2.3          janitor_2.1.0      
##  [49] crul_1.3            labeling_0.4.3      tidyselect_1.2.0    rlang_1.1.1         ggspatial_1.1.7     later_1.3.0         munsell_0.5.0       tools_4.2.2        
##  [57] cachem_1.0.6        cli_3.6.0           generics_0.1.3      broom_1.0.3         evaluate_0.20       fastmap_1.1.0       yaml_2.3.7          zip_2.2.2          
##  [65] purrr_1.0.1         nlme_3.1-160        mime_0.12           xml2_1.3.3          gap_1.5-1           compiler_4.2.2      rstudioapi_0.14     curl_5.0.2         
##  [73] e1071_1.7-13        tibble_3.1.8        bslib_0.4.2         stringi_1.7.12      highr_0.10          parameters_0.20.2   forcats_1.0.0       gdtools_0.3.0      
##  [81] lattice_0.20-45     Matrix_1.5-1        classInt_0.4-9      nloptr_2.0.3        vctrs_0.5.2         furrr_0.3.1         pillar_1.9.0        lifecycle_1.0.3    
##  [89] jquerylib_0.1.4     sfext_0.1.0         estimability_1.4.1  insight_0.19.0      filenamr_0.1.0      httpuv_1.6.8        R6_2.5.1            promises_1.2.0.1   
##  [97] KernSmooth_2.23-20  parallelly_1.34.0   cliExtras_0.1.0     codetools_0.2-18    boot_1.3-28         MASS_7.3-58.1       openssl_2.0.5       rprojroot_2.0.3    
## [105] withr_2.5.0         httpcode_0.3.0      broom.mixed_0.2.9.4 multcomp_1.4-25     mgcv_1.8-41         bayestestR_0.13.0   parallel_4.2.2      tidyr_1.3.0        
## [113] coda_0.19-4         class_7.3-20        minqa_1.2.5         rmarkdown_2.20      snakecase_0.11.0    numDeriv_2016.8-1.1 shiny_1.7.4         lubridate_1.9.2    
## [121] base64enc_0.1-3