I'm trying to tinker with visualizing more detail about the precision of results based on some color-based variation, but running into trouble when I try to simultaneously create conditions based on both alpha and color at the same time.
How would I do something like:
-If the pvalue is >.10, all colors are gray with alpha =0.5
-If the pvalue is between .05 and .10, the colors remain as specified below in scale_color_manual()
, but have alpha =0.5
-If the pvalue is <.05, the colors remain as specified below in scale_color_manual()
with "full" alpha
Some simulated data and code:
set.seed(123)
terms <- c("covariate1", "covariate2", "covariate3", "covariate4")
outcomes <- c("Outcome1", "Outcome2", "Outcome3")
treatments <- c("Treatment A", "Treatment B")
results <- expand.grid(term = terms, outcome = outcomes, treatment = treatments) %>%
mutate(
term = factor(term, levels = terms),
estimate = rnorm(n(), 0, 0.2),
se = runif(n(), 0.05, 0.2),
conf.low = estimate - 1.96 * se,
conf.high = estimate + 1.96 * se
)
ggplot(results, aes(x = estimate, y = term, color = outcome)) +
geom_vline(xintercept = 0, color = "black", linetype = "dashed") +
geom_point(size = 2, position = position_dodge(width = 0.2)) +
geom_errorbarh(aes(xmin = conf.low, xmax = conf.high), height = 0, position = position_dodge(width = 0.2)) +
facet_wrap(~ treatment) +
scale_color_manual(values = c("Outcome1" = "gold3",
"Outcome2" = "green3",
"Outcome3" = "salmon")) +
theme_minimal()
One possible solution:
First, calculate your p-values. Here's an example with a z-test, but use whatever's appropriate for your data:
results <- results %>%
mutate(
p.value = 2 * (1 - pnorm(abs(estimate / se)))
)
Then, map the color aesthetic to a new factor vector that is equal to outcome
unless p >= 0.10:
color = factor(
if_else(p.value < 0.10, outcome, "n.s."),
levels = c(levels(outcome), "n.s.")
)
In order to keep outcomes in the legend even if none are significant, we need to add drop = FALSE
to scale_color_manual()
as well as show.legend = TRUE
to both geom_point()
and geom_errorbarh()
. We also need to add the aesthetic group = outcome
so that position_dodge()
still works as before.
Map alpha to a new factor vector that is one level if less than 0.05, and another otherwise:
alpha = cut(p.value, c(0, 0.05, 1))
And use scale_alpha_manual()
to define the alpha values:
scale_alpha_manual(
values = c(1, 0.5),
guide = "none"
)
Putting it all together (note I used a different seed):
set.seed(789)
terms <- c("covariate1", "covariate2", "covariate3", "covariate4")
outcomes <- c("Outcome1", "Outcome2", "Outcome3")
treatments <- c("Treatment A", "Treatment B")
results <- expand.grid(term = terms, outcome = outcomes, treatment = treatments) %>%
mutate(
term = factor(term, levels = terms),
estimate = rnorm(n(), 0, 0.2),
se = runif(n(), 0.05, 0.2),
conf.low = estimate - 1.96 * se,
conf.high = estimate + 1.96 * se
) %>%
mutate(
p.value = 2 * (1 - pnorm(abs(estimate / se)))
)
ggplot(results,
aes(
x = estimate,
y = term,
group = outcome,
color = factor(
if_else(p.value < 0.10, outcome, "n.s."),
levels = c(levels(outcome), "n.s.")
),
alpha = cut(p.value, c(0, 0.05, 1))
)
) +
geom_vline(xintercept = 0, color = "black", linetype = "dashed") +
geom_point(size = 2, position = position_dodge(width = 0.2), show.legend = TRUE) +
geom_errorbarh(aes(xmin = conf.low, xmax = conf.high), height = 0, position = position_dodge(width = 0.2), show.legend = TRUE) +
facet_wrap(~ treatment) +
scale_color_manual(
values = c(
"Outcome1" = "gold3",
"Outcome2" = "green3",
"Outcome3" = "salmon",
"n.s." = "grey"
),
drop = FALSE,
name = "Outcome"
) +
scale_alpha_manual(
values = c(1, 0.5),
guide = "none"
) +
theme_minimal()