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

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

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

问题

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

#libraries
library(tidyverse)
library(leaflet)
library(rnaturalearth)
library(rnaturalearthdata)
library(sf)
library(countrycode)

#load world data from natural earth
world <- ne_countries(scale = "large", returnclass = "sf")
world <- st_transform(world, "+proj=longlat +datum=WGS84")

countrynames <- countryname_dict %>%
  group_by(country.name.en) %>%
  summarise(country.name.en) %>%
  distinct()

countrynames <- dplyr::pull(countrynames, country.name.en)

# 这些值是随机的,只是为了测试地图。我希望每个国家都有一个基于0到1之间某些随机数字的颜色比例。在数据框中,它们确实都在0到1之间
world_values <- c(1:284)
df <- cbind(countrynames, world_values)
df <- as.data.frame(df)
df$world_values <- as.numeric(df$world_values)
df$world_values[241] <- 599
df <- df %>%
  mutate(Value = world_values / 599)

# 将世界数据中的国家代码与国家名称匹配
df$iso_a3 <- countrycode(sourcevar = countrynames, origin = "country.name", destination = "iso3c")
df <- df %>% na.omit()

map <- leaflet() %>%
  addProviderTiles("Esri.WorldGrayCanvas") %>%
  setView(lng = 0, lat = 0, zoom = 2)

palette <- colorNumeric(
  palette = "Blues",
  domain = c(0,1)
)

# 添加国家多边形图层
map <- map %>% 
  addPolygons(
    data = world,
    stroke = TRUE,
    fillColor = ~palette(df$Value),
    fillOpacity = 0.5,
    popup = ~paste("Country:", df$countrynames, "<br>", "Value:", df$Value),
    color = "white",
    weight = 1,
    layerId = ~iso_a3,
    label = NULL
  )

# 打印地图
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...

#libraries
library(tidyverse)
library(leaflet)
library(rnaturalearth)
library(rnaturalearthdata)
library(sf)
library(countrycode)
#load world data from natural earth
world &lt;- ne_countries(scale = &quot;large&quot;, returnclass = &quot;sf&quot;)
world &lt;- st_transform(world, &quot;+proj=longlat +datum=WGS84&quot;)
countrynames &lt;- countryname_dict %&gt;% 
group_by(country.name.en) %&gt;% 
summarise(country.name.en) %&gt;% 
distinct()
countrynames &lt;- dplyr::pull(countrynames, country.name.en)
# 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
world_values &lt;- c(1:284)
df &lt;- cbind (countrynames, world_values)
df &lt;- as.data.frame(df)
df$world_values &lt;- as.numeric(df$world_values)
df$world_values[241] &lt;- 599
df &lt;- df %&gt;% 
mutate(Value = world_values / 599)
# Match country codes in world data with countrynames
df$iso_a3 &lt;- countrycode(sourcevar = countrynames, origin = &quot;country.name&quot;, destination = &quot;iso3c&quot;)
df &lt;- df %&gt;% na.omit()
map &lt;- leaflet() %&gt;%
addProviderTiles(&quot;Esri.WorldGrayCanvas&quot;) %&gt;%
setView(lng = 0, lat = 0, zoom = 2)
palette &lt;- colorNumeric(
palette = &quot;Blues&quot;,
domain = c(0,1)
)
# Add country polygons layer
map &lt;- map %&gt;% 
addPolygons(
data = world,
stroke = TRUE,
fillColor = ~palette(df$Value),
fillOpacity = 0.5,
popup = ~paste(&quot;Country:&quot;, df$countrynames, &quot;&lt;br&gt;&quot;, &quot;Value:&quot;, df$Value),
color = &quot;white&quot;,
weight = 1,
layerId = ~iso_a3,
label = NULL
)
# Print the map
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

library(dplyr)
library(leaflet)
library(rnaturalearth)
library(sf)
library(countrycode)

# 只包含国家多边形和A3代码的sf对象
world_sf <- ne_countries(scale = "large", returnclass = "sf") %>%
  as_tibble() %>%
  st_as_sf() %>%
  select(adm0_a3)
world_sf 
#> Simple feature collection with 258 features and 1 field
#> Geometry type: MULTIPOLYGON
#> Dimension:     XY
#> Bounding box:  xmin: -180 ymin: -90 xmax: 180 ymax: 83.6341
#> Geodetic CRS:  WGS 84
#> # A tibble: 258 × 2
#>    adm0_a3                                                              geometry
#>    <chr>                                                      <MULTIPOLYGON [°]>
#>  1 IDN     (((117.7036 4.163415, 117.7036 4.163415, 117.7381 4.157242, 117.7836…
#>  2 MYS     (((117.7036 4.163415, 117.6971 4.169053, 117.6441 4.215237, 117.6401…
#>  3 CHL     (((-69.51009 -17.50659, -69.50611 -17.58513, -69.49712 -17.6214, -69…

# 第二个数据集,只有属性
df_ <- distinct(countryname_dict, countrynames = country.name.en) %>%
  as_tibble() %>%
  mutate(world_values = row_number() / 599,
         world_values = if_else(countrynames == "Syria", 1, world_values),
         iso_a3 = countrycode(countrynames, "country.name", "iso3c")) %>%
  na.omit()
df_
#> # A tibble: 247 × 3
#>    countrynames      world_values iso_a3
#>    <chr>                    <dbl>  <chr> 
#>  1 Afghanistan            0.00167 AFG   
#>  2 Åland Islands          0.00334 ALA   
#>  3 Albania                0.00501 ALB   
#> ...

