# Loading the required packages
library(readxl) # Package for reading Excel files
library(dplyr) # Package for data manipulation
library(summarytools) # Package for descriptive statistics
library(gtsummary) # Package for summarizing data
library(corrplot) # Package for correlation plots
library(Hmisc) # Package for correlation tests
library(DHARMa) # Package for model diagnostics
library(performance) # Package for checking multicollinearity
library(sjPlot) # Package for visualizing models
library(lme4) # Package for fitting GLMMs
library(report) # Package for generating reports

# Loading the data from an Excel file
data1 <- read_excel("dataset_manuscript.xlsx")

# Filtering out unnecessary variables
data2 <- data1[, -c(4,6)]

# Filtering out incomplete cases for the variables of interest
data3 <- data2[complete.cases(data2),]

# Converting selected variables to factors
data3[, c(1:3, 5, 16, 17)] <- data3[, c(1:3, 5, 16, 17)] %>%
  mutate_all(as.factor)

# Reordering factor levels for better interpretation
data3$ifi_cat <- factor(data3$ifi_cat, levels = c("negative",
                                                  "low positive",
                                                  "medium positive",
                                                  "high positive"))

# Generating a table of frequencies for the 'treatment' variable
table(data3$treatment)

# Shapiro-Wilk tests to evaluate the normality of continuous variables
shapiro.test(data3$age) # not normal
shapiro.test(data3$pt) # not normal
shapiro.test(data3$alb) # not normal
shapiro.test(data3$alfa1) # not normal
shapiro.test(data3$alfa2) # not normal
shapiro.test(data3$beta) # not normal
shapiro.test(data3$gamma) # not normal
shapiro.test(data3$ag) # not normal
shapiro.test(data3$gb) # not normal
shapiro.test(data3$htc) # not normal
shapiro.test(data3$platelets) # not normal
shapiro.test(data3$total_score) # not normal

# Profile of dogs by sex
data3 %>%
  select(subject, sex, breed) %>%
  unique() %>%
  freq(sex)

# Profile of dogs by breed
data3 %>%
  select(subject, sex, breed) %>%
  unique() %>%
  freq(breed)

# Profile of dogs by age
data3 %>%
  select(age) %>%
  descr() 

# Descriptive statistics
data3 %>%
  select(c(6:15,18,5,16:17)) %>%
  tbl_summary()

# Number of visits per subject
visits <- as.vector(table(data3$subject))
descr(visits)

# Follow-up time calculation
follow_up_time <- data3 %>%
  group_by(subject) %>%
  summarise(follow_up_time = max(age) - min(age)) %>%
  mutate(follow_up_days = follow_up_time * 365.25)

descr(follow_up_time$follow_up_days)

# Clinical signs frequency
sum(table(data3$total_score[which(data3$total_score!=0)]))
sum(table(data1$total_score[which(data1$total_score!=0)]))/sum(table(data1$total_score))

# Function to calculate counts and percentages for values below, within, and above a reference interval
calculate_frequency <- function(variable, reference_interval) {
  # Calculate counts
  below_count <- sum(variable < reference_interval[1])
  within_count <- sum(variable >= reference_interval[1] & variable <= reference_interval[2])
  above_count <- sum(variable > reference_interval[2])
  
  # Total count
  total_count <- length(variable)
  
  # Calculate percentages
  below_percentage <- below_count / total_count * 100
  within_percentage <- within_count / total_count * 100
  above_percentage <- above_count / total_count * 100
  
  # Return the table with the results
  return(data.frame(Category = c("Low", "Normal", "High"),
                    Count = c(below_count, within_count, above_count),
                    Percentage = c(below_percentage, within_percentage, above_percentage)))
}

# Calculating frequencies for selected variables
calculate_frequency(data3$pt, c(5.8,7.5))
calculate_frequency(data3$alb, c(2.7,4.6))
calculate_frequency(data3$alfa1, c(0.2,0.5))
calculate_frequency(data3$alfa2, c(0.3,1.1))
calculate_frequency(data3$beta, c(1.3,2.7))
calculate_frequency(data3$gamma, c(0.5,1.2))
calculate_frequency(data3$ag, c(0.7,1.9))
calculate_frequency(data3$htc, c(35,55))
calculate_frequency(data3$gb, c(6,17))
calculate_frequency(data3$platelets, c(200,500))

