In R leaflet interactive map, all my values get incorrectly displayed (while values inside data frames are all correct)

huangapple go评论76阅读模式
英文:

In R leaflet interactive map, all my values get incorrectly displayed (while values inside data frames are all correct)

问题

由于某种原因,尽管数据框中的叙利亚的值为1,但在绘制地图时它显示为0.038,并被称为白俄罗斯... 所有其他国家也获得了一些疯狂的值和其他国家的名称... 我不明白为什么会发生这种情况。以下是代码...

  1. #libraries
  2. library(tidyverse)
  3. library(leaflet)
  4. library(rnaturalearth)
  5. library(rnaturalearthdata)
  6. library(sf)
  7. library(countrycode)
  8. #load world data from natural earth
  9. world <- ne_countries(scale = "large", returnclass = "sf")
  10. world <- st_transform(world, "+proj=longlat +datum=WGS84")
  11. countrynames <- countryname_dict %>%
  12. group_by(country.name.en) %>%
  13. summarise(country.name.en) %>%
  14. distinct()
  15. countrynames <- dplyr::pull(countrynames, country.name.en)
  16. # 这些值是随机的,只是为了测试地图。我希望每个国家都有一个基于0到1之间某些随机数字的颜色比例。在数据框中,它们确实都在0到1之间
  17. world_values <- c(1:284)
  18. df <- cbind(countrynames, world_values)
  19. df <- as.data.frame(df)
  20. df$world_values <- as.numeric(df$world_values)
  21. df$world_values[241] <- 599
  22. df <- df %>%
  23. mutate(Value = world_values / 599)
  24. # 将世界数据中的国家代码与国家名称匹配
  25. df$iso_a3 <- countrycode(sourcevar = countrynames, origin = "country.name", destination = "iso3c")
  26. df <- df %>% na.omit()
  27. map <- leaflet() %>%
  28. addProviderTiles("Esri.WorldGrayCanvas") %>%
  29. setView(lng = 0, lat = 0, zoom = 2)
  30. palette <- colorNumeric(
  31. palette = "Blues",
  32. domain = c(0,1)
  33. )
  34. # 添加国家多边形图层
  35. map <- map %>%
  36. addPolygons(
  37. data = world,
  38. stroke = TRUE,
  39. fillColor = ~palette(df$Value),
  40. fillOpacity = 0.5,
  41. popup = ~paste("Country:", df$countrynames, "<br>", "Value:", df$Value),
  42. color = "white",
  43. weight = 1,
  44. layerId = ~iso_a3,
  45. label = NULL
  46. )
  47. # 打印地图
  48. map

我已经尝试过更改layerId、fillColor、palette和popup到其他值,但无济于事。

英文:

