我的代码有问题。我有2个输入文件,我想通过点击按钮和数字输入读取,其中包含从2个文件(操作数据后)创建的表的输出的过滤值。每次用户单击按钮时,都会执行整个过程(读取文件+创建表格+过滤器)。如果输入文件没有改变,我只想做过滤操作,因为这个过程需要很长时间。
第一次单击后,我想在数字输入更改时仅执行过滤命令,除非用户也更改了输入文件。
以下代码重现了我的问题:
library(shiny)
library(data.table)
server <- function(input, output, session) {
output$table1 <- renderDataTable({
input$gobtn
isolate({
infile1 <<- input$f1
infile2 <<- input$f2
if (is.null(infile1) || is.null(infile1)) {
return (NULL)
}
else {
calc()
}
})
})
calc <- function() {
inf1 <<- fread(infile1$datapath)
inf2 <<- fread(infile2$datapath)
# do some process with files data.....
my_table <- as.data.table(rbind(inf1, inf2))
setnames(my_table, c('name', 'rank'))
result <- my_table[rank > input$rank]
return(result)
}
}
ui <- basicPage(
fileInput("f1", "f1"),
fileInput("f2", "f2"),
numericInput("rank", "show rank only above :", value = 6),
actionButton("gobtn", "show"),
dataTableOutput('table1')
)
shinyApp(ui = ui, server = server)
答案 0 :(得分:1)
使用反应性的方法是将事物分解成部分,这样您只需要更新必要的内容。管道的第一步是读取和处理文件。这似乎是一个很好的反应:如果他们没有改变,没有任何反应,但当他们改变时,重新计算需要重新计算的一切。下一步是过滤,当过滤器变量发生变化时,我们要重新过滤数据。然后我们可以把它放在输出中。
server <- function(input, output, session) {
processedData <- reactive({
req(input$f1,input$f2)
inf1 <- fread(input$f1$datapath)
inf2 <- fread(input$f2$datapath)
# do some process with files data.....
my_table <- as.data.table(rbind(inf1, inf2))
setnames(my_table, c('name', 'rank'))
my_table
}
filteredData <- reactive({
req(input$rank)
processedData()[processedData()$rank > input$rank]
})
output$table1 <- renderDataTable({
input$gobtn
isolate({
filteredData()
})
})
}