【问题标题】:How to avoid repeating the same procedure multiple times in Shiny app如何避免在 Shiny 应用程序中多次重复相同的过程
【发布时间】:2017-08-15 05:46:44
【问题描述】:

我编写了一个闪亮的应用程序,我在其中从泊松分布中采样。每次我想输出数据的图表或摘要时,我都重写了函数。我宁愿只使用该函数一次,然后让所有绘图和摘要都引用该函数被调用的单次,否则输出的结果将不相同。当我尝试调用该函数一次并将结果存储为 ggplot 使用的变量时,我得到了错误,即 ggplot 无法使用反应数据并且我无法将其强制转换为数据框。

我尝试了以下变化:

mydata <- reactive({
  x <- input$x
  y <- input$y
  z <- input$z
  Muts <- as.data.frame(rpois(100,(x*y*z)))
  Muts
})

但是它们不起作用,因为 ggplot 无法使用输入。我想我没有正确使用反应功能。非常感谢任何有助于减少代码冗余并确保绘图和摘要都使用相同的单个基础数据的帮助。提前谢谢你。

我当前的代码:

服务器.R

library(shiny)
library(ggplot2)

# Define server logic required to draw a histogram
function(input, output) {




  output$distPlot <- renderPlot({

    x <- input$x
    y <- input$y
    z <- input$z
    Muts <- as.data.frame(rpois(100,(x*y*z)))


    # draw the density plot

    ggplot(Muts, aes(Muts)) + geom_density() 

  })

  output$distPlot2 <-renderPlot({

    x <- input$x
    y <- input$y
    z <- input$z
    Muts <- as.data.frame(rpois(100,(x*y*z)))



    Muts <- as.data.frame(Muts)

    ggplot(Muts, aes(Muts)) + geom_histogram() 

  })

  output$summary <- renderPrint({
    x <- input$x
    y <- input$y
    z <- input$z
    Muts <- as.data.frame(rpois(100,(x*y*z)))

    summary(Muts)
  })


}

【问题讨论】:

  • 您需要在 ggplot 调用中调用响应式表达式,因为它包含数据。 ggplot(myData(), aes(...)) + ...
  • 另见this answer

标签: r shiny redundancy


【解决方案1】:

你的想法是对的,但是 reactive 本质上是一个缓存函数,需要调用它来检索它的返回值,所以 mydata() 是正确的,mydata 只是返回函数本身(而不是返回值) .

library(shiny)
library(ggplot2)

# Define UI for application
ui <- fluidPage(

   # Application title
   titlePanel(""),

   # Sidebar with a slider input for number of bins 
   sidebarLayout(
      sidebarPanel(
         sliderInput("x",
                     "Number of bins:",
                     min = 1,
                     max = 50,
                     value = 30),
         sliderInput("y",
                     "Number of bins:",
                     min = 1,
                     max = 50,
                     value = 30),
         sliderInput("z",
                     "Number of bins:",
                     min = 1,
                     max = 50,
                     value = 30)
      ),

      # Show a plot of the generated distribution
      mainPanel(
         plotOutput("distPlot"),
         plotOutput("distPlot2"),
         verbatimTextOutput("summary")
      )
   )
)

# Define server logic
server <- function(input, output) {

  mydata <- reactive({
    x <- input$x
    y <- input$y
    z <- input$z
    Muts <- as.data.frame(rpois(100,(x*y*z)))
    Muts
  })


  output$distPlot <- renderPlot({
    Muts <- mydata()
    ggplot(Muts, aes(Muts)) + geom_density() 
  })

  output$distPlot2 <-renderPlot({
    Muts <- mydata()
    ggplot(Muts, aes(Muts)) + geom_histogram() 
  })

  output$summary <- renderPrint({
    Muts <- mydata()
    summary(Muts)
  })


}

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

【讨论】:

  • 谢谢你,这很好。我一直在使用 Rstudio GUI 运行应用程序,'shinyApp(ui = ui, server = server)' 部分是否允许从控制台启动它?
  • 您可以在 app.R 的末尾写下它,然后 RStudio 会将“Run/Source”替换为“Run App”,因为它知道您正在开发一个闪亮的应用程序。如果您不将其添加到您的 app.R,那么您可以获取所有内容并使用带有shinyApp(ui, server) 的控制台来启动应用程序。
【解决方案2】:

只需确保调用 mydata() 以实际获取反应对象的值。

library(shiny)
library(ggplot2)


ui <- fluidPage(
numericInput("x", "x", 2), numericInput("y", "y", 2), numericInput("z", "z", 2),
plotOutput("distPlot"), plotOutput("distPlot2"))

server <- function(input, output) {

  mydata <- reactive({
    x <- input$x
    y <- input$y
    z <- input$z
    data.frame(x=rpois(100,(x*y*z)))
  })


  output$distPlot <- renderPlot({

    ggplot(mydata(), aes(x)) + geom_density() 

  })

  output$distPlot2 <-renderPlot({

    ggplot(mydata(), aes(x)) + geom_density() 

  })
}

runApp(list(ui=ui, server=server))

【讨论】:

    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多