R在闪亮的应用程序中使用多个y轴

时间:2017-08-16 12:37:13

标签: r shiny plotly

我正在尝试使用情节输出创建一个闪亮的应用程序。
该图应具有多个y轴,并根据所选变量进行更新。
问题是如何在使用add_lines时如何结合闪亮的反应性和情节,目前如果我选择的变量少于add_lines代码不起作用

示例代码:

library(shiny)
library(dplyr)
library(plotly)
library(tidyr)

data <- cbind(
  seq(from = 1, to = 30, by = 1),
  sample(seq(from = 100, to = 300, by = 10), size = 30, replace = TRUE),
  sample(seq(from = 1, to = 100, by = 9), size = 30, replace = TRUE),
  sample(seq(from = 50, to = 60, by = 2), size = 30, replace = TRUE),
  sample(seq(from = 100, to = 130, by = 1), size = 30, replace = TRUE)
) %>% 
  as.data.frame()

names(data) <- c("date", "a", "b", "x", "y")

data <- data %>% gather("key", "value", 2:5)

ui <- fluidPage(
  column(
    width = 3,
    selectInput("select", "Select var:", choices = c("a", "b", "x", "y"), selected = c("a", "b", "x"), multiple = TRUE)
  ),
  column(
    width = 9
  ),
  column(
    width = 12,
    plotlyOutput("plot")
  )
)

server <-  function(input, output){

  output$plot <- renderPlotly({
    data <- data %>% filter(key %in% c("date", input$select)) %>% spread(key, value)

    plot_ly(x = ~data$date) %>%
      add_lines(y = ~data[, 2], name = input$select[1], line = list(color = "red")) %>%
      add_lines(y = ~data[, 3], name = input$select[2], line = list(color = "blue"), yaxis = "y2") %>%
      add_lines(y = ~data[, 4], name = input$select[3], line = list(color = "green"), yaxis = "y3") %>%
      layout(
        yaxis = list(
          side = "left"
        ),
        yaxis2 = list(
          side = "left",
          overlaying = "y",
          anchor = "free",
          position = 0.02
        ),
        yaxis3 = list(
          side = "left",
          overlaying = "y",
          anchor = "free",
          position = 0.04
        )
      )
  })
}

shinyApp(ui, server)

2 个答案:

答案 0 :(得分:1)

至少在大约6个月之前,我的理解(来自情节支持)是故意没有简明地处理这种有条件的情节。相反,如果你可以枚举所有绘图场景,你可以使用类似下面的内容(实际上还没有工作,需要修复代码的其他部分),每个绘图场景都有一个else if

output$plot <- renderPlotly({
data <- data %>% filter(key %in% c("date", input$select)) %>% spread(key, value)

if (input$select == c("a", "b", "x")) {
plot_ly(x = ~data$date) %>%
  add_lines(y = ~data[, 2], name = input$select[1], line = list(color = "red")) %>%
  add_lines(y = ~data[, 3], name = input$select[2], line = list(color = "blue"), yaxis = "y2") %>%
  add_lines(y = ~data[, 4], name = input$select[3], line = list(color = "green"), yaxis = "y3") %>%
  layout(
    yaxis = list(
      side = "left"
    ),
    yaxis2 = list(
      side = "left",
      overlaying = "y",
      anchor = "free",
      position = 0.02
    ),
    yaxis3 = list(
      side = "left",
      overlaying = "y",
      anchor = "free",
      position = 0.04
    )
  )
} else if (input$select == c("a", "b")) {
plot_ly(x = ~data$date) %>%
  add_lines(y = ~data[, 2], name = input$select[1], line = list(color = "red")) %>%
  add_lines(y = ~data[, 3], name = input$select[2], line = list(color = "blue"), yaxis = "y2") %>%
  layout(
    yaxis = list(
      side = "left"
    ),
    yaxis2 = list(
      side = "left",
      overlaying = "y",
      anchor = "free",
      position = 0.02
    ),
    yaxis3 = list(
      side = "left",
      overlaying = "y",
      anchor = "free",
      position = 0.04
    )
  )
    }

})

它不简洁,但如果没有大量的情景可能会有效。

您还可以通过filter电话覆盖您的数据;如果您的数据集不是很大,您可以跳过该步骤并在绘图调用之外组织数据。否则,您可能需要reactive调用之外的plot函数,该函数将从绘图功能中调用,而原始数据不会被修改。

答案 1 :(得分:1)

以下是您的解决方案:

library(shiny)
library(dplyr)
library(plotly)
library(tidyr)

data <- cbind(
  seq(from = 1, to = 30, by = 1),
  sample(seq(from = 100, to = 300, by = 10), size = 30, replace = TRUE),
  sample(seq(from = 1, to = 100, by = 9), size = 30, replace = TRUE),
  sample(seq(from = 50, to = 60, by = 2), size = 30, replace = TRUE),
  sample(seq(from = 100, to = 130, by = 1), size = 30, replace = TRUE)
) %>% 
  as.data.frame()

names(data) <- c("date", "a", "b", "x", "y")

data <- data %>% gather("key", "value", 2:5)

ui <- fluidPage(
  column(
    width = 3,
    selectInput("select", "Select var:", choices = c("a", "b", "x", "y"), selected = c("a", "b", "x"), multiple = TRUE)
  ),
  column(
    width = 9
  ),
  column(
    width = 12,
    plotlyOutput("plot")
  )
)

server <-  function(input, output){

  output$plot <- renderPlotly({
    data <- data %>% filter(key %in% c("date", input$select)) 

    plot_ly(data, x = ~date, y=~value, color=~key) %>%
      layout(
        yaxis = list(
          side = "left"
        ),
        yaxis2 = list(
          side = "left",
          overlaying = "y",
          anchor = "free",
          position = 0.02
        ),
        yaxis3 = list(
          side = "left",
          overlaying = "y",
          anchor = "free",
          position = 0.04
        )
      )
  })
}

shinyApp(ui, server)

这很容易,您不应该spread数据集,而是使用长格式,您可以在plotly中设置参数color=,它将根据设置变量直接对数据进行分组:

plot_ly(data, x = ~date, y=~value, color=~key)