闪亮的应用程序中绘图中任意数量的垂直线

时间:2018-11-14 11:40:55

标签: r ggplot2 shiny

我有一个很好的用ggplot完成的绘图功能,它还内置了用于绘制垂直线的功能,这些是我较大的Shiny应用程序的一部分。我试图为我的问题做一个最小的可复制的例子。在这里:

library(shiny)
library(ggplot2)

ui <- fluidPage(
  fluidRow(
    column(6, offset=1,
           plotOutput("plot", width="100%", height="500px")
    )
  ),
  fluidRow(
    column(2, offset=1,
           actionButton(inputId="go", label="Plot")
    ),
    column(2, offset=1,
           selectInput(inputId="number", label="Number of lines:",
                       choices=list("No lines"="0",
                                    "One line"="1",
                                    "Two lines"="2",
                                    "Three lines"="3"))
    )
  ),
  fluidRow(
    uiOutput("dynamic")
  )
)

server <- function(input, output, session) {

  # Function for n number of input boxes for
  # vertical line interception points in UI
  vertical_line_UI <- function(n) {
    fluidRow(
      column(4, offset=1,
             numericInput(inputId=sprintf("line%s", n),
                          label=sprintf("Line%s:", n),
                          value=5))
    )
  }

  # Rendering above in UI
  output$dynamic = renderUI({
    if (as.integer(input$number) > 0) {
      lapply(1:as.integer(input$number), vertical_line_UI)
    }
  })

  # Vertical line interception points
  lines <- eventReactive(input$go, {
    if (as.integer(input$number) > 0 ) {
      c(input$line1, input$line2, input$line3)
    } else {
      NULL
    }
  })

  # Plot function
  plot_function <- function(data, lines=NULL) {
    p <- ggplot(data=data.frame(x=1:10, y=1:10),
                aes(x=x, y=y)) + geom_line() + theme_bw()
    if (!is.null(lines)) {
      for (n in 1:length(lines)) {
        p <- p + geom_vline(xintercept=lines[n])
      }
    }
    return(p)
  }

  # Rendering plot
  plot <- eventReactive(input$go, {
    plot_function(lines=lines())
  })

  output$plot <- renderPlot({
    plot()
  })

}

shinyApp(ui = ui, server = server)

相对于为N条垂直线手动编写c(input$line1, input$line2, input$line3, ..., input$lineN),我想做的是一种更好的方法。无论如何,我可能会将其上限设置为10-15。

所以我想我的问题可以缩小到如何表达

  lines <- eventReactive(input$go, {
    if (as.integer(input$number) > 0 ) {
      c(input$line1, input$line2, input$line3)
    } else {
      NULL
    }
  })

以更流畅的方式输入N个输入,而不是手动写下每个输入。如果我有5条垂直线,我将只有5个输入变量,等等。

0 个答案:

没有答案