diff --git a/R/plot.R b/R/plot.R index bbea882..72322cc 100644 --- a/R/plot.R +++ b/R/plot.R @@ -102,12 +102,31 @@ plot.outstandR <- function(x, ..., plot_df$Model <- factor(plot_df$Model, levels = model_levels) } + # Define custom colors so that any naive model is plotted in black + n_models <- length(model_levels) + is_naive <- grepl("Naive", model_levels, ignore.case = TRUE) + n_non_naive <- sum(!is_naive) + + if (n_non_naive > 0) { + non_naive_colors <- grDevices::hcl( + h = seq(15, 375, length.out = n_non_naive + 1)[1:n_non_naive], + c = 100, + l = 65 + ) + } else { + non_naive_colors <- character(0) + } + + model_colors <- stats::setNames(rep("black", n_models), model_levels) + model_colors[!is_naive] <- non_naive_colors + # combined forest plot ggplot( plot_df, aes(x = .data$Estimate, y = .data$Treatments, color = .data$Model)) + geom_point(position = position_dodge(width = 0.5), size = 3) + geom_errorbarh(aes(xmin = .data$lower.0.95, xmax = .data$upper.0.95), position = position_dodge(width = 0.5), height = 0.2, na.rm = TRUE) + + scale_color_manual(values = model_colors) + facet_wrap(~.data$Type, scales = "free") + geom_vline(data = dplyr::filter(plot_df, .data$Type == "Relative Contrasts"), aes(xintercept = 0), linetype = "dashed", color = "gray50") + diff --git a/scripts/exercises2.html b/scripts/exercises2.html index 854ab4f..7b31f55 100644 --- a/scripts/exercises2.html +++ b/scripts/exercises2.html @@ -327,15 +327,15 @@

Function Arguments

Chain 1: Iteration: 1500 / 2000 [ 75%] (Sampling) Chain 1: Iteration: 2000 / 2000 [100%] (Sampling) Chain 1: -Chain 1: Elapsed Time: 0.228 seconds (Warm-up) -Chain 1: 0.202 seconds (Sampling) -Chain 1: 0.43 seconds (Total) +Chain 1: Elapsed Time: 0.218 seconds (Warm-up) +Chain 1: 0.204 seconds (Sampling) +Chain 1: 0.422 seconds (Total) Chain 1: SAMPLING FOR MODEL 'bernoulli' NOW (CHAIN 2). Chain 2: -Chain 2: Gradient evaluation took 2.1e-05 seconds -Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 0.21 seconds. +Chain 2: Gradient evaluation took 1.7e-05 seconds +Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 0.17 seconds. Chain 2: Adjust your expectations accordingly! Chain 2: Chain 2: @@ -347,8 +347,8 @@

Function Arguments

Chain 2: Iteration: 2000 / 2000 [100%] (Sampling) Chain 2: Chain 2: Elapsed Time: 0.213 seconds (Warm-up) -Chain 2: 0.201 seconds (Sampling) -Chain 2: 0.414 seconds (Total) +Chain 2: 0.202 seconds (Sampling) +Chain 2: 0.415 seconds (Total) Chain 2: @@ -369,8 +369,8 @@

Function Arguments


 SAMPLING FOR MODEL 'bernoulli' NOW (CHAIN 1).
 Chain 1: 
-Chain 1: Gradient evaluation took 2.8e-05 seconds
-Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.28 seconds.
+Chain 1: Gradient evaluation took 3.2e-05 seconds
+Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.32 seconds.
 Chain 1: Adjust your expectations accordingly!
 Chain 1: 
 Chain 1: 
@@ -387,9 +387,9 @@ 

Function Arguments

Chain 1: Iteration: 1800 / 2000 [ 90%] (Sampling) Chain 1: Iteration: 2000 / 2000 [100%] (Sampling) Chain 1: -Chain 1: Elapsed Time: 0.224 seconds (Warm-up) -Chain 1: 0.208 seconds (Sampling) -Chain 1: 0.432 seconds (Total) +Chain 1: Elapsed Time: 0.228 seconds (Warm-up) +Chain 1: 0.205 seconds (Sampling) +Chain 1: 0.433 seconds (Total) Chain 1: SAMPLING FOR MODEL 'bernoulli' NOW (CHAIN 2). @@ -413,8 +413,8 @@

