Largeurs et angles

Author

C. Champod & J. Levasseur

Largeurs des traces

Importation des données

#Required libraries
library(readxl)
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.1
✔ purrr     1.0.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggpubr)
library(emmeans)
Welcome to emmeans.
Caution: You lose important information if you filter this package's results.
See '? untidy'
library(gtools)

#Largeur
Largeur_HD <- read_excel("Mesures taille et angle.xlsx", sheet = "Taille_HD")
Largeur_LT <- read_excel("Mesures taille et angle.xlsx", sheet = "Taille_LT")
Largeur_D <- read_excel("Mesures taille et angle.xlsx", sheet = "Taille_D")

#Small function to transform data in long format
MakeLong <- function(data, nDigitClef = 3){
  df_long <- data %>%
    rownames_to_column(var = "Row") %>%
    pivot_longer(-Row, names_to = "Column", values_to = "Largeur") %>%
    mutate(Clef = as.factor(str_sub(Column, 1, nDigitClef))) %>%
    mutate(Pince = as.factor(str_sub(Column, -1))) %>%
    mutate(Marque = as.factor(substr(Clef, 1, nchar(as.character(Clef)) - (nDigitClef-2)))) %>%
    select(Marque, Clef, Pince, Largeur) %>%
    drop_na() #remove NA in the table
  return(df_long)
}

Largeur_HD_long <- MakeLong(Largeur_HD, nDigitClef = 4)
Largeur_LT_long <- MakeLong(Largeur_LT)
Largeur_D_long <- MakeLong(Largeur_D, nDigitClef = 2) %>% 
  mutate (Marque = substr(Marque, 1, nchar(as.character(Marque)) - 1))

#Merge all tools
Largeur <- rbind(Largeur_HD_long,
                 Largeur_LT_long,
                 Largeur_D_long) %>%
  mutate(Clef = str_replace_all(Clef, "_", "")) #to remove "_" in Clef from HD

#debug(MakeLong)

Tests statistiques sur les largeurs

#Function to compute pairwise test on dataframe
GetpairWiseTest <- function(data){
  # Fit a linear model
  model <- lm(Largeur ~ Clef, data = data)

  # Perform pairwise comparisons
  pairwise_results <- emmeans(model, pairwise ~ Clef)

  # Convert the results to a dataframe for ggplot2
  # Extract pairwise comparison results and adjust the format
  pairwise_df <- as.data.frame(pairwise_results$contrasts)
  pairwise_df <- pairwise_df %>%
    mutate(group1 = sub(" - .*", "", contrast),
           group2 = sub(".* - ", "", contrast),
           p.adj.signif = ifelse(p.value < 0.001, "***",
                               ifelse(p.value < 0.01, "**",
                                      ifelse(p.value < 0.05, "*", "ns"))))

  # Determine unique significance levels and y-positions
  signif_levels <- unique(pairwise_df$p.adj.signif)
  y_positions <- seq(from = max(data$Largeur) + 0.2, by = 0.2, length.out = length(signif_levels))
  names(y_positions) <- signif_levels

  # Add y-position to pairwise_df based on significance level
  pairwise_df <- pairwise_df %>%
    mutate(y.position = y_positions[p.adj.signif])
  return(pairwise_df)
}

#To get the table of test results for all comparisons
PairWiseTests <- GetpairWiseTest(Largeur)
#PairWiseTests

Plot des largeurs

#Function to plot boxplots with or without results from test
# Note that you can have custom colors if needed

PlotBox <- function(data, Plot_significance = TRUE, custom_colors){
  data$Clef <- factor(data$Clef, mixedsort(levels(as.factor(data$Clef)))) #resort the levels
  p <- ggplot(data, aes(x = Clef, y = Largeur)) +
  geom_boxplot() +
  geom_jitter(width = 0.2, aes(color = Marque, shape = Pince), alpha = 0.6, size = 3) +
  scale_color_manual(values = custom_colors) +
  labs(title = "Largeurs des traces selon les clefs",
       x = "Clef à molette",
       y = "Largeur des traces [mm]") +
  theme_minimal()
  if(Plot_significance == TRUE){p <- p + 
    stat_pvalue_manual(GetpairWiseTest(data), 
                       label = "p.adj.signif", 
                       tip.length = 0.03)}
 return(p)
}

#plot all results without Significance results

p1 <- PlotBox(Largeur, Plot_significance = FALSE, 
        custom_colors = c("HD" = "indianred2", "LT" = "skyblue3", "D" = "seagreen3"))
p1

#plot all results with Significance results
p2 <- PlotBox(Largeur %>% filter(Marque == "HD"), 
        custom_colors = c("HD" = "indianred2"))
p2

p3 <- PlotBox(Largeur %>% filter(Marque == "LT" | Marque == "D"), 
        custom_colors = c("LT" = "skyblue3", "D" = "seagreen3"))
p3

#Save plots in PDF

ggsave("plot1.pdf", plot = p1, device = "pdf", width = 15, height = 10)
ggsave("plot2.pdf", plot = p2, device = "pdf", width = 15, height = 10)
ggsave("plot3.pdf", plot = p3, device = "pdf", width = 15, height = 10)

Angles des extrêmités des traces

Importation des données relatives aux angles

#Largeur
Angles_HD <- read_excel("Mesures taille et angle.xlsx", sheet = "Angle_HD")
Angles_LT <- read_excel("Mesures taille et angle.xlsx", sheet = "Angle_LT")
Angles_D <- read_excel("Mesures taille et angle.xlsx", sheet = "Angle_D")

Angles_HD_long <- MakeLong(Angles_HD, nDigitClef = 4)
Angles_LT_long <- MakeLong(Angles_LT)
Angles_D_long <- MakeLong(Angles_D, nDigitClef = 2) %>% 
  mutate (Marque = substr(Marque, 1, nchar(as.character(Marque)) - 1))

#Merge all tools and adapt dataframe
Angles <- rbind(Angles_HD_long,
               Angles_LT_long,
               Angles_D_long) %>%
  mutate(Angle = Largeur) %>%
  mutate(haut_bas = Pince) %>%
  mutate(Clef = str_replace_all(Clef, "_", "")) %>% #to remove "_" in Clef from HD
  mutate(Clef_H_B = paste0(Clef, haut_bas)) %>%
  select(!Largeur) %>% #not needed any more
  select(!Pince)

Tests statistiques sur les angles

#Function to compute pairwise test on dataframe
GetpairWiseTest_a <- function(data){
  # Fit a linear model
  model <- lm(Angle ~ Clef_H_B, data = data)

  # Perform pairwise comparisons
  pairwise_results <- emmeans(model, pairwise ~ Clef_H_B)

  # Convert the results to a dataframe for ggplot2
  # Extract pairwise comparison results and adjust the format
  pairwise_df <- as.data.frame(pairwise_results$contrasts)
  pairwise_df <- pairwise_df %>%
    mutate(group1 = sub(" - .*", "", contrast),
           group2 = sub(".* - ", "", contrast),
           p.adj.signif = ifelse(p.value < 0.001, "***",
                               ifelse(p.value < 0.01, "**",
                                      ifelse(p.value < 0.05, "*", "ns"))))

  # Determine unique significance levels and y-positions
  signif_levels <- unique(pairwise_df$p.adj.signif)
  y_positions <- seq(from = max(data$Angle) + 0.2, by = 2, length.out = length(signif_levels))
  names(y_positions) <- signif_levels

  # Add y-position to pairwise_df based on significance level
  pairwise_df <- pairwise_df %>%
    mutate(y.position = y_positions[p.adj.signif])
  return(pairwise_df)
}

#To get the table of test results for all comparisons
PairWiseTests_a <- GetpairWiseTest_a(Angles)
#PairWiseTests_a

Plot des angles

#plot all angles 

PlotBox_a <- function(data, Plot_significance = TRUE, custom_colors){
  data$Clef <- factor(data$Clef, mixedsort(levels(as.factor(data$Clef)))) #resort the levels
  p <- ggplot(data, aes(x = Clef_H_B, y = Angle)) +
  geom_boxplot() +
  geom_jitter(width = 0.2, aes(color = Marque, shape = haut_bas), alpha = 0.6, size = 3) +
  scale_color_manual(values = custom_colors) +
  labs(title = "Angles des traces selon les clefs",
       x = "Clef à molette",
       y = "Angles des extrêmités des traces [degrés]") +
  theme_minimal()
  if(Plot_significance == TRUE){p <- p + 
    stat_pvalue_manual(GetpairWiseTest_a(data), 
                       label = "p.adj.signif", 
                       tip.length = 0.03)}
 return(p)
}

#plot all results without Significance results
p1_a <- PlotBox_a(Angles, Plot_significance = FALSE, 
        custom_colors = c("HD" = "indianred2", "LT" = "skyblue3", "D" = "seagreen3"))
p1_a

#plot all results with Significance results
p2_a <- PlotBox_a(Angles %>% filter(Marque == "HD"), 
        custom_colors = c("HD" = "indianred2"))
p2_a

p3_a <- PlotBox_a(Angles %>% filter(Marque == "LT" | Marque == "D"), 
        custom_colors = c("LT" = "skyblue3", "D" = "seagreen3"))
p3_a

#Save plots in PDF
ggsave("plot1_a.pdf", plot = p1_a, device = "pdf", width = 20, height = 15)
ggsave("plot2_a.pdf", plot = p2_a, device = "pdf", width = 20, height = 15)
ggsave("plot3_a.pdf", plot = p3_a, device = "pdf", width = 15, height = 10)