Аннотируйте столбиковую диаграмму в процентах в середине каждого класса, ggplot

#r #ggplot2 #bar-chart #tidyverse

Вопрос:

У меня есть эти данные:

 structure(list(filter = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L), .Label = c("no filtering, (523)", 
"p3 <= 2 mm, (421)", "p3 <= 5 mm, (384)", "p3 <= 10 mm, (337)"
), class = "factor"), conti = c("False Negative", "False Positive", 
"True Negative", "True Positive", "False Negative", "False Positive", 
"True Negative", "True Positive", "False Negative", "False Positive", 
"True Negative", "True Positive", "False Negative", "False Positive", 
"True Negative", "True Positive"), n = c(26L, 476L, 47L, 497L, 
15L, 173L, 248L, 406L, 23L, 102L, 282L, 361L, 33L, 68L, 269L, 
304L), share = c(0.0248565965583174, 0.455066921606119, 0.0449330783938815, 
0.475143403441683, 0.0178147268408551, 0.205463182897862, 0.294536817102138, 
0.482185273159145, 0.0299479166666667, 0.1328125, 0.3671875, 
0.470052083333333, 0.0489614243323442, 0.100890207715134, 0.399109792284866, 
0.451038575667656)), row.names = c(NA, -16L), groups = structure(list(
    filter = structure(1:4, .Label = c("no filtering, (523)", 
    "p3 <= 2 mm, (421)", "p3 <= 5 mm, (384)", "p3 <= 10 mm, (337)"
    ), class = "factor"), .rows = structure(list(1:4, 5:8, 9:12, 
        13:16), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = c(NA, 4L), class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))
 

который со следующим кодом создает эту «столбчатую диаграмму в процентах».:

 ggplot(contis)  
  geom_bar(
    aes(
      y = filter,
      x = n,
      fill = conti
    ),
    stat = "identity",
    position = "fill"
  )  
  geom_text(
    aes(
      x = share,
      y = filter,
      label = round(share, 2)
    )
  )
 

введите описание изображения здесь

Теперь аннотации совершенно неверны, и я немного теряюсь, как я мог этого достичь.
Я бы хотел, чтобы доля каждого класса была примерно (для очень маленьких это невозможно) посередине.

Ответ №1:

Для добавления меток на гистограммы необходимо задать правильный position аргумент, как geom_bar или geom_col использовать position="stack" по умолчанию, в то время как geom_text использует position="identity" :

Следовательно, чтобы сложить метки, добавьте position = position_stack() их в geom_text. Дополнительно для размещения этикеток в середине полосок используйте vjust = .5 . Наконец, вы должны рассказать ggplot о группировке, которая в вашем случае является отображаемой переменной fill . С этой целью добавьте group=conti :

 library(ggplot2)
ggplot(contis)  
  geom_bar(
    aes(
      y = filter,
      x = n,
      fill = conti
    ),
    stat = "identity",
    position = "fill"
  )  
  geom_text(
    aes(
      x = share,
      y = filter,
      label = round(share, 2),
      group = conti,
    ),
    position = position_stack(vjust = .5)
  )
 

Тем не менее, вы могли бы немного упростить свой код, установив эстетику внутри ggplot() , например:

 ggplot(contis, aes(share, filter, fill = conti))  
  geom_col()  
  geom_text(aes(label = round(share, 2)), position = position_stack(vjust = .5))
 

Комментарии:

1. Большое вам спасибо!! Я редко использую position аргумент -, так как я не на 100 % осознаю его значение. Но я, конечно, постараюсь прочитать о том, что это на самом деле делает