Function Arguments

Chain 2: Iteration: 2000 / 2000 [100%] (Sampling) Chain 2: Chain 2: Elapsed Time: 0.21 seconds (Warm-up) -Chain 2: 0.213 seconds (Sampling) -Chain 2: 0.423 seconds (Total) +Chain 2: 0.215 seconds (Sampling) +Chain 2: 0.425 seconds (Total) Chain 2:
@@ -570,8 +570,8 @@

Function Arguments


 SAMPLING FOR MODEL 'bernoulli' NOW (CHAIN 1).
 Chain 1: 
-Chain 1: Gradient evaluation took 2.4e-05 seconds
-Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.24 seconds.
+Chain 1: Gradient evaluation took 2.5e-05 seconds
+Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.25 seconds.
 Chain 1: Adjust your expectations accordingly!
 Chain 1: 
 Chain 1: 
@@ -582,9 +582,9 @@ 

Function Arguments

Chain 1: Iteration: 1500 / 2000 [ 75%] (Sampling) Chain 1: Iteration: 2000 / 2000 [100%] (Sampling) Chain 1: -Chain 1: Elapsed Time: 0.223 seconds (Warm-up) -Chain 1: 0.206 seconds (Sampling) -Chain 1: 0.429 seconds (Total) +Chain 1: Elapsed Time: 0.219 seconds (Warm-up) +Chain 1: 0.203 seconds (Sampling) +Chain 1: 0.422 seconds (Total) Chain 1: SAMPLING FOR MODEL 'bernoulli' NOW (CHAIN 2). @@ -601,9 +601,9 @@

Function Arguments

Chain 2: Iteration: 1500 / 2000 [ 75%] (Sampling) Chain 2: Iteration: 2000 / 2000 [100%] (Sampling) Chain 2: -Chain 2: Elapsed Time: 0.216 seconds (Warm-up) +Chain 2: Elapsed Time: 0.21 seconds (Warm-up) Chain 2: 0.202 seconds (Sampling) -Chain 2: 0.418 seconds (Total) +Chain 2: 0.412 seconds (Total) Chain 2:
@@ -659,8 +659,8 @@

Function Arguments


 SAMPLING FOR MODEL 'bernoulli' NOW (CHAIN 1).
 Chain 1: 
-Chain 1: Gradient evaluation took 3.4e-05 seconds
-Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.34 seconds.
+Chain 1: Gradient evaluation took 3.9e-05 seconds
+Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.39 seconds.
 Chain 1: Adjust your expectations accordingly!
 Chain 1: 
 Chain 1: 
@@ -677,15 +677,15 @@ 

Function Arguments

Chain 1: Iteration: 1800 / 2000 [ 90%] (Sampling) Chain 1: Iteration: 2000 / 2000 [100%] (Sampling) Chain 1: -Chain 1: Elapsed Time: 0.285 seconds (Warm-up) -Chain 1: 0.253 seconds (Sampling) -Chain 1: 0.538 seconds (Total) +Chain 1: Elapsed Time: 0.225 seconds (Warm-up) +Chain 1: 0.205 seconds (Sampling) +Chain 1: 0.43 seconds (Total) Chain 1: SAMPLING FOR MODEL 'bernoulli' NOW (CHAIN 2). Chain 2: -Chain 2: Gradient evaluation took 3e-05 seconds -Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 0.3 seconds. +Chain 2: Gradient evaluation took 1.7e-05 seconds +Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 0.17 seconds. Chain 2: Adjust your expectations accordingly! Chain 2: Chain 2: @@ -702,9 +702,9 @@

Function Arguments

Chain 2: Iteration: 1800 / 2000 [ 90%] (Sampling) Chain 2: Iteration: 2000 / 2000 [100%] (Sampling) Chain 2: -Chain 2: Elapsed Time: 0.243 seconds (Warm-up) -Chain 2: 0.214 seconds (Sampling) -Chain 2: 0.457 seconds (Total) +Chain 2: Elapsed Time: 0.205 seconds (Warm-up) +Chain 2: 0.217 seconds (Sampling) +Chain 2: 0.422 seconds (Total) Chain 2:
@@ -880,22 +880,33 @@

