Reputation: 57
I'm trying to plot odds ratios, but running into an issue because some of my variables have more than one group. As an example, CatA and CatC have one group ("S1"), but CatB and CatD have two groups ("S1" and "S2").
dfex = data.frame(stringsAsFactors=FALSE,
Category = c("CatA", "CatB", "CatB", "CatC", "CatD", "CatD"),
Grouping = c("S1", "S1", "S2", "S1", "S1", "S1"),
Odds = c(2.4, 3, 2.6, 2.4, 2.4, 1.7),
CILow = c(1.3, 1.2, 1.1, 1.2, 1.1, 0.8),
CIHigh = c(4.5, 4.6, 7.9, 5, 5.9, 3.7)
)
ggplot(dfex, aes(x = Odds, y = Category)) +
geom_vline(aes(xintercept = 1), size = .25, linetype = 'dashed') +
geom_errorbarh(aes(xmax = CIHigh, xmin = CILow), size = .5, height =
.2, color = 'gray50') +
geom_point(size = 3.5) +
theme(panel.grid.minor = element_blank()) +
scale_x_continuous(breaks = seq(0,7,1) ) +
coord_trans(x = 'log10') +
ylab('') +
xlab('Odds ratio')
I'm looking for a way to including the Grouping variable so that the name ("S1" or "S2") appears and also that the different groups in CatB and CatD be slightly offset so you could see both.
Less important, is there a simple way to have CatA at the top, to match the order of the data frame, without setting a new order for the factor?
Upvotes: 1
Views: 398
Reputation: 16178
A possible way of doing is to "facet" your plot:
ggplot(dfex, aes(x = Odds, y = Grouping))+
geom_errorbarh(aes(xmax = CIHigh, xmin = CILow), size = .5, height =
.2, color = 'gray50') +
geom_point(size = 3.5) +
theme(panel.grid.minor = element_blank()) +
scale_x_continuous(breaks = seq(0,7,1) ) +
coord_trans(x = 'log10') +
ylab('') +
xlab('Odds ratio')+
facet_grid(Category~., switch = "y", scales = "free_y")+
theme(strip.placement = "outside",
strip.text.y = element_text(angle = 180),
strip.background.y = element_blank(),
panel.spacing = unit(-1, "lines"))
An alternative solution is to use interaction
to group your y values with both Category
and Grouping
.
You can also pass reorder
function in each of them if you don't want to reorder factors before the use of ggplot
:
ggplot(dfex, aes(x = Odds,
y = interaction( reorder(Category, desc(Category)), reorder(Grouping,desc(Grouping)))))+
geom_vline(aes(xintercept = 1), size = .25, linetype = 'dashed') +
geom_errorbarh(aes(xmax = CIHigh, xmin = CILow), size = .5, height =
.2, color = 'gray50') +
geom_point(size = 3.5) +
theme(panel.grid.minor = element_blank()) +
scale_x_continuous(breaks = seq(0,7,1) ) +
coord_trans(x = 'log10') +
ylab('') +
xlab('Odds ratio')
Does it answer your question ?
Update with ggplot2
v3.3.0
Minor tweaks to get the first solution working ggplot2
v3.3.0
is to replace:
strip.text.y = element_text(angle = 180),
with
strip.text.y.left = element_text(angle = 0),
Upvotes: 1