如何使用自定义数据绘制欧洲地图?代码数据绑定问题求助
Hey there! Let's break down what's going wrong with your code and fix that data binding problem step by step, plus I'll share a more modern approach using sf (since rgdal and maptools are being phased out).
The Root of the Problem
Your current merge line doesn't specify which columns to match on:
europa@data <- merge(europa@data, europe)
The shapefile's TM_WORLD_BORDERS_SIMPL-0.3 has an ISO2 column that matches your europe data's Code column, but without telling merge() to use these columns, it's trying to merge on all common column names (which there probably aren't any, leading to a messy Cartesian join or missing matches). Also, merging directly into the @data slot of a SpatialPolygonsDataFrame can mess up the order of spatial features, making your map misalign with the data entirely.
Fixing the Original Code
Here's how to adjust your existing code to fix the binding and alignment issues:
# Load required libraries library(rgdal) library(maptools) library(cartography) # Download and unzip shapefile download.file("http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip" , destfile="world_shape_file.zip") system("unzip world_shape_file.zip") # Load spatial object my_spdf <- readOGR(dsn= "./world_shape_file/" , layer="TM_WORLD_BORDERS_SIMPL-0.3", verbose=FALSE) # Subset Europe (REGION 150) europa <- my_spdf[my_spdf@data$REGION == 150, ] # Merge data correctly: explicitly match shapefile's ISO2 to your Code column europa@data <- merge( europa@data, europe, by.x = "ISO2", # Shapefile's country code column by.y = "Code", # Your data's country code column all.x = TRUE # Keep all European countries from the shapefile ) # Critical: Reorder spatial features to match merged data (prevents misalignment) europa <- europa[match(europa@data$ISO2, europe$Code), ] # Plot the choropleth (adjusted xlim to focus on Europe) par(mar=c(0,0,0,0)) spplot(europa, zcol = "Production", xlim=c(-30, 30), ylim=c(35, 70), lwd=0.5)
A Modern Alternative Using sf (Recommended)
The rgdal and maptools packages are deprecated, so using the sf (simple features) package is the current standard for spatial data in R. It's more intuitive and avoids the clunky slot-based structure of old spatial objects. Here's a cleaner implementation:
# Install if needed: install.packages(c("sf", "tidyverse", "tmap")) library(sf) library(tidyverse) library(tmap) # Your original data europe <- structure(list(Code = c("BE", "BG", "CZ", "DK", "DE", "EE", "IE", "EL", "ES", "FR", "HR", "IT", "CY", "LV", "LT", "LU", "HU", "MT", "NL", "AT", "PL", "PT", "RO", "SI", "SK", "FI", "SE", "IS", "NO", "CH", "UK"), Country = c("Belgium", "Bulgaria", "Czechia", "Denmark", "Germany (until 1990 former territory of the FRG)", "Estonia", "Ireland", "Greece", "Spain", "France", "Croatia", "Italy", "Cyprus", "Latvia", "Lithuania", "Luxembourg", "Hungary", "Malta", "Netherlands", "Austria", "Poland", "Portugal", "Romania", "Slovenia", "Slovakia", "Finland", "Sweden", "Iceland", "Norway", "Switzerland", "United Kingdom" ), Production = c(133.2, 48.2, 77.4, 138.2, 121.3, 71.2, 178.9, 58.5, 95, 126.1, 64.5, 100.1, 75, 59.8, 67.7, 175.1, 66.8, 75.8, 122.3, 115.7, 65, 66.1, 66.1, 83.9, 70.1, 109.5, 112.4, 118.2, 152.4, 129.3, 96.8)), row.names = c(NA, -31L), class = c("tbl_df", "tbl", "data.frame")) # Download and load world shapefile as sf object world_sf <- st_read("http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip", quiet = TRUE) # Subset Europe and merge with your data in one step europe_sf <- world_sf %>% filter(REGION == 150) %>% left_join(europe, by = c("ISO2" = "Code")) # Match shapefile's ISO2 to your Code column # Create a polished choropleth map tm_shape(europe_sf, bbox = st_bbox(c(xmin = -30, xmax = 30, ymin = 35, ymax = 70))) + tm_polygons("Production", title = "Production Value", lwd = 0.5) + tm_layout(frame = FALSE, legend.outside = TRUE)
Why This Works Better:
sfuses a single data frame-like object, so merging is as intuitive as regular tabular data (no more dealing with@dataslots).left_joinautomatically keeps all European features from the shapefile while matching your data correctly.tmapmakes creating clean, professional-looking maps with minimal code a breeze.
Key Takeaways
- Always specify matching columns when merging spatial and tabular data—don't rely on automatic matching.
- When using old SpatialPolygonsDataFrame objects, reorder features after merging to ensure alignment with your data.
- Switch to
sfandtmapfor modern, maintainable spatial workflows in R.
内容的提问来源于stack exchange,提问作者Oxford Bicho

