
# Load required packages
library(tidyverse)
library(patchwork)
library(ggtext)

######################################################
###Transform ex-Table 2 in Figure 1
######################################################

# Create the data
df <- tibble::tribble(
  ~outcome, ~oq, ~p1,  ~p2,  ~p3,  ~p4,
  1, 1,  0.8,  4.5, 13.4, 15.2,
  1, 2,  1.2,  2.8,  3.4,  5.6,
  2, 1,  3.5, 11.3, 10.8, 18.7,
  2, 2,  3.1,  8.3, 15.6, 18.0,
  3, 1, 95.7, 84.2, 75.8, 66.0,
  3, 2, 95.7, 89.0, 81.0, 76.4,
  4, 1,   NA, 21.9, 80.6, 60.6,
  4, 2,   NA, 17.7, 80.3, 63.2
)

#to get proper superscripts
superscript_unicode <- function(x) {
  map_chr(x, ~ {
    str_replace_all(.x, c(
      "a" = "\u1d43",  # ᵃ
      "b" = "\u1d47",  # ᵇ
      "c" = "\u1d9c",  # ᶜ
      "d" = "\u1d48"   # ᵈ
    ))
  })
}

# Create 'control' variable
df <- df %>%
  mutate(control = if_else(outcome != 4, p1, p2),
         id = row_number())

# Reshape data to long format
df_long <- df %>%
  pivot_longer(cols = starts_with("p"), names_to = "group", values_to = "p") %>%
  mutate(group = case_when(
    group == "p1" ~ 1,
    group == "p2" ~ 2,
    group == "p3" ~ 3,
    group == "p4" ~ 4
  ))

# Factor labels
df_long <- df_long %>%
  mutate(
    outcome = factor(outcome, levels = 1:4,
                     labels = c("Break-off (%)", "Item non-response (%)", "Responses (%)", "Responses using voice (%)")),
    oq = factor(oq, levels = 1:2, labels = c("OQ1", "OQ2")),
    group = factor(group, levels = 1:4,
                   labels = c("Control", "Choice", "PushDictation", "PushRecording"))
  )

# Bold labels for facet headers
oq_labels <- c("OQ1" = expression(bold("OQ1")),
               "OQ2" = expression(bold("OQ2")))

# Add superscript significance letters
df_long <- df_long %>%
  mutate(sig_letter = case_when(
    # --- Break-off
    outcome == "Break-off (%)" & oq == "OQ1" & group == "Control" ~ "",
    outcome == "Break-off (%)" & oq == "OQ1" & group == "Choice" ~ "a",
    outcome == "Break-off (%)" & oq == "OQ1" & group == "PushDictation" ~ "ab",
    outcome == "Break-off (%)" & oq == "OQ1" & group == "PushRecording" ~ "ab",
    outcome == "Break-off (%)" & oq == "OQ2" & group == "Control" ~ "",
    outcome == "Break-off (%)" & oq == "OQ2" & group == "Choice" ~ "",
    outcome == "Break-off (%)" & oq == "OQ2" & group == "PushDictation" ~ "",
    outcome == "Break-off (%)" & oq == "OQ2" & group == "PushRecording" ~ "a",
    
    # --- Item non-response
    outcome == "Item non-response (%)" & oq == "OQ1" & group == "Control" ~ "",
    outcome == "Item non-response (%)" & oq == "OQ1" & group == "Choice" ~ "a",
    outcome == "Item non-response (%)" & oq == "OQ1" & group == "PushDictation" ~ "a",
    outcome == "Item non-response (%)" & oq == "OQ1" & group == "PushRecording" ~ "abc",
    outcome == "Item non-response (%)" & oq == "OQ2" & group == "Control" ~ "",
    outcome == "Item non-response (%)" & oq == "OQ2" & group == "Choice" ~ "a",
    outcome == "Item non-response (%)" & oq == "OQ2" & group == "PushDictation" ~ "ab",
    outcome == "Item non-response (%)" & oq == "OQ2" & group == "PushRecording" ~ "ab",
    
    # --- Responses
    outcome == "Responses (%)" & oq == "OQ1" & group == "Control" ~ "",
    outcome == "Responses (%)" & oq == "OQ1" & group == "Choice" ~ "a",
    outcome == "Responses (%)" & oq == "OQ1" & group == "PushDictation" ~ "ab",
    outcome == "Responses (%)" & oq == "OQ1" & group == "PushRecording" ~ "abc",
    outcome == "Responses (%)" & oq == "OQ2" & group == "Control" ~ "",
    outcome == "Responses (%)" & oq == "OQ2" & group == "Choice" ~ "a",
    outcome == "Responses (%)" & oq == "OQ2" & group == "PushDictation" ~ "ab",
    outcome == "Responses (%)" & oq == "OQ2" & group == "PushRecording" ~ "ab",
    
    # --- Responses using voice input (Choice is reference)
    outcome == "Responses using voice (%)" & oq == "OQ1" & group == "Choice" ~ "",
    outcome == "Responses using voice (%)" & oq == "OQ1" & group == "PushDictation" ~ "b",
    outcome == "Responses using voice (%)" & oq == "OQ1" & group == "PushRecording" ~ "bc",
    outcome == "Responses using voice (%)" & oq == "OQ2" & group == "Choice" ~ "",
    outcome == "Responses using voice (%)" & oq == "OQ2" & group == "PushDictation" ~ "b",
    outcome == "Responses using voice (%)" & oq == "OQ2" & group == "PushRecording" ~ "bc",
    
    TRUE ~ ""
  ))

