r闪亮:按下按钮时eventReactive没有反应
Posted
技术标签:
【中文标题】r闪亮:按下按钮时eventReactive没有反应【英文标题】:r shiny: eventReactive is not reacting when the button is pressed 【发布时间】:2018-08-01 07:17:00 【问题描述】:下面是我的代码。它可能看起来有点长,但实际上它是一个非常简单的应用程序。
用户应该上传一个很小的数据框(如果您在美国,则为 x.csv,如果您在欧洲,则为 x_Europe.csv)。然后用户应该点击按钮开始计算。最后,用户应该能够以数据框的形式下载这些计算的结果。
我的问题:上传文件后,当我单击“do_it”操作按钮时 - 没有任何反应。我可以看到它,因为我的控制台上没有打印任何内容。为什么?毕竟,我的函数“main_calc”应该是 eventReactive 到 input$do_it?为什么 main_calc 中的所有计算只有在用户尝试下载结果后才开始发生?
重要提示:将“数据”函数与 main_calc 分开对我来说很重要。
非常感谢!
首先,在您的工作目录中生成以下两个文件之一:
# generate file 'x.csv' to read in later in the app:
write.csv(data.frame(a = 1:4, b = 2:5), "x.csv", row.names = F) # US file
write.csv2(data.frame(a = 1:4, b = 2:5), "x_Europe.csv", row.names = F)
这是闪亮应用的代码:
library(shiny)
ui <- fluidPage(
# User should upload file x here:
fileInput("file_x", label = h5("Upload file 'x.csv'!")),
br(),
actionButton("do_it", "Click Here First:"),
br(),
br(),
textInput("user_filename","Save your file as:", value = "My file x"),
downloadButton('file_down',"Save the output File:")
)
server <- function(input, output, session)
#----------------------------------------------------------------------
# Function to read in either European (csv2) or American (csv) input:
#----------------------------------------------------------------------
ReadFile <- function(pathtofile, withheader = TRUE)
test <- readLines(pathtofile, n = 1)
if (length(strsplit(test, split = ";")[[1]]) > 1)
print("Reading European CSV file")
outlist <- list(myinput = read.csv2(pathtofile, header = TRUE),
europe.file = 1)
else
print("Reading US CSV file")
outlist <- list(myinput = read.csv(pathtofile, header = TRUE),
europe.file = 0)
return(outlist)
#----------------------------------------------------------------------
# Data-related - getting the input file
#----------------------------------------------------------------------
Data <- reactive(
print("Starting reactive function 'Data'")
# Input file:
infile_x <- input$file_x
myx <- ReadFile(infile_x$datapath)$myinput
# European file?
europe <- ReadFile(infile_x$datapath)$europe.file
print("Finishing reactive function 'Data'")
return(list(data = myx, europe = europe))
)
#----------------------------------------------------------------------
# Main function that should read in the input and 'calculate' stuff
# after the users clicks on the button 'do_it' - takes about 20 sec
#----------------------------------------------------------------------
main_calc <- eventReactive(input$do_it,
req(input$file_x)
# Reading in the input file:
x <- Data()$data
print("Done reading in the data inside main_calc")
# Running useless calculations - just to kill time:
myvector <- matrix(unlist(x), ncol = 1, nrow = 1000)
print("Starting calculations")
for (i in seq_len(10))
set.seed(12)
mymatr <- matrix(abs(rnorm(1000000)), nrow = 1000)
temp <- solve(mymatr) %*% myvector
print("Finished calculations")
# Creating a new file:
y <- temp
result = list(x = x, y = y)
print("End of eventReactive function main_calc.")
return(result)
) # end of main_calc
#----------------------------------------------------------------------
# The user should be able to save the output of main_calc as a csv file
# using a string s/he specified for the file name:
#----------------------------------------------------------------------
output$file_down <- downloadHandler(
filename = function()
paste0(input$user_filename, " ", Sys.Date(), ".csv")
,
content = function(file)
print("Europe Flag is:")
print(Data()$europe)
if (Data()$europe == 1)
x_out <- main_calc()$x
print("Dimensions of x in downloadHandler are:")
print(dim(x_out))
write.csv2(x_out,
file,
row.names = FALSE)
else
x_out <- main_calc()$x
print("Dimensions of x in downloadHandler are:")
print(dim(x_out))
write.csv(x_out,
file,
row.names = FALSE)
)
# end of server code
shinyApp(ui, server)
【问题讨论】:
尝试将main_calc()
添加为downloadHandler
的第一行以创建依赖项
也许这个问题将有助于澄清:***.com/questions/33519816/…。 eventReactive
对象在事件发生时不会“运行”,它们只是被标记为无效。在实际向它们请求值之前,它们不会运行。因此,由于您在按下下载按钮之前不使用main_calc()
,因此直到那时它才会运行。您可能希望 observeEvent
与 reactiveValues
对象进行此类交互。
有趣(也很疯狂!) - 我添加了 main_calc(),作为 downloadHandler 中的第一行。确实-在我单击按钮后进行了计算,但是:计算结束后,文件下载按钮非常小,当我单击它时,一切都崩溃了:“ self$downloads$set(name,list)中的警告(filename = filename, contentType = contentType, : 重新启动中断的 Promise 评估" 然后:运行中的错误 (timeoutMs) :期望单个字符串值:[type=character; extent=2]。
@MrFlick 但是如果我使用 observeEvent - 我不能返回任何东西,可以吗?如果我没有返回我需要下载的对象的函数(如 main_calc),我的 downloadHandler 应该下载什么?
@user3245256 是的,你不能返回任何东西。这就是为什么您需要更新事件之外的 reactiveValues 对象中的值。看这个简单的例子:gist.github.com/aagarw30/69feeeb7e813788a753b71ef8c0877eb
【参考方案1】:
以下是解决方案 - 基于 MrFlick 的建议:
# generate file 'x.csv' to read in later in the app:
# write.csv(data.frame(a = 1:4, b = 2:5), "x.csv", row.names = F)
# write.csv2(data.frame(a = 1:4, b = 2:5), "x_Europe.csv", row.names = F)
library(shiny)
library(shinyjs)
ui <- fluidPage(
# User should upload file x here:
fileInput("file_x", label = h5("Upload file 'x.csv'!")),
br(),
actionButton("do_it", "Click Here First:"),
br(),
br(),
textInput("user_filename","Save your file as:", value = "My file x"),
downloadButton('file_down',"Save the output File:")
)
server <- function(input, output, session)
#----------------------------------------------------------------------
# Function to read in either European (csv2) or American (csv) input:
#----------------------------------------------------------------------
ReadFile <- function(pathtofile, withheader = TRUE)
test <- readLines(pathtofile, n = 1)
if (length(strsplit(test, split = ";")[[1]]) > 1)
print("Reading European CSV file")
outlist <- list(myinput = read.csv2(pathtofile, header = TRUE),
europe.file = 1)
else
print("Reading US CSV file")
outlist <- list(myinput = read.csv(pathtofile, header = TRUE),
europe.file = 0)
return(outlist)
#----------------------------------------------------------------------
# Data-related - getting the input file
#----------------------------------------------------------------------
Data <- reactive(
print("Starting reactive function Data")
# Input file:
infile_x <- input$file_x
myx <- ReadFile(infile_x$datapath)$myinput
# European file?
europe <- ReadFile(infile_x$datapath)$europe.file
print("Finishing reactive function 'Data'")
return(list(data = myx, europe = europe))
)
#----------------------------------------------------------------------
# Main function that should read in the input and 'calculate' stuff
# after the users clicks on the button 'do_it' - takes about 20 sec
#----------------------------------------------------------------------
# Creating reactive Values:
forout_reactive <- reactiveValues()
observeEvent(input$do_it,
print("STARTING observeEvent")
req(input$file_x)
# Reading in the input file:
x <- Data()$data
print("Done reading in the data inside observeEvent")
# Running useless calculations - just to kill time:
myvector <- matrix(unlist(x), ncol = 1, nrow = 1000)
print("Starting calculations")
for (i in seq_len(10))
set.seed(12)
mymatr <- matrix(abs(rnorm(1000000)), nrow = 1000)
temp <- solve(mymatr) %*% myvector
# takes about 22 sec on a laptop
print("Finished calculations")
# Creating a new file:
y <- temp
forout_reactive$x = x
forout_reactive$y = y
print("End of observeEvent")
) # end of main_calc
#----------------------------------------------------------------------
# The user should be able to save the output of main_calc as a csv file
# using a string s/he specified for the file name:
#----------------------------------------------------------------------
output$file_down <- downloadHandler(
filename = function()
paste0(input$user_filename, " ", Sys.Date(), ".csv")
,
content = function(file)
print("Europe Flag is:")
print(Data()$europe)
if (Data()$europe == 1)
y_out <- forout_reactive$y
print("Dimensions of y in downloadHandler are:")
print(dim(y_out))
write.csv2(y_out,
file,
row.names = FALSE)
else
y_out <- forout_reactive$y
print("Dimensions of y in downloadHandler are:")
print(dim(y_out))
write.csv(y_out,
file,
row.names = FALSE)
)
# end of server code
shinyApp(ui, server)
【讨论】:
以上是关于r闪亮:按下按钮时eventReactive没有反应的主要内容,如果未能解决你的问题,请参考以下文章
闪亮的 SelectInput 和 SelectizeInput