For some reason, despite the fact Syria in the dataframe has Value = 1, when I plot the map it shows up as 0.038 and is called Belarus... and all the other countries also get some crazy values and other country names... I don't understand why it happens. Here is the code...

  1. #libraries
  2. library(tidyverse)
  3. library(leaflet)
  4. library(rnaturalearth)
  5. library(rnaturalearthdata)
  6. library(sf)
  7. library(countrycode)
  8. #load world data from natural earth
  9. world &lt;- ne_countries(scale = &quot;large&quot;, returnclass = &quot;sf&quot;)
  10. world &lt;- st_transform(world, &quot;+proj=longlat +datum=WGS84&quot;)
  11. countrynames &lt;- countryname_dict %&gt;%
  12. group_by(country.name.en) %&gt;%
  13. summarise(country.name.en) %&gt;%
  14. distinct()
  15. countrynames &lt;- dplyr::pull(countrynames, country.name.en)
  16. # These values are random just to test out mapping. I wanted for each country to have a color based on the ratio between 0 and 1 with some random numbers. All of them ARE indeed between 0 and 1 in the data frame
  17. world_values &lt;- c(1:284)
  18. df &lt;- cbind (countrynames, world_values)
  19. df &lt;- as.data.frame(df)
  20. df$world_values &lt;- as.numeric(df$world_values)
  21. df$world_values[241] &lt;- 599
  22. df &lt;- df %&gt;%
  23. mutate(Value = world_values / 599)
  24. # Match country codes in world data with countrynames
  25. df$iso_a3 &lt;- countrycode(sourcevar = countrynames, origin = &quot;country.name&quot;, destination = &quot;iso3c&quot;)
  26. df &lt;- df %&gt;% na.omit()
  27. map &lt;- leaflet() %&gt;%
  28. addProviderTiles(&quot;Esri.WorldGrayCanvas&quot;) %&gt;%
  29. setView(lng = 0, lat = 0, zoom = 2)
  30. palette &lt;- colorNumeric(
  31. palette = &quot;Blues&quot;,
  32. domain = c(0,1)
  33. )
  34. # Add country polygons layer
  35. map &lt;- map %&gt;%
  36. addPolygons(
  37. data = world,
  38. stroke = TRUE,
  39. fillColor = ~palette(df$Value),
  40. fillOpacity = 0.5,
  41. popup = ~paste(&quot;Country:&quot;, df$countrynames, &quot;&lt;br&gt;&quot;, &quot;Value:&quot;, df$Value),
  42. color = &quot;white&quot;,
  43. weight = 1,
  44. layerId = ~iso_a3,
  45. label = NULL
  46. )
  47. # Print the map
  48. map

I have tried changing layerId, fillColor, palette and popup to other things. I'm at wits' end.

答案1

得分: 0

你在leaflet中使用了一个数据集来表示多边形,另一个数据集用于属性数据。我猜这种方法只有在worlddf中的行数和国家顺序匹配时才能正常工作,但目前world的前三个国家是印度尼西亚、马来西亚和智利,而在df中,前三个国家是阿富汗、奥兰群岛和阿尔巴尼亚。