# Combine value and significance for plotting
df_long <- df_long %>%
  mutate(label = if_else(sig_letter != "", paste0(p, "<sup>", sig_letter, "</sup>"), as.character(p)))

# Split into top and bottom sections
df_upper <- df_long %>% filter(outcome %in% c("Break-off (%)", "Item non-response (%)"))
df_lower <- df_long %>% filter(outcome %in% c("Responses (%)", "Responses using voice (%)"))

# Remove control line for "Responses using voice (%)"
df_lower_lines <- df_lower %>%
  filter(!(outcome == "Responses using voice (%)" & group == "Control"))

# Plot for top part (0–20)
p1 <- ggplot(df_upper, aes(x = group)) +
  geom_line(aes(y = control, group = 1), color = "purple") +
  geom_point(aes(y = p), shape = 21, fill = "black", size = 2) +
  ggtext::geom_richtext(aes(y = p, label = label),
                        vjust = -0.1, size = 2.3,
                        fill = NA, label.color = NA) +
  facet_grid(outcome ~ oq, labeller = labeller(oq = oq_labels), switch = "y") +
  scale_y_continuous(position = "right", limits = c(0, 20)) +
  ylim(0, 20) +
  theme_bw() +
  theme(
    legend.position = "none",
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank(),
    panel.grid.major = element_line(linetype = "dotted"),
    strip.text.x = element_text(face = "bold"),
    strip.placement = "outside",     
    plot.margin = margin(5, 5, 5, 5) 
  ) +
  xlab(NULL) + ylab(NULL)


# Plot for bottom part (0–110)
p2 <- ggplot(df_lower, aes(x = group)) +
  geom_line(data = df_lower_lines,
            aes(y = control, group = interaction(outcome, oq)),
            color = "purple") +
  geom_point(aes(y = p), shape = 21, fill = "black", size = 2) +
  ggtext::geom_richtext(aes(y = p, label = label),
                        vjust = -0.1, size = 2.3,
                        fill = NA, label.color = NA) +
  facet_grid(outcome ~ oq, labeller = labeller(oq = oq_labels), switch = "y") +
  scale_y_continuous(position = "right", limits = c(0, 20)) +
  ylim(0, 110) +
  theme_bw() +
  theme(
    legend.position = "none",
    axis.text.x = element_text(),
    panel.grid.major = element_line(linetype = "dotted"),
    strip.text.x = element_blank(),
    strip.background.x = element_blank(),
    strip.placement = "outside",     
    plot.margin = margin(5, 5, 5, 5) 
  ) +
  xlab(NULL) + ylab(NULL) +
  scale_x_discrete(labels = c(
    "Control" = "Control\n(a)",
    "Choice" = "Choice\n(b)",
    "PushDictation" = "PushDictation\n(c)",
    "PushRecording" = "PushRecording\n(d)"
  ))

