Реактивное чтение и рендеринг шейп файла - PullRequest
0 голосов
/ 28 мая 2018

Моя цель - визуализировать реактивную карту с помощью Shiny + Leaflet: я хочу использовать два перекрывающихся слоя: "confini.comuni.WGS84" и "confini.asl.WGS84" , на котором можно нарисовать реактивный слой.

На основе значения 'inputId = "Year.map"' сервер считывает слой 'zone.WGS84' ('layer = paste0 ("zone_", anno.map ())', EX "zone_2015") и раскрашивает полигоны на основезначение одного из полей в фрейме данных ("SIST_NERV", "MESOT", "TUM_RESP") , выбранное с помощью 'inputId = "Pathology.map"'.

Шейп-файлы "zone_2000.shp" и т. Д. Хранятся в "Приложение / формы / зона" , шейп-файлы "rt.confini.comunali.shp" и "rt.confini.regionali.shp " хранятся в " App / shape / originali "

Приложение и файлы здесь :

Данные.кадр, связанный с файлом формы "zone_2016":

 EXASLNOME                     Anno SIST_NERV SIST_NERVp MESOT MESOTp TUM_RESP TUM_RESPp
 Az. USL 1 di Massa Carrara    2016        43         41     1      1        4         4     
 Az. USL 2 di Lucca            2016        45         45    11     10        3         3
 Az. USL 3 di Pistoia          2016        26         21    13     13        5         5
 Az. USL 4 di Prato            2016         6          6     8      8       NA        NA
 Az. USL 5 di Pisa             2016       155        146     3      3        2         2
 Az. USL 6 di Livorno          2016       137        136    17     17       20        18
 Az. USL 7 di Siena            2016        29         24     1      1       NA        NA
 Az. USL 8 di Arezzo           2016        31         29     3      3        2         2
 Az. USL 9 di Grosseto         2016        35         34     2      2        1         1
 Az. USL 10 di Firenze         2016        34         33    24     13       11         4
 Az. USL 11 di Empoli          2016        30         29     2      2       20        20
 Az. USL 12 di Viareggio       2016       130        129     7      7        3         3 

Далее Leaflet должен создать реактивную метку, основанную на данных 'EXASLNOME' и 'pat.map()' data.frame.Наконец, карта map() должна быть сгенерирована с помощью renderLeaflet, отправленного на output$Map.ASL.Это приводит к этой ошибке:

Предупреждение: Ошибка в домене: не удалось найти функцию «домен» Трассировка стека (самая внутренняя в первую очередь): 91: colorQuantile 90: [C: / Users / User / Downloads / Prova_mappe/App_per_Stackoverflow.r#63] 79: mappa 78: func [C: /Users/User/Downloads/Prova_mappe/App_per_Stackoverflow.r#95] 77: origRenderFunc 76: вывод $ Mappa.ASL 1: runApp

Я не могу использовать все реактивные компоненты для передачи в качестве параметров функции Leaflet, вы можете мне что-нибудь сказать?

  require(shiny)
  require(stringr)
  require(shinythemes)
  require(leaflet)
  require(RColorBrewer)
  require(rgdal)
  require(rgeos)

  #### UI ####
  ui <- fluidPage(
    theme = shinytheme("spacelab"),
    titlePanel("Indice"),
    navlistPanel( 
      tabPanel(title = "Mappe",
         fluidRow(column(6, sliderInput(inputId = "Anno.map",
                                        label = "Anno di manifestazione",
                                        min = 2000,
                                        max = 2016, 
                                        value = 2016,
                                        step = 1,
                                        ticks = FALSE,
                                        sep = "")),
                  column(6, selectInput(inputId = "Patologia.map",
                                        label = "Patologia",
                                        choices = list("SIST_NERV", "MESOT","TUM_RESP"),
                                        selected = "SIST_NERV",
                                        multiple = FALSE))),
         fluidRow(column(6, leafletOutput(outputId = "Mappa.ASL", height = "600px", width = "100%")))
    )
   )
  )

 #### SERVER ####
 server <- function(input, output) {

    # NOT REACTIVE 
    confini.comuni <- readOGR(dsn = "shapes/originali", layer = "rt.confini.comunali", stringsAsFactors = FALSE)
    confini.comuni.WGS84 <- spTransform(confini.comuni, CRS("+proj=longlat +datum=WGS84 +no_defs")) 

    confini.asl <- readOGR(dsn = "shapes/originali", layer = "rt.confini.asl", stringsAsFactors = FALSE)
    confini.asl.WGS84 <- spTransform(confini.asl, CRS("+proj=longlat +datum=WGS84 +no_defs"))

    # REACTIVE 
    anno.map <- reactive({input$Anno.map})

    pat.map <- reactive({input$Patologia.map})

    mappa <- reactive({                                                         
        zone.WGS84 <- spTransform(readOGR(dsn = "shapes/zone", 
                                  layer = paste0("zone_", anno.map()), stringsAsFactors = FALSE), 
                                  CRS("+proj=longlat +datum=WGS84 +no_defs"))           

        domain <- paste0("zone_", anno.map(), "@data$", pat.map())
        labels.1 <- paste0("zone_", anno.map(), "@data$EXASLNOME")
        labels.2 <- paste0("zone_", anno.map(), "@data$", pat.map())
        labels.3 <- paste0("zone_", anno.map(), "@data$", pat.map(), "p")

        pal <- colorQuantile(palette = "YlOrRd",  
                             domain = domain(), n = 6,
                             na.color = "808080", alpha = FALSE, reverse = FALSE, right = FALSE)
        labels <- sprintf("<strong>%s</strong><br/>%g Segnalazioni<br/> %g con nesso positivo",
                   labels.1(), labels.2(), labels.3()) %>% 
                   lapply(htmltools::HTML)    

    leaflet(options = leafletOptions(zoomControl = FALSE, dragging = FALSE, minZoom = 7.5, maxZoom = 7.5)) %>%   
            addPolygons(data = confini.comuni.WGS84,
            weight = 1,
            opacity = 1,
            color = "black") %>%
    addPolygons(data = confini.asl.WGS84,
                weight = 2,
                opacity = 1,
                color = "red")  %>%      
    addPolygons(data = zone.WGS84(), 
                fillColor = ~pal(domain()),
                weight = 2,
                opacity = 1,
                color = "white",
                dashArray = "3",
                fillOpacity = 0.7,
                highlight = highlightOptions(weight = 5,
                                             color = "666",
                                             dashArray = "",
                                             fillOpacity = 0.7,
                                             bringToFront = TRUE),
                label = labels())
    })


   output$Mappa.ASL <- renderLeaflet({mappa()})

  }

  # Run the application 
  shinyApp(ui = ui, server = server)

Ответы [ 3 ]

0 голосов
/ 29 мая 2018

Спасибо, я попытался последовать вашему совету: я создал data.frame из фигуры, используя

map <- reactive({readOGR(dsn = "shapes/zone", 
                         layer = paste0("zone_", anno.map()), stringsAsFactors = FALSE)})

map.df <- reactive({map() %>% 
                    as.data.frame() %>% 
                    select(EXASLNOME, pat.map(), pat.map.p())})

Обратите внимание, что "map" и "map.df" являются реактивными.

"pat.map" - это имя столбца data.frame "map.df", взятого в качестве входного значения (input $ Pathology.map), а "pat.map.p" - это имя другого столбцатот же data.frame.Я использовал числовое поле map.df () [, 2] в качестве параметра «domain» функции «pal»

pal <- colorQuantile(palette = "YlOrRd",  
                            domain = map.df()[,2], 
                            n = 6,  
                            na.color = "808080", 
                            alpha = FALSE, 
                            reverse = FALSE, 
                            right = FALSE)

Я также создал реактивную метку с

labels <- sprintf("<strong>%s</strong> <br/> %d Segnalazioni <br/> %d con nesso positivo",
                            map.df()[,1], map.df()[,2], map.df()[,3]) %>% 
                            lapply(htmltools::HTML)

Это новый скрипт

require(shiny)
require(stringr)
require(shinythemes)
require(leaflet)
require(RColorBrewer)
require(rgdal)
require(rgeos)

#### UI ####
ui <- fluidPage(
    theme = shinytheme("spacelab"),
    titlePanel("Indice"),
    navlistPanel( 
        tabPanel(title = "Mappe",
                fluidRow(column(6, sliderInput(inputId = "Anno.map",
                                               label = "Anno di manifestazione",
                                               min = 2000,
                                               max = 2016, 
                                               value = 2016,
                                               step = 1,
                                               ticks = FALSE,
                                               sep = "")),
                        column(6, selectInput(inputId = "Patologia.map",
                                              label = "Patologia",
                                              choices = list("SIST_NERV", "MESOT","TUM_RESP"),
                                              selected = "SIST_NERV",
                                              multiple = FALSE))),
                fluidRow(column(6, leafletOutput(outputId = "Mappa.ASL", height = "600px", width = "100%")))
        )
    )
)

#### SERVER ####
server <- function(input, output) {

# NOT REACTIVE 
confini.comuni <- readOGR(dsn = "shapes/originali", layer = "rt.confini.comunali", stringsAsFactors = FALSE)
confini.comuni.WGS84 <- spTransform(confini.comuni, CRS("+proj=longlat +datum=WGS84 +no_defs")) 

confini.zone <- readOGR(dsn = "shapes/originali", layer = "rt.confini.exasl", stringsAsFactors = FALSE)
confini.zone.WGS84 <- spTransform(confini.zone, CRS("+proj=longlat +datum=WGS84 +no_defs"))

confini.asl <- readOGR(dsn = "shapes/originali", layer = "rt.confini.asl", stringsAsFactors = FALSE)
confini.asl.WGS84 <- spTransform(confini.asl, CRS("+proj=longlat +datum=WGS84 +no_defs"))

mappa.base <- leaflet(options = leafletOptions(zoomControl = FALSE, 
                                             dragging = FALSE, 
                                             minZoom = 7.5, 
                                             maxZoom = 7.5)) %>%   
addPolygons(data = confini.comuni.WGS84,
            weight = 1,
            opacity = 1,
            color = "black") %>%   
addPolygons(data = confini.zone.WGS84,
            weight = 2,
            opacity = 1,
            color = "black")

# REACTIVE 
anno.map <- reactive({input$Anno.map})
pat.map <- reactive({input$Patologia.map})
pat.map.p <- reactive({paste0(pat.map(), "p")})

map <- reactive({spTransform(readOGR(dsn = "shapes/zone", 
                             layer = paste0("zone_", anno.map()), stringsAsFactors = FALSE),
                             CRS("+proj=longlat +datum=WGS84 +no_defs"))}) 

map.df <- reactive({map() %>% 
                    as.data.frame() %>% 
                    select(EXASLNOME, pat.map(), pat.map.p())})

mappa <- reactive({             
        pal <- colorQuantile(palette = "YlOrRd",  
                            domain = map.df()[,2], 
                            n = 6,  
                            na.color = "808080", 
                            alpha = FALSE, 
                            reverse = FALSE, 
                            right = FALSE)

        labels <- sprintf("<strong>%s</strong> <br/> %d Segnalazioni <br/> %d con nesso positivo",
                            map.df()[,1], map.df()[,2], map.df()[,3]) %>% 
                            lapply(htmltools::HTML)

        leafletProxy(mapId = "mappa.base", data = map()) %>%
        addPolygons(fillColor = ~pal(map.df()[,2]),
                    weight = 2,
                    opacity = 1,
                    color = "white",
                    dashArray = "3",
                    fillOpacity = 0.7,
                    highlight = highlightOptions(weight = 5,
                                                 color = "666",
                                                 dashArray = "",
                                                 fillOpacity = 0.7,
                                                 bringToFront = TRUE),
                    label = labels()
                    )
        })


    output$Mappa.ASL <- renderLeaflet({mappa()})

}

# Run the application 
shinyApp(ui = ui, server = server)

при запуске приложения, похоже, проблема с "ярлыками"

> runApp('App')

Listening on http://127.0.0.1:3307
OGR data source with driver: ESRI Shapefile 
Source: "shapes/originali", layer: "rt.confini.comunali"
with 274 features
It has 11 fields
OGR data source with driver: ESRI Shapefile 
Source: "shapes/originali", layer: "rt.confini.exasl"
with 12 features
It has 2 fields
OGR data source with driver: ESRI Shapefile 
Source: "shapes/originali", layer: "rt.confini.asl"
with 3 features
It has 1 fields
OGR data source with driver: ESRI Shapefile 
Source: "shapes/zone", layer: "zone_2016"
with 12 features
It has 40 fields
Warning: Error in labels.default: argument "object" is missing, with no default
Stack trace (innermost first):
    108: labels.default
    107: labels
    106: safeLabel
    105: evalAll
    104: evalFormula
    103: invokeMethod
    102: eval
    101: eval
    100: %>%
    99: addPolygons
    98: function_list[[k]]
    97: withVisible
    96: freduce
    95: _fseq
    94: eval
    93: eval
    92: withVisible
    91: %>%
    90: <reactive:mappa> [S:\ProgettiR\ReportMalprof_ShinyApp\App/app.R#86]
    79: mappa
    78: func [S:\ProgettiR\ReportMalprof_ShinyApp\App/app.R#103]
    77: origRenderFunc
    76: output$Mappa.ASL
    1: runApp
0 голосов
/ 02 июня 2018

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

Прежде всего, вы можете поместить все нереактивные значения вне функции сервера и, возможно, вам следует сохранить confini. * shapefiles в RDS-файл или БД и загрузить их оттуда.Я предполагаю, что это ускорит ваше приложение.


Ваш листовой график никогда не показывался, потому что вы визуализировали объект mappa () в выходной ID = Mappa.ASL.Реактивная маппа, тем не менее, не создает карту, так как она не возвращает карту или какой-либо объект, поэтому вы должны изменить reactive на observer.LeafletProxy просто добавляет материал на исходную карту (в вашем случае mappa.base), который вы никогда не использовали в пользовательском интерфейсе.


Ваша ошибка произошла из-за вызова labels = labels() в addPolygons, как если бы метки были реактивным объектом, но вы определили его в той же реактивной среде, поэтому вы вызываете его без скобок, например:

labels = labels


Вместо того, чтобы делать реактивные значения из них:

anno.map <- reactive({input$Anno.map})
pat.map <- reactive({input$Patologia.map})
pat.map.p <- reactive({paste0(pat.map(), "p")})

Вы можете просто использовать их в качестве реактивов, таких как:

input$Anno.map
input$Patologia.map
paste0(pat.map(), "p")

Я бы также не использовал реактив (map), который всегда считывает шейп-файл с диска и сразу же перепроектирует его.Можете ли вы объединить их вместе в один шейп-файл, а затем отфильтровать и перепроектировать их заранее, чтобы вам не приходилось делать это каждый раз, когда вызывается приложение?

Следующее приложение должно работать.По крайней мере, немного, так как вы будете работать с ошибками в функции colorQuantile, как эта, поскольку в наборах данных есть значения NA (например, годы 2009-2006 для 'SIST_NERV')

Предупреждение: Ошибка в cut.default: 'breaks' не являются уникальными

Вы можете просто изменить colorQuantile на colorBin и удалить аргумент n = 6.

require(shiny)
require(stringr)
require(shinythemes)
require(leaflet)
require(RColorBrewer)
require(rgdal)
require(rgeos)


# NOT REACTIVE 
confini.comuni <- readOGR(dsn = "shapes/originali", layer = "rt.confini.comunali", stringsAsFactors = FALSE)
confini.comuni.WGS84 <- spTransform(confini.comuni, CRS("+proj=longlat +datum=WGS84 +no_defs"))

confini.zone <- readOGR(dsn = "shapes/originali", layer = "rt.confini.exasl", stringsAsFactors = FALSE)
confini.zone.WGS84 <- spTransform(confini.zone, CRS("+proj=longlat +datum=WGS84 +no_defs"))

confini.asl <- readOGR(dsn = "shapes/originali", layer = "rt.confini.asl", stringsAsFactors = FALSE)
confini.asl.WGS84 <- spTransform(confini.asl, CRS("+proj=longlat +datum=WGS84 +no_defs"))


#### UI ####
ui <- {fluidPage(
  theme = shinytheme("spacelab"),
  titlePanel("Indice"),
  navlistPanel( 
    tabPanel(title = "Mappe",
             fluidRow(column(6, sliderInput(inputId = "Anno.map",
                                            label = "Anno di manifestazione",
                                            min = 2000, max = 2016, value = 2016, step = 1,
                                            ticks = FALSE, sep = "")),
                      column(6, selectInput(inputId = "Patologia.map",
                                            label = "Patologia", choices = list("SIST_NERV", "MESOT","TUM_RESP"),
                                            selected = "SIST_NERV", multiple = FALSE))),
             fluidRow(column(6, 
                             leafletOutput(outputId = "mappa.base", height = "600px", width = "100%")
                             ))
    )
  )
)}


#### SERVER ####
server <- function(input, output) {

  # REACTIVE 
  map <- reactive({
    req(input$Anno.map)
    spTransform(readOGR(dsn = "shapes/zone", layer = paste0("zone_", input$Anno.map), stringsAsFactors = FALSE),
                CRS("+proj=longlat +datum=WGS84 +no_defs"))
  })

  output$mappa.base <- renderLeaflet({
    leaflet(options = leafletOptions(zoomControl = FALSE, dragging = FALSE, 
                                     minZoom = 7.5, maxZoom = 7.5)) %>%   
      addTiles() %>% 
      addPolygons(data = confini.comuni.WGS84,
                  weight = 1, opacity = 1, color = "black") %>%
      addPolygons(data = confini.zone.WGS84,
                  weight = 2, opacity = 1, color = "black")
  })


  map.df <- reactive({
    req(input$Anno.map)
    map() %>%
      as.data.frame() %>%
      dplyr::select(EXASLNOME, input$Patologia.map, paste0(input$Patologia.map, "p"))
  })

  mappa <- observe({
    pal <- colorQuantile(palette = "YlOrRd",  domain = map.df()[,2],
                         n = 6,  na.color = "808080",
                         alpha = FALSE, reverse = FALSE,
                         right = FALSE)

    labels <- sprintf("<strong>%s</strong> <br/> %d Segnalazioni <br/> %d con nesso positivo",
                      map.df()[,1], map.df()[,2], map.df()[,3]) %>% lapply(htmltools::HTML)

    leafletProxy(mapId = "mappa.base", data = map()) %>%
      addPolygons(fillColor = ~pal(map.df()[,2]),
                  weight = 2,
                  opacity = 1,
                  color = "white",
                  dashArray = "3",
                  fillOpacity = 0.7,
                  highlight = highlightOptions(weight = 5,
                                               color = "666",
                                               dashArray = "",
                                               fillOpacity = 0.7,
                                               bringToFront = TRUE),
                  label = labels
      )
  })
}

# Run the application 
shinyApp(ui = ui, server = server)
0 голосов
/ 28 мая 2018

Ошибка msg должна быть совершенно ясной.Вы используете функцию domain(), которую вы никогда не назначали.

ColorQuantile требуется числовые значения для домена, поэтому необходимо указать столбец с числовыми значениями в нем.На их основе листовка выдаст цвета.

 pal <- colorQuantile(palette = "YlOrRd",  
                             domain =  dataframe$numericVariable, 
                             n = 6,
                             na.color = "808080", 
                             alpha = FALSE, reverse = FALSE, 
                             right = FALSE)

и изменит эту строку во второй функции addPolygon:

fillColor = pal(dataframe$numericVariable),

Вам необходимо адаптировать dataframe$numericVariable к столбцуваш data.frame, который вы хотите использовать для раскраски.

См. следующий пример:

library(shiny)
library(leaflet)

dataframe <- data.frame(
  x = runif(n = 40, 15, 18),
  y = runif(n = 40, 50, 55),
  numericVariable = runif(n = 40, 1, 100)
)

ui <- fluidPage(
  leafletOutput("map")
)

server <- function(input, output){

  output$map <- renderLeaflet({
    pal <- colorQuantile(palette = "YlOrRd",  
                         domain =  dataframe$numericVariable, 
                         n = 6,
                         na.color = "808080", 
                         alpha = FALSE, reverse = FALSE, 
                         right = FALSE)

    leaflet() %>% 
      addTiles() %>% 
      addCircleMarkers(lng = ~x, lat = ~y, data=dataframe, 
                       fillColor = pal(dataframe$numericVariabl), fillOpacity = 1)
  })
}
shinyApp(ui, server)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...