penso che l'approccio aspetto va bene:
library(ggplot2)
library(gtable)
library(grid)
df <- data.frame(main.cat = c("A", "A", "B", "B", "B", "C"),
second.cat = c("a1", "a2", "b1", "b2", "b3", "c1"),
value = c(2, 3, 4, 2.5, 1.5, 2.3))
p = ggplot(data = df, aes(x = second.cat, y = value)) +
geom_point() + facet_grid(.~main.cat, space = "free_x", scales = "free_x") +
theme(strip.background = element_rect(fill = NA))
Ma se si vuole qualcosa di più vicino alla excel guardare, un approccio è quello di utilizzare gtable
funzioni per estrarre la striscia e inserirla sotto le etichette di segno di spunta, quindi inserire alcune linee di confine tra le categorie principali. Tieni presente che il codice riportato sotto è specifico per i tuoi dati di esempio.
p = p + theme(panel.spacing = unit(0, "lines"))
g = ggplotGrob(p)
gtable_show_layout(g) # to see the layout
# Add a row below the x-axis tick mark labels,
# the same height as the strip
g = gtable_add_rows(g, g$height[6], 8)
# Get the strip grob
stripGrob = gtable_filter(g, "strip")
# Insert the strip grob into the new row
g = gtable_add_grob(g, stripGrob, 9, 4, 9, 8)
# remove the old strip
g = g[-6, ]
# Insert line grobs as boundary lines between major categories
linesGrob = linesGrob(gp = gpar(col = "grey75"))
for(i in c(5,7)) g = gtable_add_grob(g, linesGrob, t=7, l=i, b=8, r=i)
# Insert new columns of zero width to take the line grobs for the first and last boundary lines
for(i in c(3, 9)) {
g = gtable_add_cols(g, unit(0, "lines"), i)
g = gtable_add_grob(g, linesGrob, t=7, l=i+1, b=8, r=i+1)
}
grid.newpage()
grid.draw(g)
Modifica Un tentativo di greggio a generalizzare
library(ggplot2)
library(gtable)
library(grid)
df <- data.frame(main.cat = c("A", "A", "B", "B", "C", "D"),
second.cat = c("a1", "a2", "b1", "b2", "c1", "d1"),
value = c(2, 3, 4, 2.5, 1.5, 2.3))
p = ggplot(data = df, aes(x = second.cat, y = value)) +
geom_point() + facet_grid(.~main.cat, space = "free_x", scales = "free_x") +
theme(strip.background = element_rect(fill = NA))
p = p + theme(panel.spacing = unit(0, "lines"))
g = ggplotGrob(p)
gtable_show_layout(g) # to see the layout
# Get the indices for the panels (t=top, l=left, ...
panels <- c(subset(g$layout, grepl("panel", g$layout$name), se=t:r))
# Get the strip grob
stripGrob = gtable_filter(g, "strip")
# Its height is
height = stripGrob$height
# Add a row below the x-axis tick mark labels,
# the same height as the strip.
g = gtable_add_rows(g, height, unique(panels$b+1))
# Insert the strip grob into the new row
g = gtable_add_grob(g, stripGrob,
t = unique(panels$b+2),
l = min(panels$l),
r = max(panels$r))
# Insert line grobs as boundary lines between major categories
linesGrob = linesGrob(gp = gpar(col = "grey75"))
panelsR = panels$r[-length(panels$r)]
for(i in panelsR+1) g = gtable_add_grob(g, linesGrob,
t=unique(panels$b+1),
l=i,
b=unique(panels$b+2))
# Insert new columns of zero width to take the line grobs for the first and last boundary lines
panelBound = c(3, max(panels$r)+1)
for(i in panelBound) {
g = gtable_add_cols(g, unit(0, "lines"), i)
g = gtable_add_grob(g, linesGrob,
t=unique(panels$b+1),
l=i+1,
b=unique(panels$b+2))
}
# remove the old strip
g = g[-6, ]
# Draw it
grid.newpage()
grid.draw(g)
La seconda versione è esattamente ciò che volevo, grazie. Non ho familiarità con il pacchetto Gtable quindi ho evidentemente bisogno di un po 'di lettura per capire come generalizzare questo per gestire diversi gruppi di categorie! –
Baptiste ha preparato alcune note sulle funzioni di 'gtable', disponibili su [https://github.com/baptiste/gtable/wiki/Description](https://github.com/baptiste/gtable/wiki/Description) –
Vedi la modifica - un tentativo grossolano di generalizzazione. –