# Combine both plots
combined_plot <- p1 / p2 

# Save the result
ggsave("Figure1.pdf",
       plot = combined_plot, device = cairo_pdf, width = 10, height = 8)


######################################################
###Transform ex-Table 3 in Figure 2
######################################################

# Create df2
df2 <- tibble::tribble(
  ~outcome, ~oq, ~p1,  ~p2,  ~p3,  ~p4,
  1, 1,  82.0,  90.3, 85.0, 89.6,
  1, 2,  80.8,  84.4, 83.3, 83.3,
  2, 1,  20.0,  16.8, 19.8, 19.4,
  2, 2,  13.6,   9.5, 14.9, 18.2,
  3, 1,  98.5,  94.9, 89.8, 79.4,
  3, 2,  97.5,  95.8, 90.2, 74.1,
  4, 1,   1.5,   1.6,  1.6,  1.7,
  4, 2,   2.2,   2.4,  2.5,  2.8,
  5, 1,   109,   177,  181,  227,
  5, 2,    93,   135,  144,  227
) %>%
  mutate(control = p1)

# Reshape df2 to long format
df2_long <- df2 %>%
  pivot_longer(cols = starts_with("p"), names_to = "group", values_to = "p") %>%
  mutate(group = case_when(
    group == "p1" ~ 1,
    group == "p2" ~ 2,
    group == "p3" ~ 3,
    group == "p4" ~ 4
  ))

# Factor levels
df2_long <- df2_long %>%
  mutate(
    outcome = factor(outcome, levels = 1:5,
                     labels = c("Valid responses C3 (%)", "Answered both parts C1 (%)",
                                "No problem C1 (%)", "Number themes C1 (avg.)", "Number characters (avg.)")),
    oq = factor(oq, levels = 1:2, labels = c("OQ1", "OQ2")),
    group = factor(group, levels = 1:4,
                   labels = c("Control", "Choice", "PushDictation", "PushRecording"))
  )

# Superscript helper
superscript_unicode <- function(x) {
  map_chr(x, ~ str_replace_all(.x, c(
    "a" = "\u1d43",  # ᵃ
    "b" = "\u1d47",  # ᵇ
    "c" = "\u1d9c",  # ᶜ
    "d" = "\u1d48"   # ᵈ
  )))
}

# Significance annotations
df2_long <- df2_long %>%
  mutate(sig_letter = case_when(
    outcome == "Valid responses C3 (%)" & oq == "OQ1" & group == "Choice" ~ "a",
    outcome == "Valid responses C3 (%)" & oq == "OQ1" & group == "PushRecording" ~ "a",
    
    outcome == "No problem C1 (%)" & oq == "OQ1" & group == "PushDictation" ~ "a",
    outcome == "No problem C1 (%)" & oq == "OQ1" & group == "PushRecording" ~ "ac",
    outcome == "No problem C1 (%)" & oq == "OQ2" & group == "PushDictation" ~ "a",
    outcome == "No problem C1 (%)" & oq == "OQ2" & group == "PushRecording" ~ "ac",
    
    outcome == "Number themes C1 (avg.)" & oq == "OQ1" & group == "PushRecording" ~ "a",
    outcome == "Number themes C1 (avg.)" & oq == "OQ2" & group == "PushDictation" ~ "a",
    outcome == "Number themes C1 (avg.)" & oq == "OQ2" & group == "PushRecording" ~ "ac",
    
    outcome == "Number characters (avg.)" & oq == "OQ1" & group == "Choice" ~ "a",
    outcome == "Number characters (avg.)" & oq == "OQ1" & group == "PushDictation" ~ "a",
    outcome == "Number characters (avg.)" & oq == "OQ1" & group == "PushRecording" ~ "ac",
    outcome == "Number characters (avg.)" & oq == "OQ2" & group == "Choice" ~ "a",
    outcome == "Number characters (avg.)" & oq == "OQ2" & group == "PushDictation" ~ "a",
    outcome == "Number characters (avg.)" & oq == "OQ2" & group == "PushRecording" ~ "ac",
    
    TRUE ~ ""
  )) %>%
  mutate(label = if_else(sig_letter != "", paste0(p, "<sup>", sig_letter, "</sup>"), as.character(p)))


