ggvis layer_bars и layer_lines на другой оси Y

Я хотел бы создать график с категориальными значениями х и линиями и полосами.

Пример данных выглядит следующим образом:

dataWide <- iris %>%
  group_by(Species) %>%
  summarize(sl = mean(Sepal.Length),
            sw = mean(Sepal.Width),
            pl = mean(Petal.Length),
            pw = mean(Petal.Width))

# Source: local data frame [3 x 5]
# 
# Species    sl    sw    pl    pw
# 1     setosa 5.006 3.428 1.462 0.246
# 2 versicolor 5.936 2.770 4.260 1.326
# 3  virginica 6.588 2.974 5.552 2.026

Я хочу иметь:

  1. setosa, versicolor и virginica на оси абсцисс. три линии, представляющие sl, sw и pl, т.е. layer_lines с stroke = ~Species
  2. layer_bars в другом масштабе, с меткой оси справа.

У меня проблемы с объединением различных функций. Вот моя неудачная попытка:

library(ggvis)
library(tidyr)
library(dplyr)

long <- dataWide %>%
  select(Species, sl, sw, pl) %>%
  gather(variable, value, sl : pl)

longPw <- dataWide %>% select(Species, pw) %>%
  gather(variable, value, pw)

long %>%
  ggvis(x = ~Species, y = ~value, stroke = ~variable) %>%
  layer_lines() %>%
  add_axis("y", "ypw", orient = "right", title = "PW", grid = F) %>%
  layer_bars(x = ~Species, y = ~value, data = longPw, scale = "ypw")

1 ответ

Вы можете сделать это только с помощью следующего кода, и, как вы увидите, есть ограничение, решение которого, к сожалению, не существует:

Прежде всего, чтобы это работало, вам нужно использовать ТОЛЬКО один набор данных, который будет содержать всю необходимую вам информацию. Затем вы используете следующий код:

Подготовка данных

dataWide <- iris %>%
  group_by(Species) %>%
  summarize(sl = mean(Sepal.Length),
            sw = mean(Sepal.Width),
            pl = mean(Petal.Length),
            pw = mean(Petal.Width))

library(ggvis)
library(tidyr)
library(dplyr)
long <- dataWide %>%
  select(Species, sl, sw, pl) %>%
  gather(variable, value, sl : pl)

longPw <- dataWide %>% select(Species, pw) %>%
  gather(variable, value, pw)

Иметь всю информацию, необходимую для построения графика, только в одном наборе данных, т.е. dataWide2:

dataWide2 <- cbind(dataWide, longPw[2:3]) 

Решение

dataWide2 %>%
  #start with barchart
  ggvis(x = ~Species, y = ~value) %>%
  layer_bars(opacity := 0.4) %>%

  #details for right axis i.e. the bars
  add_axis("y", orient = "right", title = "My bars" ,title_offset = 50) %>% 

  #details for left axis i.e. the lines + plotting of lines 
  add_axis("y", 'ylines' , orient = "left", title= "My lines" , grid=F ) %>%
  layer_lines(stroke := 'red',   prop('y', ~sl, scale='ylines')) %>%
  layer_lines(stroke := 'blue',  prop('y', ~sw, scale='ylines')) %>%
  layer_lines(stroke := 'green', prop('y', ~pl, scale='ylines')) 

Несколько слов для приведенного выше кода:

  • Прежде всего, вам нужно начать с диаграммой. Я не знаю, почему это происходит, но обратное приведет к ошибке.
  • Во-вторых, вам нужно создавать строки отдельно, так как вы используете один набор данных и устанавливаете цвета по отдельности.

ограничение

Как вы можете видеть на графике ниже гистограммы, линии не выровнены, что, к сожалению, пока невозможно исправить (по крайней мере, насколько мне известно - см. "Редактирование" ниже). Это ограничение на самом деле является причиной, по которой я сделал учетную запись переполнения стека. Если вы проверите мой профиль, это мой единственный вопрос.

Надеюсь, поможет:)

РЕДАКТИРОВАТЬ

Я не знаю, является ли это сообщение причиной сообщения об ошибке на ggvis на странице github, но несколько часов назад об этом сообщалось как об ошибке.

ОБНОВИТЬ

После небольшого исследования и взлома я нашел обходной путь, который выглядит следующим образом:

dataWide2 %>%
  #start with barchart
  ggvis(x = ~as.numeric(Species), y = ~value) %>%
  layer_bars(opacity := 0.4) %>%

  #add the initial x axis in order to set x labes to blank
  add_axis('x', title='Species', properties = axis_props(labels=list(fill='blank'))) %>%


  #details for right axis i.e. the bars
  add_axis("y", orient = "right", title = "My bars" ,title_offset = 50) %>% 

  #details for left axis i.e. the lines + plotting of lines 
  add_axis("y", 'ylines' , orient = "left", title= "My lines" , grid=F ) %>%
  layer_lines(stroke := 'red',   prop('y', ~sl, scale='ylines')) %>%
  layer_lines(stroke := 'blue',  prop('y', ~sw, scale='ylines')) %>%
  layer_lines(stroke := 'green', prop('y', ~pl, scale='ylines')) %>%

  #add new axis which will be for our categorical x axis
  add_axis('x', 'myx2', orient='bottom', title='') %>%

  #add categorical data and make lines invisible (we only need the categories anyway)
  layer_lines(prop("x", ~ Species, scale = "myx2"), stroke := 'blank') 

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

Выход:

Я полагаю, вы могли бы установить grid=F и удалите некоторые галочки, которые вы не хотите, но это настолько хорошо, насколько это возможно. Надеюсь, поможет!

PS вы можете контролировать ширину баров с помощью width аргумент в layer_bars,

Другие вопросы по тегам