Here is my fake data:
dat1 <- structure(list(A_B = c("A", "B", "A", "B", "A", "B", "A", "B",
"A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A",
"B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B",
"A", "B", "A", "B", "A", "B"), percentage = c(49.2629769158808,
50.7370230841193, 64.4899165250794, 35.5100834749206, 59.3111128788481,
40.6888871211519, 85.3899516501997, 14.6100483498003, 80.5933773112794,
19.4066226887206, 84.3750256827502, 15.6249743172498, 62.8269574848769,
37.1730425151231, 69.5582018265724, 30.4417981734276, 56.5840999142665,
43.4159000857335, 100, 0, 67.4302746354917, 32.5697253645083,
27.3784794349813, 72.6215205650187, 58.0885854897603, 41.9114145102397,
100, 0, 89.005829015544, 10.994170984456, 57.1694599627561, 42.8305400372439,
100, 0, 54.2251244585246, 45.7748755414754, 74.4838466287125,
25.5161533712875, 74.6413724456935, 25.3586275543065), facet = c("Facet 1",
"Facet 1", "Facet 1", "Facet 1", "Facet 1", "Facet 1", "Facet 1",
"Facet 1", "Facet 1", "Facet 1", "Facet 2", "Facet 2", "Facet 2",
"Facet 2", "Facet 2", "Facet 2", "Facet 2", "Facet 2", "Facet 2",
"Facet 2", "Facet 2", "Facet 2", "Facet 1", "Facet 1", "Facet 2",
"Facet 2", "Facet 2", "Facet 2", "Facet 1", "Facet 1", "Facet 1",
"Facet 1", "Facet 2", "Facet 2", "Facet 1", "Facet 1", "Facet 1",
"Facet 1", "Facet 1", "Facet 1"), id = c(1L, 1L, 2L, 2L, 3L,
3L, 4L, 4L, 5L, 5L, 6L, 6L, 7L, 7L, 8L, 8L, 9L, 9L, 10L, 10L,
11L, 11L, 12L, 12L, 13L, 13L, 14L, 14L, 15L, 15L, 16L, 16L, 17L,
17L, 18L, 18L, 19L, 19L, 20L, 20L)), row.names = c(NA, -40L), class = c("tbl_df",
"tbl", "data.frame"))
Here is the chart:
library(ggplot2)
ggplot(dat1, aes(id, percentage, fill = factor(A_B))) +
geom_col(position = position_fill()) +
scale_fill_manual(values = c("coral", "lightblue"),
breaks=c('A', 'B'))+
coord_flip() +
facet_wrap(. ~ facet, scale= "free")+
geom_text(data = subset(dat1, percentage != 0), aes(label = sprintf("%.1f%%", percentage), group = A_B), position = position_fill(vjust=0.5), size = 5)
When attempting to vertically align text within a single line for both A and B by adjusting the vjust argument in position_fill(), I encounter difficulties achieving a uniform alignment. Using vjust=1 brings me closest to the desired outcome; however, this results in the text exceeding the boundaries. Using any other number in vjust results in a skewed formation of the percent numbers.

Using the
vjustparameter you can only position both labels at the bottom, top or center. Instead, for what you are trying to achieve I think you are better off usingposition="idenity"and setting theyposition and the horizontal alignment using anifelse. Also note that I switched togeom_labelto add some padding (I'm not a big fan of usingh/vjustfor this task (: ).