Mantén la atención ya que en este artículo vas a encontrar el resultado que buscas.
Solución:
Editar
En realidad hay una función llamada reactiveFileReader
en el shiny
paquete que hace exactamente lo que está buscando: Comprobación periódica si la hora o el tamaño de los archivos “modificados por última vez” cambiaron y se volvieron a leer en consecuencia. Sin embargo, esta función sólo se puede utilizar en el server
context, por lo que el archivo se leerá al menos una vez para cada usuario que se conecte a su aplicación. Las opciones 3 y 4 en mi Respuesta no tienen estas ineficiencias.
Respuesta original de aquí en adelante
En primer lugar, shiny no tiene una forma de realizar un seguimiento de los cambios de archivos AFAIK. Su implementación recarga el .RData
archivo siempre que
shiny-server
se reinicia a través de bash o- las variables globales se vuelven a cargar porque la aplicación quedó inactiva en algún momento.
No hay forma de saber cuándo se cumple la segunda condición. Por lo tanto, recomendaría usar una de las siguientes cuatro opciones. Ordenado de fácil para ¡Será mejor que conozcas tu brillante!.
Opción 1: poner la declaración de carga en el servidor
Aquí, la imagen se vuelve a cargar cada vez que un nuevo usuario se conecta con la aplicación. Sin embargo, esto podría ralentizar su aplicación si su .RData
el archivo es enorme. Si la velocidad no es un problema, elegiría esta solución ya que es fácil y limpia.
# server.R
function(input, output, session)
load("working_dataset.RData")
...
Los datos también se volverán a leer cada vez que un usuario actualice la página (F5)
Opción 2: reinicie el servidor brillante cada vez que desee volver a importar sus datos
(También vea la respuesta de @shosacos). Esto obliga a la .Rdata
archivo a recargar.
$ sudo systemctl restart shiny-server
Nuevamente, esto podría ralentizar su proceso de producción según la complejidad de su aplicación. Una ventaja de este enfoque es que también puede usar los datos importados para construir la interfaz de usuario si carga los datos en global.R
. (Supongo que no diste el código que diste).
Opción 3: Importar según “última modificación”
La idea aquí es comprobar si el .RData
ha cambiado cada vez que un usuario se conecta a la aplicación. Para hacer esto, deberá usar una variable “global” que contenga una marca de tiempo de la última versión importada. El siguiente código no se ha probado, pero debería darle una idea de cómo implementar esta función.
# server.R
last_importet_timestamp <- reactiveVal("")
function(input,output,session)
current_timestamp <- file.info(rdata_path)$mtime
if(last_importet_timestamp() != current_timestamp)
# use parent.frame(2) to make data available in other sessions
load(rdata_path, envir = parent.fame(2))
# update last_importet_timestamp
last_importet_timestamp(current_timestamp)
...
En cuanto a la velocidad, esto debería ser más eficiente que las dos primeras versiones. Los datos nunca se importan más de una vez por marca de tiempo (a menos que el servidor brillante se reinicie o quede inactivo).
Opción 4: Importar "reactivamente"
Básicamente, lo mismo que la opción 3, pero se comprobará si hay cambios en el archivo cada 50 ms. Aquí hay un ejemplo de trabajo completo de este enfoque. Tenga en cuenta que los datos no se cargan a menos que se detecte un cambio en "última modificación", por lo que la sobrecarga resultante no es tan mala.
library(shiny)
globalVars <- reactiveValues()
rdata_path = "working_dataset.RData"
server <- function(input, output, session)
observe(
text = input$text_in
save(text = text, file = rdata_path, compress = TRUE)
)
observe(
invalidateLater(50, session)
req(file.exists(rdata_path))
modified <- file.info(rdata_path)$mtime
imported <- isolate(globalVars$last_imported)
if(!identical(imported, modified))
tmpenv <- new.env()
load(rdata_path, envir = tmpenv)
globalVars$workspace <- tmpenv
globalVars$last_imported <- modified
)
output$text_out <- renderText(
globalVars$workspace$text
)
ui <- fluidPage(
textInput("text_in", "enter some text to save in Rdata", "default text"),
textOutput("text_out")
)
shinyApp(ui, server)
Si le resulta inconveniente utilizar globalVars$workspace$text
puedes usar with
para acceder a los contenidos de globalVars$workspace
directamente.
output$text_out <- renderText(
with(globalVars$workspace,
paste(text, "suffix")
)
)
Calificaciones y reseñas
Si te ha resultado útil este artículo, nos gustaría que lo compartas con más entusiastas de la programación y nos ayudes a dar difusión a nuestra información.