Эффективный способ загрузки данных Wold Bank через WDI в блестящем - PullRequest
0 голосов
/ 16 января 2020

Я работаю над блестящим проектом панели инструментов для визуализации данных Всемирного банка. Всего мне нужно 14 различных переменных, которые я хочу показать в таблице данных. Это работает в R, но когда я пытаюсь сделать это блестящим, я получаю ошибку соединения. Я думаю, что это занимает слишком много времени для загрузки. Есть ли способ загрузить данные более эффективно или в фоновом режиме или что-то еще? Я не могу найти решение, чтобы заставить его работать, и я не хочу хранить данные в файле на сервере, потому что тогда у меня нет автоматического c обновления ...: /

Вот минимальный фрагмент жизненного кода

library(shiny)
library(dplyr)
library(WDI)
library(wbstats)
library(lubridate)

ui <- fluidPage(

   titlePanel('WDI Example'),
   mainPanel(tableOutput('table'))

   )


server <- function(input, output) {

  startDate <- as.numeric(format(Sys.Date(), "%Y")) -20
  endDate <- as.numeric(format(Sys.Date(), "%Y"))

  fetch.data <- list() 

  list <- c("SP.POP.TOTL",
            "NY.ADJ.NNTY.PC.CD",
            "SH.XPD.CHEX.PC.CD",
            "SH.XPD.OOPC.CH.ZS",
            "SH.MED.BEDS.ZS",
            "SH.MED.PHYS.ZS",
            "NY.GDP.MKTP.CD",
            "NY.GDP.MKTP.KD",
            "NY.GDP.MKTP.KD.ZG",
            "SH.XPD.CHEX.GD.ZS",
            "SP.DYN.LE00.IN",
            "SP.POP.65UP.TO",
            "SP.POP.DPND",
            "SP.POP.DPND.OL") 

  for (i in 1:length(list)){
    fetch.data[[i]] <- WDI(indicator = as.character(list[i]),
                           start = startDate, 
                           end = endDate,
                           country = "all",
                           extra = TRUE)
  }

  data <- fetch.data


  for (i in 1:length(list)){

    data[[i]] <- subset(data[[i]], region != "Aggregates")
    data[[i]] <- data[[i]] %>% select(country, iso3c, region, year, noquote(list[i]))
    data[[i]]$date <- as.Date(as.character(date), format = "%Y")
    data[[i]] <- data[[i]][complete.cases(data[[i]][ ,5]),]
    data[[i]] <- data[[i]] %>% group_by(country) %>% arrange(desc(date)) %>% slice(1)
  }


  indicators <- fetch.data[[1]] %>% 
    select(country, iso3c, region) %>% 
    subset(region != "Aggregates") %>% 
    arrange(desc(country)) %>% 
    group_by(country) %>% 
    slice(1)


  for (i in 1:length(list)){
    indicators <- merge(indicators, data[[i]][ ,c(2,5)], by.x = "iso3c", by.y = "iso3c", all = TRUE)
  }


  indicators <- indicators %>% 
    arrange(country) %>% 
    mutate_if(is.numeric, round, 2)

  output$table <- renderTable(indicators)

}

shinyApp(ui = ui, server = server)

, а вот пример, который не работает ... https://thera-trainer.shinyapps.io/example/

Спасибо за совет

1 Ответ

1 голос
/ 16 января 2020

Ошибка

Ваша ошибка в этой строке кода:

data[[i]]$date <- as.Date(as.character(date), format = "%Y")

date - это функция (замыкание), поэтому вы получаю ошибку. Если вы хотите сослаться на столбец в вашем фрейме данных, вам нужно будет использовать data[[i]]$date, как в

data[[i]]$date <- as.Date(as.character(data[[i]]$date), format = "%Y")

Скорее всего, вы привыкли к переходу, когда вам не нужно ставить перед столбцами префикс dataframe, но при использовании операций, не связанных с tidyverse, таких как <-, необходимо также указать имя dataframe. Кроме того, в data[[i]] нет столбца с именем date, поэтому даже если бы вы использовали as.Date(as.character(data[[i]]$date), format = "%Y"), вы бы получили сообщение об ошибке, потому что этот столбец не существует.

Кроме того, похоже, что Вы пытаетесь преобразовать дату в год, но в data[[i]] уже есть столбец с именем year, к которому можно обратиться с помощью data[[i]]$year.

Стиль кода

Не рекомендуется называть ваши объекты именами, совпадающими с именами функций. Вы сделали это дважды, один раз присвоив fetch.data на data (функция уже существует utils::data(), и, что более важно, вы присвоили свои индикаторы переменной с именем list. Это чрезвычайно опасно, так как вы перезаписали функцию list() в вашей глобальной среде, и чтобы позже использовать функцию списка снова, вам придется вызывать ее с помощью base::list(). Я бы порекомендовал более эмоциональное имя для индикаторов, такое как :

indicators_list <- c("SP.POP.TOTL",
            "NY.ADJ.NNTY.PC.CD",
            "SH.XPD.CHEX.PC.CD",
            "SH.XPD.OOPC.CH.ZS",
            "SH.MED.BEDS.ZS",
            "SH.MED.PHYS.ZS",
            "NY.GDP.MKTP.CD",
            "NY.GDP.MKTP.KD",
            "NY.GDP.MKTP.KD.ZG",
            "SH.XPD.CHEX.GD.ZS",
            "SP.DYN.LE00.IN",
            "SP.POP.65UP.TO",
            "SP.POP.DPND",
            "SP.POP.DPND.OL") 

withProgress

Существует Блестящий индикатор прогресса , который можно использовать для отслеживания циклов, которые занимают много времени. это так;

  withProgress(
    for (i in 1:length(indicators_list)){
      incProgress(1/length(indicators_list), detail = paste("Doing part", i))
      fetch.data[[i]] <- WDI(indicator = indicators_list[i],
                             start = startDate, 
                             end = endDate,
                             country = "all",
                             extra = TRUE)
  })

Полный пример

Вот полный пример, который мне удалось получить. Я включил только серверный компонент, как он есть единственный, где я внес изменения.

server <- function(input, output) {

  startDate <- as.numeric(format(Sys.Date(), "%Y")) -20
  endDate <- as.numeric(format(Sys.Date(), "%Y"))

  fetch.data <- list() 

  indicators_list <- c("SP.POP.TOTL",
                  "NY.ADJ.NNTY.PC.CD",
                  "SH.XPD.CHEX.PC.CD",
                  "SH.XPD.OOPC.CH.ZS",
                  "SH.MED.BEDS.ZS",
                  "SH.MED.PHYS.ZS",
                  "NY.GDP.MKTP.CD",
                  "NY.GDP.MKTP.KD",
                  "NY.GDP.MKTP.KD.ZG",
                  "SH.XPD.CHEX.GD.ZS",
                  "SP.DYN.LE00.IN",
                  "SP.POP.65UP.TO",
                  "SP.POP.DPND",
                  "SP.POP.DPND.OL") 

  withProgress(
    for (i in 1:length(indicators_list)){
      incProgress(1/length(indicators_list), detail = paste("Doing part", i))
      fetch.data[[i]] <- WDI(indicator = indicators_list[i],
                             start = startDate, 
                             end = endDate,
                             country = "all",
                             extra = TRUE)
  })

  data <- fetch.data


  for (i in 1:length(indicators_list)){

    data[[i]] <- subset(data[[i]], region != "Aggregates")
    data[[i]] <- data[[i]] %>% select(country, iso3c, region, year, noquote(indicators_list[i]))
    data[[i]]$date <- data[[i]]$year
    data[[i]] <- data[[i]][complete.cases(data[[i]][ ,5]),]
    data[[i]] <- data[[i]] %>% group_by(country) %>% arrange(desc(date)) %>% slice(1)
  }


  indicators <- fetch.data[[1]] %>% 
    select(country, iso3c, region) %>% 
    subset(region != "Aggregates") %>% 
    arrange(desc(country)) %>% 
    group_by(country) %>% 
    slice(1)


  for (i in 1:length(indicators_list)){
    indicators <- merge(indicators, data[[i]][ ,c(2,5)], by.x = "iso3c", by.y = "iso3c", all = TRUE)
  }


  indicators <- indicators %>% 
    arrange(country) %>% 
    mutate_if(is.numeric, round, 2)

  output$table <- renderTable(indicators)

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