# Labels for top strip
oq_labels <- c("OQ1" = "OQ1", "OQ2" = "OQ2")

upper_outcomes <- c(
  "Valid responses C3 (%)",
  "No problem C1 (%)")
middle_outcomes <- c("Answered both parts C1 (%)",
                     "Number themes C1 (avg.)")
lower_outcomes <- "Number characters (avg.)"

df2_upper <- df2_long %>% filter(outcome %in% upper_outcomes)
df2_middle <- df2_long %>% filter(outcome %in% middle_outcomes)
df2_lower <- df2_long %>% filter(outcome %in% lower_outcomes)

tv_data_upper <- tibble::tribble(
  ~group, ~oq, ~outcome, ~Text, ~Voice,
  "Choice", "OQ1", "Valid responses C3 (%)", 90.7, 88.9,
  "PushDictation", "OQ1", "Valid responses C3 (%)", 86.0, 84.7,
  "PushRecording", "OQ1", "Valid responses C3 (%)", 86.7, 91.3,
  "Choice", "OQ2", "Valid responses C3 (%)", 85.4, 80.0,
  "PushDictation", "OQ2", "Valid responses C3 (%)", 76.2, 85.0,
  "PushRecording", "OQ2", "Valid responses C3 (%)", 88.0, 80.6,
  "Choice", "OQ1", "No problem C1 (%)", 98.1, 82.5,
  "PushDictation", "OQ1", "No problem C1 (%)", 94.6, 88.7,
  "PushRecording", "OQ1", "No problem C1 (%)", 98.5, 68.7,
  "Choice", "OQ2", "No problem C1 (%)", 99.4, 78.1,
  "PushDictation", "OQ2", "No problem C1 (%)", 96.9, 88.7,
  "PushRecording", "OQ2", "No problem C1 (%)", 97.0, 59.6
) %>%
  pivot_longer(cols = c(Text, Voice), names_to = "subgroup", values_to = "p") %>%
  mutate(
    outcome = factor(outcome, levels = levels(df2_long$outcome)),
    subgroup_color = if_else(subgroup == "Text", "red", "blue")
  )

tv_data_middle <- tibble::tribble(
  ~group, ~oq, ~outcome, ~Text, ~Voice,
  "Choice", "OQ1", "Answered both parts C1 (%)", 17.9, 12.5,
  "PushDictation", "OQ1", "Answered both parts C1 (%)", 24.3, 18.7,
  "PushRecording", "OQ1", "Answered both parts C1 (%)", 13.8, 22.6,
  "Choice", "OQ2", "Answered both parts C1 (%)",  9.5,  9.4,
  "PushDictation", "OQ2", "Answered both parts C1 (%)", 12.5, 15.5,
  "PushRecording", "OQ2", "Answered both parts C1 (%)",  9.1, 24.0,
  "Choice", "OQ1", "Number themes C1 (avg.)", 1.6, 1.6,
  "PushDictation", "OQ1", "Number themes C1 (avg.)", 1.7, 1.6,
  "PushRecording", "OQ1", "Number themes C1 (avg.)", 1.5, 1.9,
  "Choice", "OQ2", "Number themes C1 (avg.)", 2.4, 2.8,
  "PushDictation", "OQ2", "Number themes C1 (avg.)", 2.6, 2.5,
  "PushRecording", "OQ2", "Number themes C1 (avg.)", 2.4, 3.0
) %>%
  pivot_longer(cols = c(Text, Voice), names_to = "subgroup", values_to = "p") %>%
  mutate(
    outcome = factor(outcome, levels = levels(df2_long$outcome)),
    subgroup_color = if_else(subgroup == "Text", "red", "blue")
  )

tv_data_lower <- tibble::tribble(
  ~group, ~oq, ~outcome, ~Text, ~Voice,
  "Choice", "OQ1", "Number characters (avg.)", 169, 210,
  "PushDictation", "OQ1", "Number characters (avg.)", 160, 187,
  "PushRecording", "OQ1", "Number characters (avg.)", 124, 289,
  "Choice", "OQ2", "Number characters (avg.)", 121, 196,
  "PushDictation", "OQ2", "Number characters (avg.)", 132, 147,
  "PushRecording", "OQ2", "Number characters (avg.)", 116, 291
) %>%
  pivot_longer(cols = c(Text, Voice), names_to = "subgroup", values_to = "p") %>%
  mutate(
    outcome = factor(outcome, levels = levels(df2_long$outcome)),
    subgroup_color = if_else(subgroup == "Text", "red", "blue")
  )

