我有一个很好的用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个输入变量,等等。