ggplot: показать количество каждой ячейки с включенными классами

#r #ggplot2

#r #ggplot2

Вопрос:

Я пытаюсь построить гистограмму с общим количеством каждой ячейки сверху. Ниже приведены мои данные: введите описание изображения здесь

Вы можете использовать следующие примеры данных:

 histData <- data.frame("UserId" = 1:20, "age" = c(replicate(20,sample(10:20,20,rep=TRUE))), "Gender" = c("Male", "Female"))
 

Я использую ggplot, как показано ниже:

 ggplot(histData, aes(x = age, color = Gender, fill = Gender))  
  geom_histogram(binwidth = 1,
                 alpha = 0.2,
                 position = "identity", aes(y = 100*(..count..)/sum(..count..)))  
  scale_color_manual(values = rainbow(3))  
  geom_vline(
    aes(xintercept = mean(age)),
    color = "black",
    linetype = "dashed",
    size = 1
  )  
  labs(title = "Age histogram plot", x = "Age", y = "Percentage")  
  theme_minimal()   theme(plot.title = element_text(hjust = 0.5)) 
  stat_bin(aes(y=round(100*(..count..)/sum(..count..),1), label=round(100*(..count..)/sum(..count..),1)), geom="text", vjust=0, binwidth = 1) 
 

в результате получается график, как показано ниже:
введите описание изображения здесь

На графике количество для каждого пола отображается отдельно, в верхней части соответствующих ячеек. Тем не менее, я не хочу, чтобы количество зависело от пола, я просто хочу общее количество поверх стеков ячеек (т. Е. Мне просто нужны красные цифры, которые указывают общее количество). Как мне добиться этого, имея aes(x = age, color = Gender, fill = Gender) эстетику в моем ggplot2 для классов пола?

РЕДАКТИРОВАТЬ: основываясь на приведенном ниже ответе, попробовал следующее

 ageGroupCount <- histData[, -1]
ageGroupCount$age <- as.integer(df$age)
ageGroupCount$Gender <- as.factor(df$Gender)
ageGroupCount <-
  ageGroupCount %>%  group_by(age, Gender) %>% count()

ageCount <- histData[2] %>% count()

ageGroupCount %>%
  ggplot(aes(x = age, y = freq, label = freq))  
  geom_col(aes(fill = Gender, color = Gender), alpha = 0.65)  
  scale_y_continuous(labels = percent)  
  geom_text(
    data = ageCount,
    size = 3,
    position = position_dodge(width = 1),
    vjust = -0.5
  )   geom_vline(
    aes(xintercept = mean(age)),
    color = "black",
    linetype = "dashed",
    size = 1
  )   scale_color_manual(values = rainbow(3))  
  labs(title = "Age histogram plot", x = "Age", y = "Percentage")  
  theme_minimal()   theme(plot.title = element_text(hjust = 0.5))
 

что привело к следующему графику:
введите описание изображения здесь
Как мне избавиться от конечных нулей в шкале и как мне выставить процентные значения в верхней части каждого столбца вместо абсолютных чисел?

ОТВЕТ: Я смог сделать это, используя приведенный ниже код

 ageGroupCount <- histData[, -1]
ageGroupCount$age <- as.integer(ageGroupCount$age)
ageGroupCount$Gender <- as.factor(ageGroupCount$Gender)
ageGroupCount <-
  ageGroupCount %>%  group_by(age, Gender) %>% count()
ageGroupCount <- mutate(ageGroupCount, freq = round(100*freq / sum(freq),1))

ageCount <- histData[2] %>% count()
ageCount$age <- as.integer(ageCount$age)
ageCount <- mutate(ageCount, freq = round(100*freq / sum(freq),1))

ageGroupCount %>%
  ggplot(aes(x = age, y = freq, label = freq))  
  geom_col(aes(fill = Gender, color = Gender), alpha = 0.65)  
  geom_text(
    data = ageCount,
    size = 3,
    position = position_dodge(width = 1),
    vjust = -0.5
  )   geom_vline(
    aes(xintercept = mean(age)),
    color = "black",
    linetype = "dashed",
    size = 1
  )   scale_color_manual(values = rainbow(3))  
  scale_y_continuous(labels = function(x) paste0(x, "%")) 
  labs(title = "Age histogram plot", x = "Age", y = "Percentage")  
  theme_minimal()   theme(plot.title = element_text(hjust = 0.5))
 

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

Ответ №1:

Хорошо, сначала давайте немного упростим это, получив сводный фрейм данных с подсчетами по возрасту и полу.

 df <-
  histData %>% 
  group_by(age, Gender) %>% 
  count()

df
# A tibble: 22 x 3
# Groups:   age, Gender [22]
     age Gender     n
   <int> <fct>  <int>
 1    10 Female    20
 2    10 Male      22
 3    11 Female    22
...
 

Тогда мы можем использовать geom_col для прямого отображения результатов вместо того geom_histogram , чтобы вычислять их с большим количеством неприятного синтаксиса. Текстовые метки поступают из второй операции группирования / подсчета, используя гендерные числа в качестве весов:

 df %>% 
  ggplot(aes(x = age, y = n))  
  geom_col(aes(fill = Gender))  
  geom_text(
    data = . %>% group_by(age) %>% count(wt = n),
    aes(y = n   2, label = n)
  )
 

график ggplot

Это позволяет выполнить основную часть графика — похоже, вы сможете обрабатывать форматирование и другие дополнения отсюда.

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

1. У меня это не работает. df <- histData[,-1] %>% group_by(age, Gender) %>% count() df %>% ggplot(aes(x = age, y = freq)) geom_col(aes(fill = Gender)) geom_text( data = . %>% group_by(age) %>% count(wt = freq), aes(y = freq 2, label = freq) )

2. Выдает ошибку, которая Error in count(., wt = freq) : object 'freq' not found

3. мой df содержит имя последнего столбца как freq вместо n, поэтому заменил его.

4. df%>% group_by(age) %>% count(wt = freq) выдает эту ошибку

5. как мне использовать% масштаб по оси y? scale_y_continuous(labels = scales::percent) показывает странные и неправильные значения.