Function Arguments

5. Build the Forest Plot

-
ggplot(all_results_intro, aes(x = Estimate, y = Method, color = Method)) +
-  geom_point(size = 4) +
-  geom_errorbarh(aes(xmin = lower.0.95, xmax = upper.0.95), height = 0.2, linewidth = 1, na.rm = TRUE) +
-  geom_vline(xintercept = 0, linetype = "dashed", color = "gray50", linewidth = 1) +
-  theme_minimal() +
-  labs(
-    title = "Relative Treatment Effect (A vs B)",
-    subtitle = "Adjusted vs. Unadjusted Anchored Estimates",
-    x = "Risk Difference",
-    y = ""
-  ) +
-  theme(
-    legend.position = "none",
-    axis.text.y = element_text(size = 11, face = "bold"),
-    plot.title = element_text(face = "bold", size = 14)
-  )
+
# Define colors: naive is black, others are default ggplot2 colors
+methods_intro <- levels(all_results_intro$Method)
+is_naive_intro <- grepl("Naive", methods_intro, ignore.case = TRUE)
+n_non_naive_intro <- sum(!is_naive_intro)
+colors_intro <- stats::setNames(rep("black", length(methods_intro)), methods_intro)
+colors_intro[!is_naive_intro] <- grDevices::hcl(
+  h = seq(15, 375, length.out = n_non_naive_intro + 1)[1:n_non_naive_intro], 
+  c = 100, l = 65
+)
+
+ggplot(all_results_intro, aes(x = Estimate, y = Method, color = Method)) +
+  geom_point(size = 4) +
+  geom_errorbarh(aes(xmin = lower.0.95, xmax = upper.0.95), height = 0.2, linewidth = 1, na.rm = TRUE) +
+  scale_color_manual(values = colors_intro) +
+  geom_vline(xintercept = 0, linetype = "dashed", color = "gray50", linewidth = 1) +
+  theme_minimal() +
+  labs(
+    title = "Relative Treatment Effect (A vs B)",
+    subtitle = "Adjusted vs. Unadjusted Anchored Estimates",
+    x = "Risk Difference",
+    y = ""
+  ) +
+  theme(
+    legend.position = "none",
+    axis.text.y = element_text(size = 11, face = "bold"),
+    plot.title = element_text(face = "bold", size = 14)
+  )
@@ -1009,8 +1020,8 @@

Exercises


 SAMPLING FOR MODEL 'continuous' NOW (CHAIN 1).
 Chain 1: 
-Chain 1: Gradient evaluation took 8.4e-05 seconds
-Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.84 seconds.
+Chain 1: Gradient evaluation took 4.7e-05 seconds
+Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 0.47 seconds.
 Chain 1: Adjust your expectations accordingly!
 Chain 1: 
 Chain 1: 
@@ -1028,8 +1039,8 @@ 

Exercises

SAMPLING FOR MODEL 'continuous' NOW (CHAIN 2). Chain 2: -Chain 2: Gradient evaluation took 1e-05 seconds -Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 0.1 seconds. +Chain 2: Gradient evaluation took 9e-06 seconds +Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 0.09 seconds. Chain 2: Adjust your expectations accordingly! Chain 2: Chain 2: @@ -1040,9 +1051,9 @@

Exercises

Chain 2: Iteration: 1500 / 2000 [ 75%] (Sampling) Chain 2: Iteration: 2000 / 2000 [100%] (Sampling) Chain 2: -Chain 2: Elapsed Time: 0.073 seconds (Warm-up) -Chain 2: 0.09 seconds (Sampling) -Chain 2: 0.163 seconds (Total) +Chain 2: Elapsed Time: 0.072 seconds (Warm-up) +Chain 2: 0.087 seconds (Sampling) +Chain 2: 0.159 seconds (Total) Chain 2:
@@ -1082,15 +1093,15 @@

Exercises

