Почему этот код статически неверен в ggplot, чтобы получить процент по оси y?

#r #ggplot2 #dplyr #percentage #geom-bar

#r #ggplot2 #dplyr #процент #геометрическая шкала

Вопрос:

У меня есть эти данные, и я хочу получить процент по оси y.

 structure(list(sb_1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L, 2L), .Label = c("0", "x"), class = "factor"), 
    sb_2 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L), .Label = "0", class = "factor"), sb_3 = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "b", class = "factor"), 
    sb_4 = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L), .Label = c("0", "c"), class = "factor"), wave = structure(c(1L, 
    2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), .Label = c("h", 
    "j"), class = "factor")), row.names = c(NA, 12L), class = "data.frame")
 

Этот код я использовал:

 nn%>%
  pivot_longer(cols = starts_with("sb_")) %>%
  filter(value != 0) %>%
  unite(sb_, name, value) %>%
  group_by(wave) %>%
  mutate(wave_total = n()) %>%
  group_by(sb_, .add = TRUE) %>%
  mutate(sb_pct = 100 * n() / wave_total) %>%
  ggplot(aes(x = factor(sb_, levels = str_sort(unique(sb_), numeric = TRUE)), y = sb_pct))  
    geom_bar(aes(fill = wave), stat = "identity", position = position_dodge(preserve = "single"))  
    xlab("sb")  
    ylab("percent")
 

И результат таков :
![1]

И результат должен быть другим, потому что, например, для первого столбца не было нуля, и все это результат.

   sb_1 sb_2 sb_3 sb_4 wave
1     0    0    b    0    h
2     0    0    b    0    j
3     0    0    b    0    h
4     0    0    b    c    j
5     0    0    b    c    h
6     0    0    b    c    j
7     x    0    b    c    h
8     x    0    b    c    j
9     x    0    b    c    h
10    x    0    b    c    j
11    x    0    b    c    h
12    x    0    b    c    j
 

Поэтому, пожалуйста, помогите мне, почему это неправильно?

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

1. Я не вижу ошибки. Можете ли вы вручную нарисовать ожидаемый результат? Вы должны отделить этап создания данных от этапа построения графика вместо того, чтобы объединять их прямо сейчас, например, создать nn_long , который включает mutate(x = factor(sb_, levels = str_sort(unique(sb_), numeric = TRUE))) , затем построить этот фрейм данных

2. Как вы видите в sb_3, у нас есть все вхождения, поэтому на графике у нас должно быть 100% в столбцах, в то время как текущий показывает около 50%, и оба должны быть одинаковыми. Я не думаю, что такое разделение приводит к каким-либо различиям.

Ответ №1:

Я не могу сказать, почему ваш код неверен, но я попробовал другой способ, и, похоже, он работает так, как ожидалось:

 n <- structure(list(sb_1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L, 2L), .Label = c("0", "x"), class = "factor"), 
    sb_2 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L), .Label = "0", class = "factor"), sb_3 = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "b", class = "factor"), 
    sb_4 = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L), .Label = c("0", "c"), class = "factor"), wave = structure(c(1L, 
    2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), .Label = c("h", 
    "j"), class = "factor")), row.names = c(NA, 12L), class = "data.frame")

n <- pivot_longer(n, cols = starts_with("sb_"))
n$wave_and_name <- as.factor(paste(n$wave,n$name, sep="_"))
n <- as.data.frame(table(filter(n, value != 0)$wave_and_name) / table(n$wave_and_name) * 100)
n$wave <- substr(n$Var1, 1, 1)
n$name <- substr(n$Var1, 3, 6)

ggplot(n, aes(x=name, y=Freq))  
  geom_bar(aes(fill = wave), stat="identity",position = position_dodge())  
  xlab("sb")   
  ylab("percent")

 

график

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

1. Это было идеально