Как загрузить данные с понижением частоты при масштабировании в R-графике?

Я создал блестящее приложение R, которое имеет граф, основанный на таблице данных, которая динамически подставляется в checkboxGroupInput. Моя проблема в том, что когда я пытаюсь загрузить большие объемы данных (миллионы записей), он загружается очень медленно и / или вылетает.

Проведя еще несколько исследований, я наткнулся на технику "ленивой нагрузки" отсюда. Насколько я понимаю, этот метод существенно сокращает данные, загружая только количество точек данных, равное ширине окна графика. Когда пользователь увеличивает масштаб, он будет детализировать и загружать больше данных в пределах максимальных / минимальных значений dyRangeSelector. Я подозреваю, что это решит мою проблему, потому что при любом взаимодействии с графом будет загружено значительно меньше данных. Тем не менее, все примеры, представленные в этой ссылке, были в Javascript, и у меня возникли проблемы с переводом на R.

Я также попытался обработать файл GraphDataProvider.js как плагин dygraph, но мне не удалось заставить его работать должным образом.

Несколько быстрых заметок о моей реализации:

  • Каждый элемент data_dict на сервере есть объект xts.
  • do.call.cbind Вызов функции на сервере основан на этой реализации SO, и это очень быстро.

Моя текущая настройка по сути такая (я реорганизовал ее, чтобы сделать ее общей):

Настройка данных:

library(shiny)
library(shinydashboard)
library(dygraphs)
library(xts)
library(data.table)

start <- as.POSIXlt("2018-07-09 00:00:00","UTC")
end   <- as.POSIXlt("2018-07-11 00:00:00","UTC")
x <- seq(start, end, by=0.5)

data <- data.frame(replicate(4,sample(0:1000,345601,rep=TRUE)))
data$timestamp <- x
data <- data[c("timestamp", "X1", "X2", "X3", "X4")]
data <- as.data.table(data)

filters <- c("X1","X2","X3","X4")
data_dict <- vector(mode="list", length=4)
names(data_dict) <- filters

data_dict[[1]] <- as.xts(data[,c('timestamp','X1')]); data_dict[[2]] <- as.xts(data[,c('timestamp','X2')])
data_dict[[3]] <- as.xts(data[,c('timestamp','X3')]); data_dict[[4]] <- as.xts(data[,c('timestamp','X4')])

# Needed to quickly cbind the xts objects
do.call.cbind <- function(lst){
  while(length(lst) > 1) {
    idxlst <- seq(from=1, to=length(lst), by=2)
    lst <- lapply(idxlst, function(i) {
      if(i==length(lst)) { return(lst[[i]]) }
      return(cbind(lst[[i]], lst[[i+1]]))})}
  lst[[1]]}

UI:

header <- dashboardHeader(title = "App")
body <- dashboardBody(
        fluidRow(
            column(width = 8,
                box(
                    width = NULL,
                    solidHeader = TRUE,
                    dygraphOutput("graph")
                )
            ),
            column(width = 4,
                box(
                    width = NULL,
                    checkboxGroupInput(
                        "data_selected",
                        "Filter",
                        choices = filters,
                        selected = filters[1]
                    ),
                    radioButtons(
                        "data_format",
                        "Format",
                        choices=c("Rolling Averages","Raw"),
                        selected="Rolling Averages",
                        inline=TRUE
                    )
                )
            )
        )
)

ui <- dashboardPage(
    header,
    dashboardSidebar(disable=TRUE),
    body
)

Сервер:

server <- function(input, output) {
    # Reactively subsets the dataset based on checkboxGroupInput filters
    the_data <- reactive({
        data <- do.call.cbind(data_dict[input$data_selected]) # Column bind multiple xts objects
})

output$graph <- renderDygraph({
    graph <- dygraph(the_data()) %>% 
         dyRangeSelector(c("2018-07-10 00:00:00","2018-07-10 02:00:00")) %>% 
         dyOptions(useDataTimezone = TRUE,connectSeparatedPoints = TRUE)
    if(input$data_format == "Rolling Averages") graph <- graph %>% dyRoller(rollPeriod = 100)
    graph
    })
}

Сделать приложение:

shinyApp(ui, server)

Я был бы признателен за любую помощь, которую я могу получить в этом, это застало меня на некоторое время сейчас. Спасибо!

0 ответов

Другие вопросы по тегам