# Correlation plot
matriz_cor_spearman <- cor(data3[, c(4, 6:15, 18)],
                           use = "complete.obs",
                           method = "spearman")

p_values <- cor.mtest(matriz_cor_spearman, 
                      method = "spearman")$p

corrplot(
  matriz_cor_spearman,
  method = "circle",
  type = 'lower',
  insig = 'blank',
  addCoef.col = "black",
  number.cex = 0.8,
  order = 'hclust',
  diag = FALSE,
  tl.col = "black",
  tl.srt = 45,
  p.mat = p_values,   
  sig.level = 0.05   
)

# Association plot
corrplot::corrplot(
  DescTools::PairApply(data3[, c(5,16,17)],
                       DescTools::CramerV),
  method = "circle",
  type = 'lower',
  insig = 'blank',
  addCoef.col = "black",
  number.cex = 0.8,
  order = 'hclust',
  diag = FALSE,
  tl.col = "black",
  tl.srt = 45,
  sig.level = 0.05
)

# Model 1
# Considering the ag variable
# ag = alb / (alfa1 + alfa2 + beta + gamma)

data_model1 <- data3[,-c(7:11)]

# Transforming ag to interpret the increase of 0.1
data_model1$ag <- data_model1$ag * 10

# Fitting GLMMs
m1_model1 <- glmer(
  treatment ~ sex + breed +
    age + ifi_cat + ag +
    htc + gb + platelets +
    total_score +
    (1 | subject),
  data = data_model1,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m1_model1) # AIC: 195.6

# Model selection
m2_model1 <- glmer(
  treatment ~ sex + breed +
    age + ifi_cat + ag +
    htc + gb +
    total_score +
    (1 | subject),
  data = data_model1,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m2_model1) # AIC: 193.8

# Removing sex
m3_model1 <- glmer(
  treatment ~ breed +
    age + ifi_cat + ag +
    htc + gb +
    total_score +
    (1 | subject),
  data = data_model1,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m3_model1) # AIC: 192

# Removing breed
m4_model1 <- glmer(
  treatment ~
    age + ifi_cat + ag +
    htc + gb +
    total_score +
    (1 | subject),
  data = data_model1,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m4_model1) # AIC: 190.2

# Removing gb
m5_model1 <- glmer(
  treatment ~
    age + ifi_cat + ag +
    htc +
    total_score +
    (1 | subject),
  data = data_model1,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m5_model1) # AIC: 188.9

# Removing age
m6_model1 <- glmer(
  treatment ~
    ifi_cat + ag +
    htc +
    total_score +
    (1 | subject),
  data = data_model1,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m6_model1) # AIC: 188.4 

# Removing htc
m7_model1 <- glmer(
  treatment ~
    ifi_cat + ag +
    total_score +
    (1 | subject),
  data = data_model1,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m7_model1) # AIC: 188.4 

# Removing if_cat
m8_model1 <- glmer(
  treatment ~
    ag +
    total_score +
    (1 | subject),
  data = data_model1,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m8_model1) # AIC: 188.7 

# Comparing the models
anova(m8_model1,
      m7_model1,
      m6_model1,
      m5_model1, 
      m4_model1, 
      m3_model1, 
      m2_model1, 
      m1_model1)

# The m8_model1 provides the best trade-off between model fit and complexity
# When comparing models using the chi-squared test, none of the models show a significant improvement over the previous model at the 0.05 significance level, as all p-values are above this threshold
# It's important to consider both AIC/BIC and the chi-squared test when selecting the final model. While AIC/BIC provide a measure of fit, the chi-squared test assesses whether additional parameters significantly improve the model

# Model diagnostics
isSingular(m8_model1) # The result FALSE suggests that the model is not singular, which is desirable as it indicates that the model estimation has proceeded without encountering issues related to singularity
VarCorr(m8_model1) # A standard deviation value of 0.46072 suggests that there is variability in the intercepts among the different subjects, capturing the random effects associated with individual variability not explained by the fixed effects in the model
plotQQunif(m8_model1) # Normality
plotResiduals(m8_model1) # No significant problems detected
check_collinearity(m8_model1)

# Forest plot
sjPlot::plot_model(m8_model1, 
                   vline.color = "black",
                   show.values = TRUE, 
                   value.offset = .3,
                   title = "Model 1")

# Table Model 1
sjPlot::tab_model(m8_model1, 
                  p.style = "numeric", 
                  show.aic = T)

# Report Model 1
report(m8_model1)

#---------------------------------#
# Model 2
# Considering the ag variable
# ag = alb / (alfa1 + alfa2 + beta + gamma)

data_model2 <- data3[,-c(12)]

# Transforming alfa1, alfa2, beta, gamma to interpret the increase of 0.1
data_model2$alb <- data_model2$alb * 10
data_model2$alfa1 <- data_model2$alfa1 * 10
data_model2$alfa2 <- data_model2$alfa2 * 10
data_model2$beta <- data_model2$beta * 10
data_model2$gamma <- data_model2$gamma * 10

# Since pt has moderate correlation with gamma, let's remove pt from the analysis

# Fitting GLMMs
m1_model2 <- glmer(
  treatment ~ sex + breed +
    age + ifi_cat + alb +
    alfa1 + alfa2 + beta + gamma +
    htc + gb + platelets + total_score  +
    (1 | subject),
  data = data_model2,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m1_model2) # AIC: 204.2

# Removing sex
m2_model2 <- glmer(
  treatment ~ breed +
    age + ifi_cat + alb +
    alfa1 + alfa2 + beta + gamma +
    htc + gb + platelets + total_score +
    (1 | subject),
  data = data_model2,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m2_model2) # AIC: 202.4

# Removing platelets
m3_model2 <- glmer(
  treatment ~ breed +
    age + ifi_cat + alb +
    alfa1 + alfa2 + beta + gamma +
    htc + gb + total_score +
    (1 | subject),
  data = data_model2,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m3_model2) # AIC: 200.5

# Removing breed
m4_model2 <- glmer(
  treatment ~
    age + ifi_cat + alb +
    alfa1 + alfa2 + beta + gamma +
    htc + gb + total_score +
    (1 | subject),
  data = data_model2,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m4_model2) # AIC: 198.9

# Removing alfa1
m5_model2 <- glmer(
  treatment ~
    age + ifi_cat + alb +
    alfa2 + beta + gamma +
    htc + gb + total_score +
    (1 | subject),
  data = data_model2,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m5_model2) # AIC: 197.3

# Removing gb
m6_model2 <- glmer(
  treatment ~
    age + ifi_cat + alb +
    alfa2 + beta + gamma +
    htc + total_score +
    (1 | subject),
  data = data_model2,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m6_model2) # AIC: 195.8

# Removing alfa2
m7_model2 <- glmer(
  treatment ~
    age + ifi_cat + alb +
    beta + gamma +
    htc + total_score +
    (1 | subject),
  data = data_model2,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m7_model2) # AIC: 194.8

# Removing age
m8_model2 <- glmer(
  treatment ~
    ifi_cat + alb +
    beta + gamma +
    htc + total_score +
    (1 | subject),
  data = data_model2,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m8_model2) # AIC: 194.0

# Removing gamma
m9_model2 <- glmer(
  treatment ~
    ifi_cat + alb +
    beta +
    htc + total_score +
    (1 | subject),
  data = data_model2,
  family = binomial,
  control = glmerControl(optimizer = "bobyqa"),
  nAGQ = 0
)
summary(m9_model2) # AIC: 193.4

# Model evaluation
anova(
  m9_model2,
  m8_model2,
  m7_model2,
  m6_model2,
  m5_model2,
  m4_model2,
  m3_model2,
  m2_model2,
  m1_model2
)

# Diagnostic checks
isSingular(m9_model2) # The result FALSE suggests that the model is not singular, which is desirable as it indicates that the model estimation has proceeded without encountering issues related to singularity
VarCorr(m9_model2) # A standard deviation value of 0.39632 suggests that there is variability in the intercepts among the different subjects, capturing the random effects associated with individual variability not explained by the fixed effects in the model
plotQQunif(m9_model2) # Normality
plotResiduals(m9_model2) # No significant problems detected
check_collinearity(m9_model2)

# Forest plot
sjPlot::plot_model(m9_model2, 
                   vline.color = "black",
                   show.values = TRUE, 
                   value.offset = .3,
                   title = "Model 2")

# Table Model 2
sjPlot::tab_model(m9_model2, 
                  p.style = "numeric", 
                  show.aic = T)

# Report Model 2
report(m8_model2)