p2_upper <- ggplot(df2_upper, aes(x = group)) +
  geom_line(aes(y = control, group = interaction(outcome, oq)), color = "purple") +
  geom_point(aes(y = p), shape = 21, fill = "black", size = 2.2)+
  geom_point(data = tv_data_upper, aes(x = group, y = p, color = subgroup),
             size = 2, shape = 16, inherit.aes = FALSE) +
  ggtext::geom_richtext(aes(y = p, label = label),
                        vjust = -0.3, size = 2.5,
                        fill = NA, label.color = NA) +
  facet_grid(outcome ~ oq, labeller = labeller(oq = oq_labels), switch = "y") +
  scale_y_continuous(position = "right", limits = c(0, 20)) +
  ylim(0, 112) +
  theme_bw(base_size = 10) +
  theme(
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank(),
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    #legend.position = "none",
    panel.grid.major = element_line(linetype = "dotted"),
    strip.text.x = element_text(face = "bold"),
    strip.placement = "outside",     
    plot.margin = margin(5, 5, 5, 5) 
  )

p2_middle <- ggplot(df2_middle, aes(x = group)) +
  geom_line(aes(y = control, group = interaction(outcome, oq)), color = "purple") +
  geom_point(aes(y = p), shape = 21, fill = "black", size = 2.2) +
  geom_point(data = tv_data_middle, aes(x = group, y = p, color = subgroup),
             size = 2, shape = 16, inherit.aes = FALSE)+
  ggtext::geom_richtext(aes(y = p, label = label),
                        vjust = -0.2, size = 2.5,
                        fill = NA, label.color = NA) +
  facet_grid(outcome ~ oq, labeller = labeller(oq = oq_labels), switch = "y") +
  scale_y_continuous(position = "right", limits = c(0, 20)) +
  ylim(0, 30) +  
  theme_bw(base_size = 10) +
  theme(
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank(),
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    legend.position = "none",
    panel.grid.major = element_line(linetype = "dotted"),
    strip.text.x = element_blank(),         # Hide x facet labels in middle and bottom
    strip.background.x = element_blank(),
    strip.placement = "outside",     
    plot.margin = margin(5, 5, 5, 5) 
  )

p2_lower <- ggplot(df2_lower, aes(x = group)) +
  geom_line(data = df2_lower,
            aes(y = control, group = interaction(outcome, oq)),
            color = "purple") +
  geom_point(aes(y = p), shape = 21, fill = "black", size = 2.2) +
  geom_point(data = tv_data_lower, aes(x = group, y = p, color = subgroup),
             size = 2, shape = 16, inherit.aes = FALSE)+
  ggtext::geom_richtext(aes(y = p, label = label),
                        vjust = -0.2, size = 2.5,
                        fill = NA, label.color = NA) +
  facet_grid(outcome ~ oq, labeller = labeller(oq = oq_labels), switch = "y") +
  scale_y_continuous(position = "right", limits = c(0, 20)) +
  ylim(80, 300) +
  theme_bw(base_size = 10) +
  theme(
    axis.text.x = element_text(),
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    legend.position = "none",
    panel.grid.major = element_line(linetype = "dotted"),
    strip.text.x = element_blank(),
    strip.background.x = element_blank(),
    strip.placement = "outside",     
    plot.margin = margin(5, 5, 5, 5), 
    ) +
  scale_x_discrete(labels = c(
    "Control" = "Control\n(a)",
    "Choice" = "Choice\n(b)",
    "PushDictation" = "PushDictation\n(c)",
    "PushRecording" = "PushRecording\n(d)"
  ))


# Combine all three plots 
figure2 <- p2_upper / p2_middle / p2_lower +
  plot_layout(heights = c(1.2, 1.2, 0.7)) 


ggsave("Figure2.pdf",
       plot = figure2, device = cairo_pdf, width = 10, height = 10)