如果你尝试让这两个数据集匹配,仍然会很脆弱且难以调试,所以在大多数情况下,你可能希望将属性表与空间数据集连接,并在地图库中使用它。这也是leaflet中公式(~)符号的基础,其中data = world, fillColor = ~ palette(Value)的意思是:
使用world数据框中的Value列来计算fillColor

  1. library(dplyr)
  2. library(leaflet)
  3. library(rnaturalearth)
  4. library(sf)
  5. library(countrycode)
  6. # 只包含国家多边形和A3代码的sf对象
  7. world_sf <- ne_countries(scale = "large", returnclass = "sf") %>%
  8. as_tibble() %>%
  9. st_as_sf() %>%
  10. select(adm0_a3)
  11. world_sf
  12. #> Simple feature collection with 258 features and 1 field
  13. #> Geometry type: MULTIPOLYGON
  14. #> Dimension: XY
  15. #> Bounding box: xmin: -180 ymin: -90 xmax: 180 ymax: 83.6341
  16. #> Geodetic CRS: WGS 84
  17. #> # A tibble: 258 × 2
  18. #> adm0_a3 geometry
  19. #> <chr> <MULTIPOLYGON [°]>
  20. #> 1 IDN (((117.7036 4.163415, 117.7036 4.163415, 117.7381 4.157242, 117.7836…
  21. #> 2 MYS (((117.7036 4.163415, 117.6971 4.169053, 117.6441 4.215237, 117.6401…
  22. #> 3 CHL (((-69.51009 -17.50659, -69.50611 -17.58513, -69.49712 -17.6214, -69…
  23. # 第二个数据集,只有属性
  24. df_ <- distinct(countryname_dict, countrynames = country.name.en) %>%
  25. as_tibble() %>%
  26. mutate(world_values = row_number() / 599,
  27. world_values = if_else(countrynames == "Syria", 1, world_values),
  28. iso_a3 = countrycode(countrynames, "country.name", "iso3c")) %>%
  29. na.omit()
  30. df_
  31. #> # A tibble: 247 × 3
  32. #> countrynames world_values iso_a3
  33. #> <chr> <dbl> <chr>
  34. #> 1 Afghanistan 0.00167 AFG
  35. #> 2 Åland Islands 0.00334 ALA
  36. #> 3 Albania 0.00501 ALB
  37. #> ...
  38. # 通过 world_sf$adm0_a3 == df_$iso_a3 连接数据集,内连接只保留两个数据集中都存在的记录
  39. leaflet_sf <- inner_join(world_sf, df_, by = join_by(adm0_a3 == iso_a3))
  40. leaflet_sf
  41. #> Simple feature collection with 232 features and 3 fields
  42. #> Geometry type: MULTIPOLYGON
  43. #> Dimension: XY
  44. #> Bounding box: xmin: -180 ymin: -90 xmax: 180 ymax: 83.6341
  45. #> Geodetic CRS: WGS 84
  46. #> # A tibble: 232 × 4
  47. #> adm0_a3 geometry countrynames world_values
  48. #> <chr> <MULTIPOLYGON [°]> <chr> <dbl>
  49. #> 1 IDN (((117.7036 4.163415, 117.7036 4.163415, 1… Indonesia 0.195
  50. #> 2 MYS (((117.7036 4.163415, 117.6971 4.169053, 1… Malaysia 0.244
  51. #> 3 CHL (((-69.51009 -17.50659, -69.50611 -17.5851… Chile 0.0835
  52. # ...
  53. palette <- colorNumeric(
  54. palette = "Blues",
  55. domain = c(0,1)
  56. )
  57. map_ <- leaflet() %>%
  58. addProviderTiles("Esri.WorldGrayCanvas") %>%
  59. setView(lng = 0, lat = 0, zoom = 2) %>%
  60. addPolygons(
  61. data = leaflet_sf,
  62. stroke = TRUE,
  63. fillColor = ~ palette(world_values),
  64. fillOpacity = 0.5,
  65. popup = ~ paste("Country:", countrynames, "<br>", "Value:", world_values),
  66. color = "white",
  67. weight = 1,
  68. layerId = ~ adm0_a3,
  69. label = NULL
  70. )
  71. map_

In R leaflet interactive map, all my values get incorrectly displayed (while values inside data frames are all correct)

创建于2023年6月6日,使用 reprex v2.0.2

英文:

You are using one dataset for polygons and another for attribute data in leaflet. I guess this aproach wold work if number of rows and country order in both world and df would match, but currently first 3 in world are "Indonesia", "Malaysia", "Chile" while in df the top reads "Afghanistan", "Åland Islands", "Albania".

