R leaflet/shiny: 根据列值显示和偏移重叠折线

R leaflet/shiny: display and offset overlapping polylines based on column value

我正在尝试扩展我在 R 中可以做的事情并且碰壁了,希望你能为我指明正确的方向,告诉我如何最好地完成我想做的事情。我正在从一个形状文件中绘制一堆折线,其数据如下所示:

placename,placetype,placebook,numbooks,row_number,placelinecoords
Main Street,street,"BOOKTDS",1,1,LINESTRING(-3.700559678237278 40.42098474661999,-3.698346475125229 40.42033268716025,-3.69731867182242 40.42003534594848,-3.697243299580215 40.42003534594848)
First Street,street,"BOOKESM",3,1,LINESTRING(-3.710546258545151 40.41308011176736,-3.710213664627304 40.41309440722183,-3.709234658336868 40.41341707524381,-3.708880606746902 40.4135232694443,-3.708711627578964 40.41372748858957)
First Street,street,"BOOKTDS",3,2,LINESTRING(-3.710546258545151 40.41308011176736,-3.710213664627304 40.41309440722183,-3.709234658336868 40.41341707524381,-3.708880606746902 40.4135232694443,-3.708711627578964 40.41372748858957)
First Street,street,"BOOKLDE",3,3,LINESTRING(-3.710546258545151 40.41308011176736,-3.710213664627304 40.41309440722183,-3.709234658336868 40.41341707524381,-3.708880606746902 40.4135232694443,-3.708711627578964 40.41372748858957)
Loughborough Street,street,"BOOKESM",2,1,LINESTRING(-3.707336328013795 40.42433623251054,-3.707014282978915 40.42429971916709,-3.706726498054129 40.42429971916709,-3.706281116622912 40.42409628731927,-3.705390353760477 40.42377288157678,-3.704602371228324 40.42316257940762,-3.70376642454204 40.42259400231908)
Loughborough Street,street,"BOOKTDS",2,2,LINESTRING(-3.707336328013795 40.42433623251054,-3.707014282978915 40.42429971916709,-3.706726498054129 40.42429971916709,-3.706281116622912 40.42409628731927,-3.705390353760477 40.42377288157678,-3.704602371228324 40.42316257940762,-3.70376642454204 40.42259400231908)
Oak Street,street,"BOOKLMI",2,1,LINESTRING(-3.700391803697817 40.41664973667679,-3.700384951675798 40.41673842198933,-3.699754565650076 40.4176044018386,-3.699549004989513 40.41782350340716)
Oak Street,street,"BOOKLBU",2,2,LINESTRING(-3.700391803697817 40.41664973667679,-3.700384951675798 40.41673842198933,-3.699754565650076 40.4176044018386,-3.699549004989513 40.41782350340716)

"placebook" 是出现特定街道名称的书籍的唯一代码。我已经为每本书分配了颜色并加载了数据:

books = c("OBRAESM", "OBRAHOR", "OBRAINS", "OBRALBU", "OBRALCT", "OBRALDB","OBRALDE","OBRALMI","OBRALPI","OBRATDS")
color = c("red", "orange", "yellow", "green", "blue", "pink","gray","purple","black","white")
df = cbind.data.frame(books,color)
colnames(df) = c("books","color")

placeographypaths <- readOGR("shapefiles/places_paths.shp")
placeographypathsstreets <- subset(placeographypaths, placetype %like% "street")

我想做的是按册将这些线绘制到地图上,每条线显示为不同的颜色。当有不止一本书分配给特定行时,我需要偏移这些行以便它们都可见。这些线会完全重叠,在大多数情况下,同一位置只会有几条线重叠(最多5条,但大多数是1-3条)。

所以"First Street"会显示三行:红色、灰色和白色。我看到有一个 PolylineOffset 工具,但我找不到任何使用列值作为偏移标准的示例——它似乎主要适用于更复杂的情况,其中只有一部分线重叠)——也许有我缺少的更简单的解决方案。

我花了一些时间思考我能做些什么,因为我不知道如何使用 PolylineOffset。似乎此功能将出现在传单包中。我想为您的可视化建议一个替代方案。阅读您的问题,您将有五种类型的线条。也就是说,每种线型都可以代表街道在您的数据集中出现的次数。你说最大重叠是五次。我认为您可以在分组变量中创建五个级别并在传单中创建颜色。

首先,我总结了您按地名分组的数据。对于每个地名,我计算了存在多少个数据点(行)。我还创建了一个包含书名的字符串。该字符串是为弹出窗口安排的。然后,我为传单创建了一个调色板。最后,我画了一张地图。如果你想要更高级的东西,我想你可以使用 htmlTable 包,例如。

library(dplyr)
library(leaflet)
library(sf)
library(viridis)

# Aggregate the data by placename. Note your data is called mysf, which is an
# sf object.

group_by(mysf, placename) %>% 
summarize(frequency = factor(n(), levels = 1:3, labels = c("1", "2", "3")),
          books = paste0("<br/>", paste0(placebook, collapse = "<br/>"))) -> mysf2

# Create categorical colors
# I am checking colors here
previewColors(colorFactor(palette = "viridis", domain = mysf2$frequency),
                          values = unique(mysf2$frequency))

