Как построить сгруппированные бары, не начиная с нуля? - PullRequest
0 голосов
/ 25 марта 2019

У меня есть следующий фрейм данных

unit <- c("a", "b", "c", "d")
top1990 <- c(100, 80, 70, 90)
base1990 <- c(40, 60, 20, 30)
top2000 <- c(120, 85, 65, 80)
base2000 <- c(40, 65, 25, 15)
df <- data.frame(unit, top1990, base1990, top2000, base2000)

unit top1990 base1990 top2000 base2000
a     100       40     120       40
b      80       60      85       65
c      70       20      65       25
d      90       30      80       15

Мне нужно построить на одном графике для каждого блока два бара, один для 1990 года и другой для 2000 года. Каждый столбец должен начинаться со значения "base ***" и заканчиваться на значение "топ ****". Мне также нужно упорядочить единицы по «top1990» (по убыванию).

Я использовал функцию geom_segment библиотеки ggplot2 следующим образом

df$unit <- factor(df$unit, levels = df$unit[order(df$top1990, decreasing = T)])    

ggplot(data = df) + geom_segment(aes(x=df$unit, xend=df$unit, y=df$top1990, yend=df$base1990), size = 7, color = "blue") +
geom_segment(aes(x=df$unit, xend=df$unit, y=df$top2000, yend=df$base2000), size = 7, color = "red")

Тем не менее, я получил этот , в котором столбцы перекрываются, поэтому мне они понадобятся бок о бок.

enter image description here

Чего мне не хватает?

1 Ответ

3 голосов
/ 26 марта 2019

Я думаю, что необходимо сначала преобразовать ваши данные.Я предлагаю {cdata} для ваших нужд трансформации.Я думаю, что вы хотите geom_linerange() с более толстым размером, чтобы они выглядели как коробки.

unit <- c("a", "b", "c", "d")
top1990 <- c(100, 80, 70, 90)
base1990 <- c(40, 60, 20, 30)
top2000 <- c(120, 85, 65, 80)
base2000 <- c(40, 65, 25, 15)

df <- data.frame(unit, top1990, base1990, top2000, base2000)

library(cdata)
library(ggplot2)

control_table <- 
  qchar_frame(
    year, base      , top       |
    1990, "base1990", "top1990" |
    2000, "base2000", "top2000" 
  )

df_2 <- 
  rowrecs_to_blocks(
    df, controlTable = control_table,
    controlTableKeys = "year",
    columnsToCopy = "unit"
  )

df_2 %>% 
  ggplot(aes(unit, ymin = base, ymax = top, color = year)) +
  geom_linerange(position = position_dodge(width = 1), size = 20)

С {cdata} я преобразовал ваши данные в эту форму

  unit year base top
1    a 1990   40 100
2    a 2000   40 120
3    b 1990   60  80
4    b 2000   65  85
5    c 1990   20  70
6    c 2000   25  65
7    d 1990   30  90
8    d 2000   15  80

Теперь мы можем использовать base в качестве ymin и top в качестве ymax в качестве эстетики для geom_linerange().

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

Base to Top with a Thick LineRange

Надеюсь, это поможет.

...