Chain 1: Iteration: 1800 / 2000 [ 90%] (Sampling) Chain 1: Iteration: 2000 / 2000 [100%] (Sampling) Chain 1: -Chain 1: Elapsed Time: 0.082 seconds (Warm-up) +Chain 1: Elapsed Time: 0.08 seconds (Warm-up) Chain 1: 0.082 seconds (Sampling) -Chain 1: 0.164 seconds (Total) +Chain 1: 0.162 seconds (Total) Chain 1: SAMPLING FOR MODEL 'continuous' NOW (CHAIN 2). Chain 2: -Chain 2: Gradient evaluation took 3.2e-05 seconds -Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 0.32 seconds. +Chain 2: Gradient evaluation took 1.1e-05 seconds +Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 0.11 seconds. Chain 2: Adjust your expectations accordingly! Chain 2: Chain 2: @@ -1108,8 +1119,8 @@

Exercises

Chain 2: Iteration: 2000 / 2000 [100%] (Sampling) Chain 2: Chain 2: Elapsed Time: 0.082 seconds (Warm-up) -Chain 2: 0.091 seconds (Sampling) -Chain 2: 0.173 seconds (Total) +Chain 2: 0.093 seconds (Sampling) +Chain 2: 0.175 seconds (Total) Chain 2:
@@ -1477,27 +1488,38 @@

Exercises

"G-comp ML (Anchored, Adjusted)" )) -ggplot(all_results_final, aes(x = Estimate, y = Method, color = Method)) + - geom_point(size = 4) + - geom_errorbarh(aes(xmin = lower.0.95, xmax = upper.0.95), height = 0.2, linewidth = 1, na.rm = TRUE) + - - # Highlight True Effect (0.0) with a distinct line - geom_vline(aes(xintercept = 0, linetype = "True Underlying Effect"), color = "red", linewidth = 1.2) + - scale_linetype_manual(name = "", values = "dashed") + - - theme_minimal() + - labs( - title = "Relative Treatment Effect (A vs B)", - subtitle = "The Impact of Population Adjustment and Anchoring Assumptions", - x = "Risk Difference", - y = "" - ) + - theme( - legend.position = "bottom", # Show the legend so can see the "True Effect" label - axis.text.y = element_text(size = 11, face = "bold"), - plot.title = element_text(face = "bold", size = 14) - ) + - guides(color = "none") # Hide redundant colour legend for methods
+# Define colors dynamically: naive is black, others are default ggplot2 colors +methods_final <- levels(all_results_final$Method) +is_naive_final <- grepl("Naive", methods_final, ignore.case = TRUE) +n_non_naive_final <- sum(!is_naive_final) +colors_final <- stats::setNames(rep("black", length(methods_final)), methods_final) +colors_final[!is_naive_final] <- grDevices::hcl( + h = seq(15, 375, length.out = n_non_naive_final + 1)[1:n_non_naive_final], + c = 100, l = 65 +) + +ggplot(all_results_final, aes(x = Estimate, y = Method, color = Method)) + + geom_point(size = 4) + + geom_errorbarh(aes(xmin = lower.0.95, xmax = upper.0.95), height = 0.2, linewidth = 1, na.rm = TRUE) + + scale_color_manual(values = colors_final) + + + # Highlight True Effect (0.0) with a distinct line + geom_vline(aes(xintercept = 0, linetype = "True Underlying Effect"), color = "red", linewidth = 1.2) + + scale_linetype_manual(name = "", values = "dashed") + + + theme_minimal() + + labs( + title = "Relative Treatment Effect (A vs B)", + subtitle = "The Impact of Population Adjustment and Anchoring Assumptions", + x = "Risk Difference", + y = "" + ) + + theme( + legend.position = "bottom", # Show the legend so can see the "True Effect" label + axis.text.y = element_text(size = 11, face = "bold"), + plot.title = element_text(face = "bold", size = 14) + ) + + guides(color = "none") # Hide redundant colour legend for methods
diff --git a/scripts/exercises2.qmd b/scripts/exercises2.qmd index 8d5427b..dad4bca 100644 --- a/scripts/exercises2.qmd +++ b/scripts/exercises2.qmd @@ -341,9 +341,20 @@ all_results_intro$Method <- factor(all_results_intro$Method, levels = c( ```{r} #| echo: true +# Define colors: naive is black, others are default ggplot2 colors +methods_intro <- levels(all_results_intro$Method) +is_naive_intro <- grepl("Naive", methods_intro, ignore.case = TRUE) +n_non_naive_intro <- sum(!is_naive_intro) +colors_intro <- stats::setNames(rep("black", length(methods_intro)), methods_intro) +colors_intro[!is_naive_intro] <- grDevices::hcl( + h = seq(15, 375, length.out = n_non_naive_intro + 1)[1:n_non_naive_intro], + c = 100, l = 65 +) + ggplot(all_results_intro, aes(x = Estimate, y = Method, color = Method)) + geom_point(size = 4) + geom_errorbarh(aes(xmin = lower.0.95, xmax = upper.0.95), height = 0.2, linewidth = 1, na.rm = TRUE) + + scale_color_manual(values = colors_intro) + geom_vline(xintercept = 0, linetype = "dashed", color = "gray50", linewidth = 1) + theme_minimal() + labs( @@ -696,9 +707,20 @@ all_results_final$Method <- factor(all_results_final$Method, levels = c( "G-comp ML (Anchored, Adjusted)" )) +# Define colors dynamically: naive is black, others are default ggplot2 colors +methods_final <- levels(all_results_final$Method) +is_naive_final <- grepl("Naive", methods_final, ignore.case = TRUE) +n_non_naive_final <- sum(!is_naive_final) +colors_final <- stats::setNames(rep("black", length(methods_final)), methods_final) +colors_final[!is_naive_final] <- grDevices::hcl( + h = seq(15, 375, length.out = n_non_naive_final + 1)[1:n_non_naive_final], + c = 100, l = 65 +) + ggplot(all_results_final, aes(x = Estimate, y = Method, color = Method)) + geom_point(size = 4) + geom_errorbarh(aes(xmin = lower.0.95, xmax = upper.0.95), height = 0.2, linewidth = 1, na.rm = TRUE) + + scale_color_manual(values = colors_final) + # Highlight True Effect (0.0) with a distinct line geom_vline(aes(xintercept = 0, linetype = "True Underlying Effect"), color = "red", linewidth = 1.2) + diff --git a/scripts/exercises2_files/figure-html/unnamed-chunk-12-1.png b/scripts/exercises2_files/figure-html/unnamed-chunk-12-1.png index 6810bff..9fcfc86 100644 Binary files a/scripts/exercises2_files/figure-html/unnamed-chunk-12-1.png and b/scripts/exercises2_files/figure-html/unnamed-chunk-12-1.png differ diff --git a/scripts/exercises2_files/figure-html/unnamed-chunk-14-1.png b/scripts/exercises2_files/figure-html/unnamed-chunk-14-1.png index 85dfa1d..e9c6b5d 100644 Binary files a/scripts/exercises2_files/figure-html/unnamed-chunk-14-1.png and b/scripts/exercises2_files/figure-html/unnamed-chunk-14-1.png differ diff --git a/scripts/exercises2_files/figure-html/unnamed-chunk-25-1.png b/scripts/exercises2_files/figure-html/unnamed-chunk-25-1.png index e07e43f..06d92b5 100644 Binary files a/scripts/exercises2_files/figure-html/unnamed-chunk-25-1.png and b/scripts/exercises2_files/figure-html/unnamed-chunk-25-1.png differ diff --git a/scripts/exercises2_files/figure-html/unnamed-chunk-9-1.png b/scripts/exercises2_files/figure-html/unnamed-chunk-9-1.png index 9f851e9..95ea92d 100644 Binary files a/scripts/exercises2_files/figure-html/unnamed-chunk-9-1.png and b/scripts/exercises2_files/figure-html/unnamed-chunk-9-1.png differ diff --git a/scripts/practical_paic.pdf b/scripts/practical_paic.pdf index 20c31f5..f368c6a 100644 Binary files a/scripts/practical_paic.pdf and b/scripts/practical_paic.pdf differ