英文:
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 <- 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)
# 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 <- 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)
# Match country codes in world data with countrynames
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)
)
# Add country polygons layer
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
)
# Print the map
map
I have tried changing layerId, fillColor, palette and popup to other things. I'm at wits' end.
答案1
得分: 0
你在leaflet
中使用了一个数据集来表示多边形,另一个数据集用于属性数据。我猜这种方法只有在world
和df
中的行数和国家顺序匹配时才能正常工作,但目前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_
创建于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 <- ne_countries(scale = "large", returnclass = "sf") %>%
# tibble printing is more compact
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…
# ...
# 2nd dataset, only atributes
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),
# world_values = replace(world_values, 241, 1),
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
# ...
# join datasets by world_sf$adm0_a3 == df_$iso_a3, inner join keerp only records
# that are present in both datasets
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_
<!-- -->
<sup>Created on 2023-06-06 with reprex v2.0.2</sup>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论