If you try to make those 2 to match, it would still be quite fragile and difficult to debug, so in most cases you'd want to join attribute table to the spatial dataset and use that with the mapping library. This is also the basis of formula (~) notation in leaflet where data = world, fillColor = ~ palette(Value) means:
use Value column from world data.frame to calculate fillColor

  1. library(dplyr)
  2. library(leaflet)
  3. library(rnaturalearth)
  4. library(sf)
  5. library(countrycode)
  6. # sf object with just counrty polygons and A3 codes
  7. world_sf &lt;- ne_countries(scale = &quot;large&quot;, returnclass = &quot;sf&quot;) %&gt;%
  8. # tibble printing is more compact
  9. as_tibble() %&gt;%
  10. st_as_sf() %&gt;%
  11. select(adm0_a3)
  12. world_sf
  13. #&gt; Simple feature collection with 258 features and 1 field
  14. #&gt; Geometry type: MULTIPOLYGON
  15. #&gt; Dimension: XY
  16. #&gt; Bounding box: xmin: -180 ymin: -90 xmax: 180 ymax: 83.6341
  17. #&gt; Geodetic CRS: WGS 84
  18. #&gt; # A tibble: 258 &#215; 2
  19. #&gt; adm0_a3 geometry
  20. #&gt; &lt;chr&gt; &lt;MULTIPOLYGON [&#176;]&gt;
  21. #&gt; 1 IDN (((117.7036 4.163415, 117.7036 4.163415, 117.7381 4.157242, 117.7836…
  22. #&gt; 2 MYS (((117.7036 4.163415, 117.6971 4.169053, 117.6441 4.215237, 117.6401…
  23. #&gt; 3 CHL (((-69.51009 -17.50659, -69.50611 -17.58513, -69.49712 -17.6214, -69…
  24. # ...
  25. # 2nd dataset, only atributes
  26. df_ &lt;- distinct(countryname_dict, countrynames = country.name.en) %&gt;%
  27. as_tibble() %&gt;%
  28. mutate(world_values = row_number() / 599,
  29. world_values = if_else(countrynames == &quot;Syria&quot;, 1, world_values),
  30. # world_values = replace(world_values, 241, 1),
  31. iso_a3 = countrycode(countrynames, &quot;country.name&quot;, &quot;iso3c&quot;)) %&gt;%
  32. na.omit()
  33. df_
  34. #&gt; # A tibble: 247 &#215; 3
  35. #&gt; countrynames world_values iso_a3
  36. #&gt; &lt;chr&gt; &lt;dbl&gt; &lt;chr&gt;
  37. #&gt; 1 Afghanistan 0.00167 AFG
  38. #&gt; 2 &#197;land Islands 0.00334 ALA
  39. #&gt; 3 Albania 0.00501 ALB
  40. # ...
  41. # join datasets by world_sf$adm0_a3 == df_$iso_a3, inner join keerp only records
  42. # that are present in both datasets
  43. leaflet_sf &lt;- inner_join(world_sf, df_, by = join_by(adm0_a3 == iso_a3))
  44. leaflet_sf
  45. #&gt; Simple feature collection with 232 features and 3 fields
  46. #&gt; Geometry type: MULTIPOLYGON
  47. #&gt; Dimension: XY
  48. #&gt; Bounding box: xmin: -180 ymin: -90 xmax: 180 ymax: 83.6341
  49. #&gt; Geodetic CRS: WGS 84
  50. #&gt; # A tibble: 232 &#215; 4
  51. #&gt; adm0_a3 geometry countrynames world_values
  52. #&gt; &lt;chr&gt; &lt;MULTIPOLYGON [&#176;]&gt; &lt;chr&gt; &lt;dbl&gt;
  53. #&gt; 1 IDN (((117.7036 4.163415, 117.7036 4.163415, 1… Indonesia 0.195
  54. #&gt; 2 MYS (((117.7036 4.163415, 117.6971 4.169053, 1… Malaysia 0.244
  55. #&gt; 3 CHL (((-69.51009 -17.50659, -69.50611 -17.5851… Chile 0.0835
  56. # ...
  57. palette &lt;- colorNumeric(
  58. palette = &quot;Blues&quot;,
  59. domain = c(0,1)
  60. )
  61. map_ &lt;- leaflet() %&gt;%
  62. addProviderTiles(&quot;Esri.WorldGrayCanvas&quot;) %&gt;%
  63. setView(lng = 0, lat = 0, zoom = 2) %&gt;%
  64. addPolygons(
  65. data = leaflet_sf,
  66. stroke = TRUE,
  67. fillColor = ~ palette(world_values),
  68. fillOpacity = 0.5,
  69. popup = ~ paste(&quot;Country:&quot;, countrynames, &quot;&lt;br&gt;&quot;, &quot;Value:&quot;, world_values),
  70. color = &quot;white&quot;,
  71. weight = 1,
  72. layerId = ~ adm0_a3,
  73. label = NULL
  74. )
  75. map_

In R leaflet interactive map, all my values get incorrectly displayed (while values inside data frames are all correct)<!-- -->

<sup>Created on 2023-06-06 with reprex v2.0.2</sup>

huangapple
  • 本文由 发表于 2023年6月6日 07:10:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76410518.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定