首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >闪亮-在输出中观察函数调用的使用结果

闪亮-在输出中观察函数调用的使用结果
EN

Stack Overflow用户
提问于 2013-11-06 18:38:18
回答 2查看 11K关注 0票数 7

我有一个闪亮的应用程序,其中基于选定的选项(列)数据集是动态重新计算的。重新计算的结果用于向用户显示另一组选项并创建绘图。

目前,我正在使用observe()读取用户选择、重新计算数据集和更新UI。但是,当显示输出(绘图)时,我必须再次进行重新计算,因为observe()没有返回任何内容。

有没有办法只重新计算一次数据集?

我已经创建了简单的example来说明这一点:

代码语言:javascript
复制
library(devtools)
library(shiny)
runGist('7333949') 

server.R中,我希望在observe()中调用一次自定义函数AggregateData,而在renderUI()中不调用。

应用程序代码:

server.R:

代码语言:javascript
复制
# shiny server side code for each call
shinyServer(function(input, output, session){
     #update variable and group based on dataset
     observe({

          require(sqldf)

          if (is.null(input$source_columns)) {
               obj <-TestData
          } else {
               obj<-AggregateData(TestData,Columns=input$source_columns)
          }

          var.opts<-namel(colnames(obj))
          var.opts.original.slicers <- namel(colnames(TestData))           
          measures <- c('m1','m2','m3','m4','m5')

          var.opts.slicers <- var.opts[!(var.opts %in% c(measures,'x'))]
          var.opts.original.slicers <- var.opts.original.slicers[!(var.opts.original.slicers %in% c(measures,'x'))]
          var.opts.measures <- var.opts[var.opts %in% measures]

          updateSelectInput(session, "source_columns", choices = var.opts.original.slicers, selected=var.opts.slicers)
          updateSelectInput(session, "xaxis", choices = var.opts.slicers,selected="x")
          updateSelectInput(session, "yaxis", choices = var.opts.measures,selected="m1")

     })

     output$plot <- renderUI({
          plotOutput("p")
     })

     #plotting function using ggplot2

     output$p <- renderPlot({
          require(ggplot2)
          obj <- AggregateData(TestData,Columns=input$source_columns)
          p <- PlotData(obj,x=input$xaxis, y=input$yaxis)
          print(p)
     })     
})

ui.R:

代码语言:javascript
复制
shinyUI(pageWithSidebar(
     # title
     headerPanel("Analysis setup"),

     #input
     sidebarPanel
     (
          selectInput("source_columns","Source Columns:", "Loading...",multiple=TRUE),
          selectInput("xaxis","X Axis:", "Loading..."),
          selectInput("yaxis","Y Axis:", "Loading...")
     ),     

     # output               
     mainPanel(
          #h3('Vintage Analysis'),
          uiOutput("plot") # depends on input 
     )
))

global.R:

代码语言:javascript
复制
#initialize
library(ggplot2) 

TestData <- data.frame(   a = rep(LETTERS[1:4],10),
                          b = rep(c('A','B'),20),
                          c = rep(LETTERS[1:5],each=8),
                          d = rep(c('A','B'),2,each=10),
                          m1 = rnorm(40),
                          m2 = rnorm(40),
                          m3 = rnorm(40),
                          m4 = rnorm(40),
                          m5 = rnorm(40),
                          x  = rep(1:5,each=8)
)

#helper function (convert vector to named list)
namel<-function (vec){
     tmp<-as.list(vec)
     names(tmp)<-as.character(unlist(vec))
     tmp
}

# Function to aggregate data based on selected columns (Source Columns)
AggregateData <- function(data,Columns=NA) {

     require(sqldf)
     if (all(is.na(Columns))) {
          sql <- "select 
                    sum(m1) as m1, sum(m2) as m2, sum(m3) as m3, sum(m4) as m4, sum(m5) as m5, x
                 from TestData group by x" 
          sqldf(sql)                
     } else {
          sql <- paste("select ", paste(Columns, collapse =','), ",
                    sum(m1) as m1, sum(m2) as m2, sum(m3) as m3, sum(m4) as m4, sum(m5) as m5, x
                 from TestData group by ",paste(Columns, collapse =','),", x")
          sqldf(sql)          
     }
}

# Function to plot data
PlotData <- function(data,x="x",y="m1") { 
     ggplot(data, aes_string(x=x, y=y)) + geom_line()
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-11 19:40:56

observe不会返回任何东西,但它仍然可以创建一些东西。我通过使用<<-操作符将obj分配给全局环境解决了这个问题。在我现在拥有的server.R中:

代码语言:javascript
复制
obj<<-AggregateData(TestData,Columns=input$source_columns)

然后,在UI.r中,我可以直接在ggplot中调用obj,而不需要再次调用AggregateData

票数 0
EN

Stack Overflow用户

发布于 2014-06-04 07:13:36

使用reactiveValues()

代码语言:javascript
复制
shinyServer(function(input, output, session){
     #update variable and group based on dataset

     values <- reactiveValues()

     observe({

          require(sqldf)

          if (is.null(input$source_columns)) {
               values$obj <-TestData
          } else {
               values$obj<-AggregateData(TestData,Columns=input$source_columns)
          }
             ...
     })

     output$plot <- renderUI({
          plotOutput("p")
     })

     #plotting function using ggplot2

     output$p <- renderPlot({
          require(ggplot2)
          obj <- values$obj
          p <- PlotData(obj,x=input$xaxis, y=input$yaxis)
          print(p)
     })     
})
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19809824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档