Как автоматически адаптировать количество требуемых цветов для графика geom_bar? - PullRequest
0 голосов
/ 10 января 2020

Я хотел бы сделать столбчатую диаграмму для столбца с разноцветными полосами, используя ggplot.

library(ggplot2)

set.seed(123)

df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))

ggplot(df_a, aes(A1)) +
  geom_bar(fill = c("green", "blue", "red", "yellow", "black"))  +
  scale_x_discrete(drop = FALSE)

Это прекрасно работает: enter image description here Однако в таком небольшом примере Я не могу ожидать, что все возможные числа присутствуют. Вот пример, где это имеет место:

set.seed(321)

df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))

Использование ggplot до ...

ggplot(df_a, aes(A1)) +
  geom_bar(fill = c("green", "blue", "red", "yellow", "black"))  +
  scale_x_discrete(drop = FALSE)

... выдает ошибку:

Error: Aesthetics must be either length 1 or the same as the data (3): fill

Похоже, что ожидается вектор с ровно 3 цветами, поскольку есть 3 бара для заполнения?

Почему это так?

Есть ли способ заполнения без проверки чисел первый?

И форсирование заранее определенного количества баров (даже если оно пустое)?

Редактировать:

Решение было предложено AndS.

set.seed(321)

df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))

ggplot(df_a, aes(A1)) +
  geom_bar(aes(fill = as.factor(A1)))  +
  scale_x_discrete(drop = FALSE)

В этом случае это приведет к 4 барам (включая 1 пустой столбец).

Однако, чтобы получить все 5 столбцов (включая отсутствующие столбцы), необходимо пометить данные:

set.seed(321)

df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))

df_a[[1]] <- ordered(df_a[[1]], levels = c(0:4), labels = c(0, 1, 2, 3, 4))

ggplot(df_a, aes(A1)) +
  geom_bar(aes(fill = as.factor(A1)))  +
  scale_x_discrete(drop = FALSE)

Есть ли способ избежать этого? Например, включить параметры выборки, чтобы получить количество возможных столбцов?

Количество необходимых баров:

c_a <- c(0, 1, 2, 3, 4)

df_a <- data.frame(A1 = sample(c_a, 10, replace = TRUE))

length(c_a)

edit2: Я нашел решение, которое работает для меня:

set.seed(321)

c_a <- c(0, 1, 2, 3, 4)

df_a <- data.frame(A1 = sample(c_a, 10, replace = TRUE))

df_a[[1]] <- ordered(df_a[[1]], levels = c_a, labels = as.character(c_a))

ggplot(df_a, aes(A1)) +
  geom_bar(aes(fill = as.factor(A1)))  +
  scale_x_discrete(drop = FALSE)

1 Ответ

1 голос
/ 10 января 2020

Существует разница между указанием аргумента заполнения внутри aes() вызова geom_bar или за его пределами. Получаемое сообщение об ошибке самоочевидно:

Error: Aesthetics must be either length 1 or the same as the data (3): fill
  • либо вы даете только один цвет, который будет одинаковым для всех баров (что обычно рекомендуется, если цвета не добавляют смысл сюжету). В этом случае достаточно geom_bar(fill="a color"):
df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))
ggplot(df_a, aes(A1)) +
    geom_bar(fill = c("steelblue"))
  • , либо вы задаете вектор цветов, который должен быть такой же длины данных, которые вы выводите. Это то, что предлагает комментарий @ AndS.: Если вы конвертируете A1 в коэффициент, вы получаете один уникальный цвет на значение и вектор такой же длины, что и A1. В этом случае вы должны инкапсулировать цвета как эстетику c для графика: geom_bar(aes(fill = as.factor(A1)), потому что значения заполнения соответствуют некоторым значениям данных в вашем фрейме данных (то есть, что является эстетикой в ​​ggplot):
df_a <- data.frame(A1 = sample(c(0, 1, 2, 3, 4), 10, replace = TRUE))
df_a$fill_value <- as.factor(df_a$A1)
ggplot(df_a, aes(A1)) +
    geom_bar(aes(fill = fill_value))
...