контролировать ширину баров в ggplot2 [дубликат]

Когда вы конвертируете .1 или 1/10 в base 2 (двоичный), вы получаете повторяющийся шаблон после десятичной точки, точно так же, как пытаетесь представить 1/3 в базе 10. Значение не является точным, и поэтому вы можете 't делать точную математику с ней, используя обычные методы с плавающей запятой.

37
задан tcash21 2 May 2016 в 03:58
поделиться

3 ответа

Самый простой способ - дополнить свой набор данных так, чтобы каждая комбинация присутствовала, даже если она имеет NA в качестве ее значения. Взяв более простой пример (поскольку у вас много ненужных функций):

dat <- data.frame(a=rep(LETTERS[1:3],3),
                  b=rep(letters[1:3],each=3),
                  v=1:9)[-2,]

ggplot(dat, aes(x=a, y=v, colour=b)) +
  geom_bar(aes(fill=b), stat="identity", position="dodge")

enter image description here [/g0]

Это показывает поведение, которое вы пытаетесь избежать: в группы «В», нет группы «а», поэтому полосы шире. Дополнение dat с фреймворком данных со всеми комбинациями a и b:

dat.all <- rbind(dat, cbind(expand.grid(a=levels(dat$a), b=levels(dat$b)), v=NA))

ggplot(dat.all, aes(x=a, y=v, colour=b)) +
  geom_bar(aes(fill=b), stat="identity", position="dodge")  

enter image description here [/g1]

26
ответ дан Brian Diggs 26 August 2018 в 00:27
поделиться

Некоторые новые опции для position_dodge() и новых position_dodge2(), введенные в ggplot2 3.0.0, могут помочь.

Вы можете использовать preserve = "single" в position_dodge(), чтобы установить ширину с одного Элемент, поэтому ширина всех полос будет одинаковой.

ggplot(data = d, aes(x = Month, y = Quota, color = "Quota")) + 
     geom_line(size = 1) + 
     geom_col(data = d[c(-1:-5),], aes(y = Sepal.Width, fill = Species), 
              position = position_dodge(preserve = "single") ) + 
     scale_fill_manual(values = colours)

[/g0]

Использование position_dodge2() изменяет способ центровки по центру, центрируя каждый набор баров в каждом месте оси x. У него есть padding, поэтому используйте padding = 0 для удаления.

ggplot(data = d, aes(x = Month, y = Quota, color = "Quota")) + 
     geom_line(size = 1) + 
     geom_col(data = d[c(-1:-5),], aes(y = Sepal.Width, fill = Species), 
              position = position_dodge2(preserve = "single", padding = 0) ) + 
     scale_fill_manual(values = colours)

[/g1]

1
ответ дан aosmith 26 August 2018 в 00:27
поделиться

У меня была та же проблема, но я искал решение, которое работает с трубой (%>%). Использование tidyr::spread и tidyr::gather из tidyverse делает трюк. Я использую те же данные, что и @Brian Diggs, но с именами переменных верхнего регистра, которые не имеют двойных имен переменных при преобразовании в wide:

library(tidyverse)

dat <- data.frame(A = rep(LETTERS[1:3], 3),
                  B = rep(letters[1:3], each = 3),
                  V = 1:9)[-2, ]
dat %>% 
  spread(key = B, value = V, fill = NA) %>% # turn data to wide, using fill = NA to generate missing values
  gather(key = B, value = V, -A) %>% # go back to long, with the missings
  ggplot(aes(x = A, y = V, fill = B)) +
  geom_col(position = position_dodge())

Edit:

еще более простое решение этой проблемы в сочетании с трубой. Использовать tidyr::complete дает тот же результат в одной строке:

dat %>% 
  complete(A, B) %>% 
  ggplot(aes(x = A, y = V, fill = B)) +
  geom_col(position = position_dodge())
10
ответ дан Tino 26 August 2018 в 00:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: