реактивныйFileReader в Shiny для .RData - PullRequest
0 голосов
/ 29 августа 2018

Мой текущий рабочий процесс в блестящем приложении состоит в том, чтобы периодически запускать R-скрипт как задание cron для извлечения различных таблиц из нескольких баз данных, а также для загрузки данных из некоторых API. Затем они сохраняются в виде файла .Rdata в папке с именем data.

.

В моем файле global.R я загружаю данные, используя load("data/workingdata.Rdata"). Это приводит к загрузке всех фреймов данных (около 30) в среду. Я знаю, что могу использовать функцию reactiveFileReader() для обновления данных, но, очевидно, ее нужно будет использовать в файле server.R из-за связанного сеанса с функцией. Кроме того, я не уверен, что load принимается как readFunc в reactiveFileReader(). Какова должна быть лучшая стратегия для сценария здесь?

Ответы [ 3 ]

0 голосов
/ 26 ноября 2018

Несколько мыслей о вашем рабочем процессе:

В конце концов с вашим подходом RData вы настраиваете другой источник данных параллельно вашим базам данных / API.

При работе с файлами всегда есть некоторые служебные издержки (например, завершен ли ваш файл .RData при его чтении?). На мой взгляд, это (частично) то, для чего созданы СУБД - забота о домашнем хозяйстве. У большинства из них есть сложные решения, гарантирующие, что вы получите то, что запрашиваете очень быстро; так зачем изобретать велосипед?

Вместо того, чтобы непрерывно создавать свои файлы .RData и опрашивать данные с помощью реагирующей функции (), вы могли бы напрямую запросить в БД изменения , используя реактивный пакет (см. это для примера с использованием sqlite). Если ваши запросы выполняются долго (что, я полагаю, является причиной вашего рабочего процесса), вы можете обернуть их в будущем и выполнить их асинхронно (см. post чтобы получить вдохновение). В качестве альтернативы многие СУБД предоставляют что-то вроде материализованных представлений, чтобы избежать длительного времени ожидания (согласно предполагаемым привилегиям пользователя).

Конечно, все это основано на предположениях, потому что ваша экосистема мне не известна, но по моему опыту сокращение интерфейсов означает уменьшение источников ошибок.

0 голосов
/ 27 ноября 2018

В этом примере используется объект reactiveVal с observe и invalidateLater. Данные загружаются в новую среду и присваиваются реактивному значению каждые 2 секунды.

library(shiny)

ui <- fluidPage(
  actionButton("generate", "Click to generate an Rdata file"),
  tableOutput("table")
)

server <- shinyServer(function(input, output, session) {

  ## Use reactiveVal with observe/invalidateLater to load Rdata
  data <- reactiveVal(value = NULL)
  observe({
    invalidateLater(2000, session)
    n <- new.env()
    print("load data")
    env <- load("workingdata.Rdata", envir = n)
    data(n[[names(n)]])
  })


  ## Click the button to generate a new random data frame and write to file
  observeEvent(input$generate, {
    sample_dataframe <- iris[sample(1:nrow(iris), 10, F),]
    save(sample_dataframe, file="workingdata.Rdata")
    rm(sample_dataframe)
  })

  ## Table output
  output$table <- renderTable({
    req(data())
    data()
  })
})


shinyApp(ui = ui, server = server)
0 голосов
/ 26 ноября 2018

Вы можете использовать load("data/workingdata.Rdata") вверху server.R. Затем, каждый раз, когда кто-нибудь начинает новый сеанс Shiny, данные будут самыми последними. Возможные недостатки:

  • может произойти сбой, если данные записываются в то же время, когда новый сеанс Shiny загружает данные.
  • данные будут устаревшими, если сеанс будет открыт непосредственно перед, а затем после того, как новые данные станут доступны.

Я думаю, что первая возможная проблема не возникнет достаточно, чтобы быть проблемой. Вторая возможная проблема встречается с большей вероятностью, но если вы не находитесь в сверхкритической ситуации, я не вижу в ней достаточно существенной проблемы для беспокойства.

Это работает для вас?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...