关于 r:如何根据闪亮的 inputselect 对数据框进行子集化并使用Leaflet进行绘图

How to subset a dataframe and plot with leaflet depending on inputselect in shiny

使用 Rstudio 我正在尝试制作一个闪亮的应用程序,它可以生成Leaflet输出。请注意,shiny 是我以前从未使用过的包,因此脚本中可能存在除我目前遇到的错误之外的其他错误。

我正在使用一个数据框,其中包含不同个体的轨迹,我想从中提取子集并绘制一只动物的轨迹以响应输入选择。

1
2
3
4
5
6
7
8
9
Sample:

WhaleID     lat       long
gm08_150c   68,4276   16,5192
gm08_150c   68,4337   16,5263
gm08_150c   68,4327   16,5198
gm08_154d   68,4295   16,5243
gm08_154d   68,4313   16,5314
gm08_154d   68,4281   16,5191

输入选择中的选项是 .csv 文件中使用的确切名称,在列 WhaleID 中,因此我希望子集包含来自主数据框中具有该 WhaleID 的所有行。

在此子集之后,我只想从先前子集化的数据帧中对"long"和"lat"列进行子集化。然后通过Leaflet读取该数据帧。

最后一步是在地图上绘制这些"long"和"lat"位置。

不幸的是,我不断收到错误消息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Warning: Error in $: object of type 'closure' is not subsettable
Stack trace (innermost first):
    82: inherits
    81: resolveFormula
    80: derivePolygons
    79: addPolylines
    78: function_list[[i]]
    77: freduce
    76: _fseq
    75: eval
    74: eval
    73: withVisible
    72: %>%
    71: func [#15]
    70: output$map
     4: <Anonymous>
     3: do.call
     2: print.shiny.appobj
     1: <Promise>

我使用的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    require(shiny)
    require(leaflet)

    ##Main dataframe I want to subset depending on inputselection    
    dataframe <-read.csv2("PW_with_speedbearingturn.csv")


    ui <- bootstrapPage(
      tags$style(type ="text/css","html, body {width:100%;height:100%}"),
      absolutePanel(top = 10, right = 10,
      selectInput(inputId ="whaleID",
                  label ="Select a whale",
                  choices = c("gm08_150c","gm08_154d"))),
      leafletOutput(outputId ="map", width ="100%", height ="700")
    )

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

      #?observeEvent  
      #observeEvent(input$whaleID, )
      Start <- makeIcon(
        iconUrl ="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Dark_Green_Arrow_Down.svg/480px-Dark_Green_Arrow_Down.svg.png",
        iconWidth = 22, iconHeight = 20,
        iconAnchorX = 11, iconAnchorY = 20)

      eventReactive(input$whaleID,{
                    df<-subset(dataframe, WhaleID =="input$whaleID") ##"input$whaleID" should become the WhaleID that is selected from the inputselect.

                    df<-subset(df, select = c("long","lat"))
      })                
      output$map <- renderLeaflet({
      leaflet() %>%
      addTiles() %>%
      addPolylines(df, lng = df$long, lat = df$lat, col ="grey", opacity = 1)%>%
      addMarkers(df, lng = first(df$long), lat = first(df$lat), icon = Start, popup ="Start")
      })
    }

    shinyApp(ui = ui, server = server)

我相信它与 eventreactive 部分和其中的子集部分有关。每次都必须更新它以响应从输入选择中选择的选择。不幸的是,我找不到这个问题的任何现有解决方案。

关于如何解决这个问题有什么建议吗?

提前致谢,

Onno


我认为您可以完全避免使用 eventReactive,因为 renderLeaflet 将对 input 的更改做出反应。这是一个改编的例子,因为我没有你的数据。如果没有意义,请告诉我。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
require(shiny)
require(leaflet)

##Main dataframe I want to subset depending on inputselection    
dataframe <- data.frame(
  abb = state.abb,
  x = state.center$x,
  y = state.center$y,
  stringsAsFactors = FALSE
)


ui <- bootstrapPage(
  tags$style(type ="text/css","html, body {width:100%;height:100%}"),
  absolutePanel(top = 10, right = 10,
                selectInput(inputId ="whaleID",
                            label ="Select a state",
                            choices = dataframe[["abb"]])),
  leafletOutput(outputId ="map", width ="100%", height ="700")
)

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

  Start <- makeIcon(
    iconUrl ="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Dark_Green_Arrow_Down.svg/480px-Dark_Green_Arrow_Down.svg.png",
    iconWidth = 22, iconHeight = 20,
    iconAnchorX = 11, iconAnchorY = 20)


  output$map <- renderLeaflet({
    df <- subset(dataframe, abb == input$whaleID)
    leaflet() %>%
      addTiles() %>%
      #addPolylines(df, lng = df$long, lat = df$lat, col ="grey", opacity = 1)%>%
      addMarkers(data = df, lng = ~x, lat = ~y, icon = Start, popup ="Start")
  })
}

shinyApp(ui = ui, server = server)


有点晚了,但为了完整性并说明如何使用 eventReactive 来做到这一点。
您必须为其分配一个名称,然后调用 eventReactive (df()),否??则它将永远不会运行。

此外,如果您将 input$whaleID 放在括号中,它将对 "input$whaleID" 的数据帧列进行子集化,我认为该列不在数据帧中。因此你想要它没有括号,所以它从 selectInput.

中获取 selected 参数

您也可以将图标放在服务器之外,因为它不必是被动的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
require(shiny)
require(leaflet)
require(dplyr)

##Main dataframe I want to subset depending on inputselection    
dataframe <- read.csv2("PW_with_speedbearingturn.csv")

Start <- makeIcon(
  iconUrl ="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Dark_Green_Arrow_Down.svg/480px-Dark_Green_Arrow_Down.svg.png",
  iconWidth = 22, iconHeight = 20,
  iconAnchorX = 11, iconAnchorY = 20)

ui <- bootstrapPage(
  tags$style(type ="text/css","html, body {width:100%;height:100%}"),
  absolutePanel(top = 10, right = 10,
                selectInput(inputId ="whaleID",
                            label ="Select a whale",
                            choices = c("gm08_150c","gm08_154d"))),
  leafletOutput(outputId ="map", width ="100%", height ="700")
)

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

  df <- eventReactive(input$whaleID,{
    daf <- subset(dataframe, WhaleID == input$whaleID)
    subset(daf, select = c("long","lat"))
  })  

  output$map <- renderLeaflet({
    leaflet() %>%
      addTiles() %>%
      addPolylines( lng = df()$long, lat = df()$lat, col ="red", opacity = 1)%>%
      addMarkers( lng = first(df()$long), lat = first(df()$lat), icon = Start,
                  popup ="Start")
  })
}

shinyApp(ui = ui, server = server)