2017-05-19 6 views
0

私はRとShinyの初心者です。私は原点と目的地のフローデータを探索するためのアプリケーションを構築しようとしていました。これは、原点ゾーン番号、目的地ゾーン番号、および情報フィールドの束、およびポリゴンとしてのゾーンのシェイプファイルを有するcsvを取り込み、特定のゾーンへのまたはそのゾーンからのフローを描写することを可能にする。私は実際に動作するシャイニーアプリを持っていますが、それはあまりにも非効率的であるか、またはこれはこの仕事のためのかなり適切なツールではないかもしれません。私は下のコードを貼り付けます。シェイプファイルからリーフレットマップを生成し、CSVが遅すぎるシャイニーなアプリ。大きなシェイプファイルでクラッシュする

私の問題は、メモリが多すぎるようです。ゾーンの数が少ない場合は動作しますが、非常に遅いです(最初に読み込むまでに時間がかかり、入力の1つが変更されるたびに更新されます)。より大きな問題は、私が大規模なゾーンシステムで何百、何千ものゾーンを持ち、数百万の頂点を持っていることです。これらの大きなゾーンシステムの1つにこれを適用しようとすると、最初はロードされますが、2つまたは3つの移動(ズームまたはパン)または1つの入力の変更だけでRStudioがクラッシュします。

これをより効率的にする方法があるのか​​、RStudio/Shinyがこのようなものに使用されることを意図していないのかどうか疑問に思っていました。私はあなたが少し説明を少し愚かにしたなら、私はそれを感謝するだろうので、私はほとんど最適化について無知だということに留意してください。

シェープファイルを読み込む
library(shiny) 
library(rgdal) 
library(sp) 
library(leaflet) 
library(RColorBrewer) 

shape <- readOGR(dsn=".", layer="zones") 
shape <- spTransform(shape, CRS("+init=EPSG:4326")) 

、そのデータ:

これは動作しますアプリです。 「i」および「j」は、発信元および宛先ゾーン番号です。また、マップするフィールドのリストが必要です。フィールドは完全に数値でなければなりません。私はループなしでそれをサブセット化する方法を考え出していない。それについての助けに感謝します。

values <- read.csv("values.csv") 
zonelist <- sort(unique(c(values$i, values$j))) 
zones <- length(zonelist) 
fieldlist <- as.vector(character()) 
fields <- 0 
for (valname in colnames(values)){ 
    if (valname != "i" & 
     valname != "j" & 
     is.numeric(values[[valname]]) 
    ) { 
     fields <- fields + 1 
     fieldlist[fields] <- valname 
     } 
} 

そして、私はそれらを行列mmに入れています。繰り返しますが、これを行うための効率的な方法があれば歓迎します。

mm <- array(numeric(), dim=c(fields,zones,zones)) 
mm[,,] <- 0 
valarray <- array(numeric(), dim=fields*zones*zones) 
valarray[] <- 0 
for (k in 1:length(values)){ 
    if (colnames(values)[k] %in% fieldlist) { 
    valarray[(values$j - 1) * zones * fields 
      + (values$i - 1) * fields 
      + which(colnames(values)[k] == fieldlist) 
      ] <- values[[k]] 
    } 
} 
mm[,,] <- valarray 

インターフェイスは単純です:参照ゾーンから/を選択し、参照ゾーンを選択し、マッピングする数値フィールドを選択します。フローのリーフレットマップを表示します。

ui <- fluidPage(
    titlePanel("Interzonal values mapping"), 
    sidebarLayout(
     sidebarPanel(
     selectInput(inputId = "ft", label = "From/to zone", choices = c("from", "to")), 
     selectInput(inputId = "zn", label = "Reference zone", choices = zonelist), 
     selectInput(inputId = "fl", label = "Field to map", choices = fieldlist), 
     width = 2 
    ), 
    mainPanel(leafletOutput("mapped_zonelist", height = 800), 
      width = 10) 
    ) 
) 

は、サーバは、入力に応じてマトリックスミリメートルからベクトルとして(VS)マッピングするフローをピックアップし、流量値に応じてゾーンマップをフォーマットします。

server <- function(input, output) { 
    m <- reactive({ 
    if (input$ft == "from"){ 
     vs <- mm[which(input$fl == fieldlist), as.numeric(input$zn), ] 
     } else { 
     vs <- mm[which(input$fl == fieldlist), , as.numeric(input$zn)] 
     } 

    c_weight <- numeric() 
    c_weight[1:zones] <- 1 
    c_weight[as.numeric(input$zn)] <- 2 
    c_color <- character() 
    c_color[1:zones] <- "blue" 
    c_color[as.numeric(input$zn)] <- "black" 

    leaflet() %>% 
     addTiles() %>% 
     addPolygons(data=shape, 
        fillOpacity = 0.7, 
        opacity = 0.8, 
        weight = c_weight[[email protected]$n], 
        color = c_color[[email protected]$n], 
        fillColor = colorNumeric(palette = brewer.pal(10, "RdBu"), domain = vs)(vs[[email protected]$n]), 
        popup = paste0("Zone ", input$zn, " to zone ", as.character([email protected]$n), 
            "<br>", 
            input$fl, " = ", vs) 
       ) 
    }) 
    output$mapped_zonelist <- renderLeaflet(m()) 
} 

shinyApp(ui = ui, server = server) 

助けてください。ありがとう!

+0

このコードを光沢のない場所で実行すると、正常に動作しますか? –

+0

サンプルファイルを提供して再現できますか? – Sab

答えて

0

シェイプファイルのサイズや複雑さによっては、最初に行うことは簡単です。通常の方法でシェイプファイルをロードしてください:

install.packages("rmapshaper") 
shape_simp <- rmapshaper::ms_simplify(shape, keep = 0.05) 

引数をkeep =と試してみてください。数値が大きいほど、得られるシェイプファイルの複雑さが大きくなります。これはあなたの問題を完全には解決できないかもしれませんが、それは始まりです。

+0

優秀なアイデア!シェイプファイルを読んだ後、最初に小切手を追加しました.10 MBを超える場合は10 MBを目標とするように簡略化します。残念ながら、単純化を行うには少し時間がかかりますが、そうでなければ素晴らしいです! –

+0

@ArlinConioリーフレットにロードする前にシェイプファイルを単純化します。また、10MBよりもずっと低くすることができます。あなたのニーズにもよりますが、1MB以下になることもあります - Philは55分前に – Phil

+0

あなたはそうです.1MBでも動作します。ご協力いただきありがとうございます! –

関連する問題