# 通过 world_sf$adm0_a3 == df_$iso_a3 连接数据集,内连接只保留两个数据集中都存在的记录
leaflet_sf <- inner_join(world_sf, df_, by = join_by(adm0_a3 == iso_a3)) 
leaflet_sf
#> Simple feature collection with 232 features and 3 fields
#> Geometry type: MULTIPOLYGON
#> Dimension:     XY
#> Bounding box:  xmin: -180 ymin: -90 xmax: 180 ymax: 83.6341
#> Geodetic CRS:  WGS 84
#> # A tibble: 232 × 4
#>    adm0_a3                                    geometry countrynames world_values
#>    <chr>                            <MULTIPOLYGON [°]> <chr>               <dbl>
#>  1 IDN     (((117.7036 4.163415, 117.7036 4.163415, 1… Indonesia          0.195 
#>  2 MYS     (((117.7036 4.163415, 117.6971 4.169053, 1… Malaysia           0.244 
#>  3 CHL     (((-69.51009 -17.50659, -69.50611 -17.5851… Chile              0.0835
# ...

palette <- colorNumeric(
  palette = "Blues",
  domain = c(0,1)
)

map_ <- leaflet() %>%
  addProviderTiles("Esri.WorldGrayCanvas") %>%
  setView(lng = 0, lat = 0, zoom = 2) %>% 
  addPolygons(
    data = leaflet_sf,
    stroke = TRUE,
    fillColor = ~ palette(world_values),
    fillOpacity = 0.5,
    popup = ~ paste("Country:", countrynames, "<br>", "Value:", world_values),
    color = "white",
    weight = 1,
    layerId = ~ adm0_a3,
    label = NULL
  )
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

library(dplyr)
library(leaflet)
library(rnaturalearth)
library(sf)
library(countrycode)

# sf object with just counrty polygons and A3 codes
world_sf &lt;- ne_countries(scale = &quot;large&quot;, returnclass = &quot;sf&quot;) %&gt;% 
  # tibble printing is more compact
  as_tibble() %&gt;% 
  st_as_sf() %&gt;% 
  select(adm0_a3)
world_sf 
#&gt; Simple feature collection with 258 features and 1 field
#&gt; Geometry type: MULTIPOLYGON
#&gt; Dimension:     XY
#&gt; Bounding box:  xmin: -180 ymin: -90 xmax: 180 ymax: 83.6341
#&gt; Geodetic CRS:  WGS 84
#&gt; # A tibble: 258 &#215; 2
#&gt;    adm0_a3                                                              geometry
#&gt;    &lt;chr&gt;                                                      &lt;MULTIPOLYGON [&#176;]&gt;
#&gt;  1 IDN     (((117.7036 4.163415, 117.7036 4.163415, 117.7381 4.157242, 117.7836…
#&gt;  2 MYS     (((117.7036 4.163415, 117.6971 4.169053, 117.6441 4.215237, 117.6401…
#&gt;  3 CHL     (((-69.51009 -17.50659, -69.50611 -17.58513, -69.49712 -17.6214, -69…
# ...  

# 2nd dataset, only atributes
df_ &lt;- distinct(countryname_dict, countrynames = country.name.en) %&gt;% 
  as_tibble() %&gt;% 
  mutate(world_values = row_number() / 599,
         world_values = if_else(countrynames == &quot;Syria&quot;, 1, world_values),
         # world_values = replace(world_values, 241, 1),
         iso_a3 = countrycode(countrynames, &quot;country.name&quot;, &quot;iso3c&quot;)) %&gt;% 
  na.omit()
df_
#&gt; # A tibble: 247 &#215; 3
#&gt;    countrynames      world_values iso_a3
#&gt;    &lt;chr&gt;                    &lt;dbl&gt; &lt;chr&gt; 
#&gt;  1 Afghanistan            0.00167 AFG   
#&gt;  2 &#197;land Islands          0.00334 ALA   
#&gt;  3 Albania                0.00501 ALB   
# ...

# join datasets by world_sf$adm0_a3 == df_$iso_a3, inner join keerp only records 
# that are present in both datasets
leaflet_sf &lt;- inner_join(world_sf, df_, by = join_by(adm0_a3 == iso_a3)) 
leaflet_sf
#&gt; Simple feature collection with 232 features and 3 fields
#&gt; Geometry type: MULTIPOLYGON
#&gt; Dimension:     XY
#&gt; Bounding box:  xmin: -180 ymin: -90 xmax: 180 ymax: 83.6341
#&gt; Geodetic CRS:  WGS 84
#&gt; # A tibble: 232 &#215; 4
#&gt;    adm0_a3                                    geometry countrynames world_values
#&gt;    &lt;chr&gt;                            &lt;MULTIPOLYGON [&#176;]&gt; &lt;chr&gt;               &lt;dbl&gt;
#&gt;  1 IDN     (((117.7036 4.163415, 117.7036 4.163415, 1… Indonesia          0.195 
#&gt;  2 MYS     (((117.7036 4.163415, 117.6971 4.169053, 1… Malaysia           0.244 
#&gt;  3 CHL     (((-69.51009 -17.50659, -69.50611 -17.5851… Chile              0.0835
# ...


palette &lt;- colorNumeric(
  palette = &quot;Blues&quot;,
  domain = c(0,1)
)

map_ &lt;- leaflet() %&gt;%
  addProviderTiles(&quot;Esri.WorldGrayCanvas&quot;) %&gt;%
  setView(lng = 0, lat = 0, zoom = 2) %&gt;% 
  addPolygons(
    data = leaflet_sf,
    stroke = TRUE,
    fillColor = ~ palette(world_values),
    fillOpacity = 0.5,
    popup = ~ paste(&quot;Country:&quot;, countrynames, &quot;&lt;br&gt;&quot;, &quot;Value:&quot;, world_values),
    color = &quot;white&quot;,
    weight = 1,
    layerId = ~ adm0_a3,
    label = NULL
  )
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:

确定