Saltar al contenido

La aplicación Shiny no refleja los cambios en la actualización del archivo RData

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

  1. shiny-server se reinicia a través de bash o
  2. 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$textpuedes 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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *