r语言 - 在导航栏页面的选项卡中跨选项卡重用 ouputs$xxx



我对Shiny相当陌生 - 特别是如何使代码紧凑并避免重复。 为了简化我的问题(下面的代码(:我想使用导航栏页面,因为我喜欢它给出的概述。

在每个选项卡中,我想在主面板中显示一个绘图,这取决于来自侧面板的输入,而侧面板又取决于选项卡。但是由于现在允许在多个地方调用相同的输出,这会导致重复,如下面的代码所示。

所以我的问题是,在仍然使用选项卡的情况下,解决这个问题的方法是什么。 非常感谢您的帮助和新年快乐!

#test
library(shiny)
plot_fun_helper <- function(x,y){
plot(x,y, type = 'l')
}
#function that returns the x- and y vektors for plotting, not important.
xy_dens_gen <- function(tab, input){
if(tab == "Normal"){
#if normal, plot around mean, pm 3 std
x <- seq(from = input$normal_mean - 3*input$normal_std, 
to = input$normal_mean + 3*input$normal_std,
length.out = 1e3)
y <- dnorm(x, mean = input$normal_mean, sd = input$normal_std)
}
else if(tab == "LogNormal"){
#if LogNormal, plot from 0 to 3*CV
x <- seq(from = 0, 
to = 3*input$lognormal_CV,
length.out = 1e3)
y <- dlnorm(x, meanlog = 0, sdlog = 1)
}
else if(tab =="Exponential"){
x <- seq(from = 0,
to = 3/input$exp_rate,
length.out = 1e3)
y <- dexp(x, rate = input$exp_rate)
}
else stop("No method found")
return(list(x = x,
y = y))
}

# Define UI for application that draws the pdf
ui <- 
navbarPage(
title = 'reprex', id = "cur_tab", selected = 'Normal',
# Normal Tab ----
navbarMenu("Normal/LogNormal",
tabPanel("Normal",
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "normal_mean", "Choose mean", value = 1, min = -2 , max = 2),
sliderInput(inputId = "normal_std" , "Choose std" , value = 1, min = 0 , max = 2)
),
mainPanel(
plotOutput("plot_normal")
)
)
),
tabPanel("LogNormal",
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "lognormal_CV", "Choose CV", value = 1, min = 0 , max = 20)
),
mainPanel(
plotOutput("plot_LogNormal")
)
)
)
),
# exponential Tab 
tabPanel('Exponential',       
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "exp_rate", "Choose rate", value = 1, min = 0, max = 10)
),
mainPanel(
plotOutput("plot_exp")
)
)
)
)

# Define server logic required to draw pdf
server <- function(input, output) {
rvals <- reactiveValues()
observe({
rvals$x <- xy_dens_gen(tab = input$cur_tab, input = input)$x
rvals$y <- xy_dens_gen(tab = input$cur_tab, input = input)$y
})

#Render print inside renderPLot
output$plot_normal <- renderPlot({
plot_fun_helper(x = rvals$x, y = rvals$y)
})
output$plot_LogNormal <- renderPlot({
plot_fun_helper(x = rvals$x, y = rvals$y)
})
output$plot_exp <- renderPlot({
plot_fun_helper(x = rvals$x, y = rvals$y)
})

}
# Run the application 
shinyApp(ui = ui, server = server)

据我所知,没有。不同的选项卡需要不同的输出 ID。也许,你可以用一个闪亮的模块来掩盖这一事实,但在某个地方,在某种程度上,你将分配给 3 个不同的输出。

官方的答案是使用模块。半官方的答案,从模块还不存在的时候开始,是在一次调用中定义多个输出,例如:

output$plot_normal <- output$plot_LogNormal <- output$plot_exp <-  renderPlot({
plot_fun_helper(x = rvals$x, y = rvals$y)
})

请注意,这只会帮助您减少服务器部分中的重复项。在UI中,您仍然需要定义三个不同的绘图。此外,它可能无法与服务器部分的 renderUI 语句一起使用。

下面是代码的工作示例:

#test
library(shiny)
plot_fun_helper <- function(x,y){
plot(x,y, type = 'l')
}
#function that returns the x- and y vektors for plotting, not important.
xy_dens_gen <- function(tab, input){
if(tab == "Normal"){
#if normal, plot around mean, pm 3 std
x <- seq(from = input$normal_mean - 3*input$normal_std, 
to = input$normal_mean + 3*input$normal_std,
length.out = 1e3)
y <- dnorm(x, mean = input$normal_mean, sd = input$normal_std)
}
else if(tab == "LogNormal"){
#if LogNormal, plot from 0 to 3*CV
x <- seq(from = 0, 
to = 3*input$lognormal_CV,
length.out = 1e3)
y <- dlnorm(x, meanlog = 0, sdlog = 1)
}
else if(tab =="Exponential"){
x <- seq(from = 0,
to = 3/input$exp_rate,
length.out = 1e3)
y <- dexp(x, rate = input$exp_rate)
}
else stop("No method found")
return(list(x = x,
y = y))
}

# Define UI for application that draws the pdf
ui <- 
navbarPage(
title = 'reprex', id = "cur_tab", selected = 'Normal',
# Normal Tab ----
navbarMenu("Normal/LogNormal",
tabPanel("Normal",
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "normal_mean", "Choose mean", value = 1, min = -2 , max = 2),
sliderInput(inputId = "normal_std" , "Choose std" , value = 1, min = 0 , max = 2)
),
mainPanel(
plotOutput("plot_normal")
)
)
),
tabPanel("LogNormal",
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "lognormal_CV", "Choose CV", value = 1, min = 0 , max = 20)
),
mainPanel(
plotOutput("plot_LogNormal")
)
)
)
),
# exponential Tab 
tabPanel('Exponential',       
sidebarLayout(
sidebarPanel(
sliderInput(inputId = "exp_rate", "Choose rate", value = 1, min = 0, max = 10)
),
mainPanel(
plotOutput("plot_exp")
)
)
)
)

# Define server logic required to draw pdf
server <- function(input, output) {
rvals <- reactiveValues()
observe({
rvals$x <- xy_dens_gen(tab = input$cur_tab, input = input)$x
rvals$y <- xy_dens_gen(tab = input$cur_tab, input = input)$y
})

#Render print inside renderPLot
output$plot_normal <- output$plot_LogNormal <- output$plot_exp <-  renderPlot({
plot_fun_helper(x = rvals$x, y = rvals$y)
})

}
# Run the application 
shinyApp(ui = ui, server = server)

最新更新