我在使用下载按钮模块下载正确的数据集时遇到问题。一旦按照您的预期下载,就可以使用它,但是一旦小部件值发生变化,并且重新单击下载按钮,它就会下载之前选择的变量,几乎就像是缓存值而不是更新它们一样。绘图/文件名标题也是如此。
根据需要,所有内容都包含在
reactive
中,并且绘图会随着值的变化而更新。如果我做错了什么,请告诉我。干杯!
注意:即使不使用模块,问题仍然存在。
代表:
# Load libraries
library(shiny)
library(shinyWidgets)
library(tidyverse)
library(here)
# Load sources
source(here("dwnld buttons.R"))
# Load data
data(mtcars)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
varSelectInput(inputId = "x_var",
data = mtcars,
label = "Select x var"),
varSelectInput(inputId = "y_var",
data = mtcars,
selected = names(mtcars)[2],
label = "Select y var")
),
mainPanel(
plotOutput(outputId = "plot"),
dwnldButtonUI(id = "download")
)
)
)
server <- function(input, output){
plot1_data <- reactive({
mtcars %>%
select(input$x_var, input$y_var) %>%
rename("x" = input$x_var,
"y" = input$y_var)
})
labels <- reactiveValues()
observeEvent(c(input$x_var, input$y_var), {
labels$title1 <- paste(input$y_var, "vs", input$x_var)
})
output$plot <- renderPlot({
ggplot(data = plot1_data(),
aes(x = x,
y = y))+
geom_point()+
labs(title = labels$title1)
}
)
dwnldButtonServer(id = "download",
file_name = labels$title1,
graph_df = plot1_data()
)
}
shinyApp(ui, server)
### Module ###
dwnldButtonUI <- function(id){
ns <- NS(id)
tagList(
downloadButton(outputId = ns("dwnldBtn"),
label = "")
)
}
dwnldButtonServer <- function(id, file_name, graph_df){
moduleServer(
id,
function(input, output, session){
output$dwnldBtn <- downloadHandler(
filename = function() {
paste(file_name, ".csv", sep = "")
},
content = function(file) {
write.csv(graph_df, file, row.names = FALSE)
}
)
}
)
}
利用@Limey 的评论,该解决方案可以扩展为包括在更改小部件值后更新下载数据和文件名。这涉及将
reactive
(不是它的值)传递给模块,然后访问它的值(而不是 reactive
本身)。见下图:
# Here we try and recreate a simplified version of the download button error #
# Load libraries
library(shiny)
library(shinyWidgets)
library(tidyverse)
# library(here)
# Load sources
# source(here("dwnld buttons.R"))
# Load data
data(mtcars)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
varSelectInput(inputId = "x_var",
data = mtcars,
label = "Select x var"),
varSelectInput(inputId = "y_var",
data = mtcars,
selected = names(mtcars)[2],
label = "Select y var")
),
mainPanel(
plotOutput(outputId = "plot"),
dwnldButtonUI(id = "download")
)
)
)
server <- function(input, output){
plot1_data <- reactive({
mtcars %>%
select(input$x_var, input$y_var) %>%
rename("x" = input$x_var,
"y" = input$y_var)
})
labels <- reactiveValues()
observeEvent(c(input$x_var, input$y_var), {
labels$title1 <- paste(input$y_var, "vs", input$x_var)
})
output$plot <- renderPlot({
ggplot(data = plot1_data(),
aes(x = x,
y = y))+
geom_point()+
labs(title = labels$title1
)
})
labels_title1 <- reactive({labels$title1})
dwnldButtonServer(id = "download",
# File_name and graph_df is passed the reactive, not value
file_name = labels_title1,
graph_df = plot1_data
)
}
shinyApp(ui, server)
# Module UI
dwnldButtonUI <- function(id){
ns <- NS(id)
tagList(
downloadButton(outputId = ns("dwnldBtn"),
label = "")
)
}
# Module server
dwnldButtonServer <- function(id, file_name, graph_df){
moduleServer(
id,
function(input, output, session){
output$dwnldBtn <- downloadHandler(
filename = function() {
# Access the reactive value using ()
paste(file_name(), ".csv", sep = "")
},
content = function(file) {
# Access the reactive value using ()
write.csv(graph_df(), file, row.names = FALSE)
}
)
}
)
}