После выполнения реактивного блока все элементы в нем 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)
Хотя этот код немного длиннее, он также группирует «загрузку / обработку данных» вместе и "сделать данные красивыми" вместе. И если вам нужно взглянуть на ранние данные или отфильтрованные данные, все в порядке.
(Примечание: один удар по производительности, который вы можете увидеть из этого, заключается в том, что теперь у вас есть больше копий данных, перемещающихся вокруг. Пока Вы не имеете дело с «большими» данными, это не так уж и сложно.)