# Create my own palette
mypal <- colorFactor(palette = "viridis", domain = mysf2$frequency)

# Draw a leaflet map
leaflet() %>% 
addProviderTiles("CartoDB.Positron") %>% 
addPolylines(data = mysf2, color = ~mypal(mysf2$frequency),
             popup = paste("Place: ", mysf2$placename, "<br>",
                           "Book(s): ", mysf2$books, "<br>")) %>% 
addLegend(position = "bottomright", pal = mypal, values = mysf2$frequency,
          title = "Frequency",
          opacity = 1)

最后一张纸条。不幸的是,您提供数据的方式对任何人都无法复制您的情况。 (我花了很多时间手动创建你的数据。如果我没有足够的时间我不会这样做。也许你也不想这样做,对吧?)如果你的数据很大,你要考虑上传它在别的地方。否则,您可以使用 dput() 创建数据副本。如果你仔细看 R 中的问题,很多用户提供他们的数据 dput()。强烈推荐大家以后提问的时候使用这个功能

数据

mysf <- structure(list(placename = structure(c(3L, 1L, 1L, 1L, 2L, 2L, 
4L, 4L), .Label = c("First Street", "Loughborough Street", "Main Street", 
"Oak Street"), class = "factor"), placetype = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "placetype", class = "factor"), 
placebook = structure(c(5L, 1L, 5L, 3L, 1L, 5L, 4L, 2L), .Label = c("BOOKESM", 
"BOOKLBU", "BOOKLDE", "BOOKLMI", "BOOKTDS"), class = "factor"), 
geometry = structure(list(structure(c(-3.70055967823728, 
-3.69834647512523, -3.69731867182242, -3.69724329958022, 
40.42098474662, 40.4203326871602, 40.4200353459485, 40.4200353459485
), .Dim = c(4L, 2L), class = c("XY", "LINESTRING", "sfg")), 
    structure(c(-3.71054625854515, -3.7102136646273, -3.70923465833687, 
    -3.7088806067469, -3.70871162757896, 40.4130801117674, 
    40.4130944072218, 40.4134170752438, 40.4135232694443, 
    40.4137274885896), .Dim = c(5L, 2L), class = c("XY", 
    "LINESTRING", "sfg")), structure(c(-3.71054625854515, 
    -3.7102136646273, -3.70923465833687, -3.7088806067469, 
    -3.70871162757896, 40.4130801117674, 40.4130944072218, 
    40.4134170752438, 40.4135232694443, 40.4137274885896), .Dim = c(5L, 
    2L), class = c("XY", "LINESTRING", "sfg")), structure(c(-3.71054625854515, 
    -3.7102136646273, -3.70923465833687, -3.7088806067469, 
    -3.70871162757896, 40.4130801117674, 40.4130944072218, 
    40.4134170752438, 40.4135232694443, 40.4137274885896), .Dim = c(5L, 
    2L), class = c("XY", "LINESTRING", "sfg")), structure(c(-3.70733632801379, 
    -3.70701428297891, -3.70672649805413, -3.70628111662291, 
    -3.70539035376048, -3.70460237122832, -3.70376642454204, 
    40.4243362325105, 40.4242997191671, 40.4242997191671, 
    40.4240962873193, 40.4237728815768, 40.4231625794076, 
    40.4225940023191), .Dim = c(7L, 2L), class = c("XY", 
    "LINESTRING", "sfg")), structure(c(-3.70733632801379, 
    -3.70701428297891, -3.70672649805413, -3.70628111662291, 
    -3.70539035376048, -3.70460237122832, -3.70376642454204, 
    40.4243362325105, 40.4242997191671, 40.4242997191671, 
    40.4240962873193, 40.4237728815768, 40.4231625794076, 
    40.4225940023191), .Dim = c(7L, 2L), class = c("XY", 
    "LINESTRING", "sfg")), structure(c(-3.70039180369782, 
    -3.7003849516758, -3.69975456565008, -3.69954900498951, 
    40.4166497366768, 40.4167384219893, 40.4176044018386, 
    40.4178235034072), .Dim = c(4L, 2L), class = c("XY", 
    "LINESTRING", "sfg")), structure(c(-3.70039180369782, 
    -3.7003849516758, -3.69975456565008, -3.69954900498951, 
    40.4166497366768, 40.4167384219893, 40.4176044018386, 
    40.4178235034072), .Dim = c(4L, 2L), class = c("XY", 
    "LINESTRING", "sfg"))), class = c("sfc_LINESTRING", "sfc"
), precision = 0, bbox = structure(c(xmin = -3.71054625854515, 
ymin = 40.4130801117674, xmax = -3.69724329958022, ymax = 40.4243362325105
), class = "bbox"), crs = structure(list(epsg = 4326L, proj4string = "+proj=longlat +datum=WGS84 +no_defs"), class = "crs"), n_empty = 0L)), row.names = c(NA, 
8L), sf_column = "geometry", agr = structure(c(placename = NA_integer_, 
placetype = NA_integer_, placebook = NA_integer_), class = "factor", .Label = c("constant", 
"aggregate", "identity")), class = c("sf", "data.frame"))