bugfix> r > 投稿

私は以下を目的とする光沢のあるWebアプリを開発しています。

  • ファイルを読み込む
  • ファイルを解析する一回 関数 myDummyFun を使用する
  • 返されたデータフレーム d を使用する複数のタブにわたるプロット関数への入力として

これは、私がやっていることの単純化されたバージョンであり、問​​題を示しています(ただし、 mtcars ロードされたファイルの代わりのデータセット:

library(shiny)
library(dplyr)
data(mtcars)
ui <- fluidPage(
  tabsetPanel(
    # Tab 1
    tabPanel("Upload File",
             titlePanel("Upload your file"),
              sidebarLayout(
               sidebarPanel(
                 fileInput('file1', 'Browse for your file')
               ),
               mainPanel(
                 renderDataTable('contents')
               )
              )
    ),
    tabPanel("Plot",
             pageWithSidebar(
               headerPanel('Example plot'),
               sidebarPanel(),
               mainPanel(
                 plotOutput('plotExample')
               )
             )
    )
  )
)


myDummyFun <- function(x){
  x <- x %>% 
    filter(disp<=400) 
  return(x)
}


server <- function(input, output, server) {
  observe({
    inFile <- input$file1
    if (is.null(inFile))
      return(NULL)
    # I am really using the loaded file as input: 
    # d <- myDummyFun(inFile$datapath)
    d <- myDummyFun(mtcars)
  })
  # datatable of data
  output$contents <- DT::renderDataTable({
    renderDataTable(d)
  })
  # tabPanel 1 
  output$plotExample <-renderPlot({
    ggplot(d) +
      geom_point(aes(disp, mpg))
  })
}


shinyApp(ui = ui, server = server)

構文解析関数 myDummyFun 実際には非常に大きく、選択したファイル input$file1 を読み込むのに時間がかかります 、 そうファイルを1回読み取り、返されたデータフレームに各プロット関数からアクセスできるようにします。

この例では、 d ローカルスコープであるため、 renderDataTable(d) からアクセスできませんまたは renderPlot 。これを整理する正しい方法は何ですか?

回答 1 件
  • ?observe を観察するためのヘルプ  言う:

    An observer is like a reactive expression in that it can read reactive values and call reactive expressions, and will automatically re-execute when those dependencies change. But unlike reactive expressions, it doesn't yield a result and can't be used as an input to other reactive expressions. Thus, observers are only useful for their side effects (for example, performing I/O).

    そして、ここでの答えは、 output$something をネストすることを想定しています   observe 内の呼び出し  構造。

    したがって、私はあなたの observe だと思う  次のようになります。

     observe({
        inFile <- input$file1
        if (is.null(inFile))
          return(NULL)
        # I am really using the loaded file as input: 
        # d <- myDummyFun(inFile$datapath)
        d <- myDummyFun(mtcars)
        output$contents <- DT::renderDataTable({
          renderDataTable(d)
        })
        # tabPanel 1 
        output$plotExample <-renderPlot({
          ggplot(d) +
            geom_point(aes(disp, mpg))
        })
      })
    
    

    if (is.null(inFile)) return(NULL) をコメントアウトするとき  このアプリも実行され、プロットは次のようになります

    完全を期すために、完全なコード:

    ui.R

    library(shiny)
    library(dplyr)
    library(ggplot2)
    data(mtcars)
    fluidPage(
      tabsetPanel(
        # Tab 1
        tabPanel("Upload File",
                 titlePanel("Upload your file"),
                 sidebarLayout(
                   sidebarPanel(
                     fileInput('file1', 'Browse for your file')
                   ),
                   mainPanel(
                     renderDataTable('contents')
                   )
                 )
        ),
        tabPanel("Plot",
                 pageWithSidebar(
                   headerPanel('Example plot'),
                   sidebarPanel(),
                   mainPanel(
                     plotOutput('plotExample')
                   )
                 )
        )
      )
    )
    
    

    server.R

    myDummyFun <- function(x){
      x <- x %>% 
        filter(disp<=400) 
      return(x)
    }
    function(input, output, server) {
      observe({
        inFile <- input$file1
        # if (is.null(inFile))
        #   return(NULL)
        # 
        # I am really using the loaded file as input: 
        # d <- myDummyFun(inFile$datapath)
        d <- myDummyFun(mtcars)
        output$contents <- DT::renderDataTable({
          renderDataTable(d)
        })
        # tabPanel 1 
        output$plotExample <-renderPlot({
          ggplot(d) +
            geom_point(aes(disp, mpg))
        })
      })
      # datatable of data
    }
    
    

    お役に立てれば。

あなたの答え