Объект не найден R Shiny - PullRequest
       0

Объект не найден R Shiny

0 голосов
/ 29 января 2020

Я пытаюсь получить доступ к фрейму данных, созданному в одной функции рендеринга, в другую функцию рендеринга.

Существует два выхода сервера, lvi и Category, в lvi я создал фрейм данных Data1, а в категории I я создал фрейм данных Data2. Я хочу выбрать Data2, где Data1 ID совпадает.

Я выполняю следующие шаги для достижения своей цели, но получаю ошибку «Объект Data1 not found».

Мой пользовательский интерфейс

ui <- fluidPage(
  # App title ----
  titlePanel("Phase1"),
  fluidPage(
    column(4,
           # Input: Select a file ----
           fileInput("file1", "Import file1")
    ) 
  ),
  fluidPage(
    column(4,
           # Input: Select a file ----
           fileInput("file2", "Import File2")
    ) 

  ),
    # Main panel for displaying outputs ----
    mainPanel( 
      # Output: Data file ----
      dataTableOutput("lvi"),
      dataTableOutput("category")
    )
  )

Код моего сервера

server <- function(input, output) {
  output$lvi <- renderDataTable({
    req(input$file1)
    Data1 <- as.data.frame(read_excel(input$file1$datapath, sheet = "Sheet1"))    
  })

  output$category <- renderDataTable({        
    req(input$file2)        
    Data2 <- as.data.frame(read_excel(input$file2$datapath, sheet = "Sheet1"))
    Data2 <- Data2[,c(2,8)]
    Data2 <- Data2[Data1$ID == "ID001",]        
  })        
}
shinyApp(ui, server)

1 Ответ

2 голосов
/ 29 января 2020

После выполнения реактивного блока все элементы в нем go удаляются, как функция. Единственное, что выживает, это то, что «возвращается» из этого блока, который обычно является либо последним выражением в блоке (или, когда в реальном function, что-то в return(...)). Если вы думаете о реактивных (и наблюдающих) блоках как о «функциях», вы можете понять, что единственное, что что-то вне функции знает о том, что происходит внутри , это функция, если функция явно возвращает его как-то.

Имея это в виду, вы попадаете в кадр внутри одного render / реактивного блока, а не вычисляете его внутри этого реактивного блока: вместо этого создайте этот кадр в его собственный блок данных reactive и используйте его как в render, так и в других render.

Попробуйте это (не проверено):

server <- function(input, output) {

  Data1_rx <- eventReactive(input$file1, {
    req(input$file1, file.exists(input$file1$datapath))
    as.dataframe(read_excel(input$file1$datapath, sheet = "Sheet1"))
  })

  output$lvi <- renderDataTable({ req(Data1_rx()) })

  output$category <- renderDataTable({        
    req(input$file2, file.exists(input$file2$datapath),
        Data1_rx(), "ID" %in% names(Data1_rx()))
    Data2 <- as.data.frame(read_excel(input$file2$datapath, sheet = "Sheet1"))
    Data2 <- Data2[,c(2,8)]
    Data2 <- Data2[Data1_rx()$ID == "ID001",]        
  })        
}
shinyApp(ui, server)

Но так как мы уже Идя по пути «лучшего дизайна» и «лучших практик», давайте разберем data2 и фрейм с фильтром data2 ... вы можете не использовать его отдельно, но часто лучше разделить «загрузку / генерацию фреймов» "из" рендеринга во что-то красивое ". Таким образом, если вам нужно что-то узнать о загруженных данных, вам не нужно (а) перезагружать их в другом месте, неэффективно; или (b) попытаться вскрыть внутренности блестящего объекта DataTable и получить его вручную. (И то, и другое действительно плохие идеи.)

Так что несколько лучшее решение может начаться с:

server <- function(input, output) {

  Data1_rx <- eventReactive(input$file1, {
    req(input$file1, file.exists(input$file1$datapath))
    as.dataframe(read_excel(input$file1$datapath, sheet = "Sheet1"))
  })
  Data2_rx <- eventReactive(input$file2, {
    req(input$file2, file.exists(input$file2$datapath))
    dat <- as.dataframe(read_excel(input$file2$datapath, sheet = "Sheet1"))
    dat[,c(2,8)]
  })
  Data12_rx <- reactive({
    req(Data1_rx(), Data2_rx())
    Data2_rx()[ Data1_rx()$ID == "ID001", ]
  })

  output$lvi <- renderDataTable({ req(Data1_rx()); })
  output$category <- renderDataTable({ req(Data12_rx()); })
}
shinyApp(ui, server)

Хотя этот код немного длиннее, он также группирует «загрузку / обработку данных» вместе и "сделать данные красивыми" вместе. И если вам нужно взглянуть на ранние данные или отфильтрованные данные, все в порядке.

(Примечание: один удар по производительности, который вы можете увидеть из этого, заключается в том, что теперь у вас есть больше копий данных, перемещающихся вокруг. Пока Вы не имеете дело с «большими» данными, это не так уж и сложно.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...