tmap_save保存地图报错:Unknown format问题求助
问题描述
执行tmap_save()保存交互式地图时触发错误:
Error in tmap_save(st_map, filename = mapname) :
Unknown format. tm should be either a tmap output, or a list of tmap outputs
原脚本及示例数据如下:
原脚本
# Load Packages library(tidyverse) library(readr) library(dplyr) library(lubridate) library(forcats) library(stringr) library(ggplot2) library(ggmap) library(maps) library(mapdata) library(sf) library(tmap) library(spData) library(ggspatial) library(readxl) library(haven) library(RColorBrewer) library(ggsci) library(ggthemes) library(vroom) library(scales) # Map Title map_title <- 'Place Schedule Adherence Map' # Initialize Map tmap_mode("view") st_map <- NULL # Create timepd List tp_list <- sa_sf %>% select(timepd) %>% arrange(timepd) tp_list <- unique(tp_list$timepd) %>% sort() # Loop Through Each Time Period for (tp in tp_list) { st_map <- st_map %>% tm_shape(sa_sf %>% filter(timepd == tp)) + tm_symbols(col='pgr_delay', size=.01, scale=10, palette = 'YlOrRd', group = paste(tp, 'Place Schedule Adherence'), interactive=TRUE, popup.vars=c('schedule_type', 'timepd', 'place', 'stopid', 'stopname', 'route_list', 'pc_late')) } # Add Map Title and Scale Bar st_map <- st_map %>% tm_layout(title = map_title, title.size = 10, title.fontface = 'bold') # Create Map html File mapname = 'Schedule Adherence Map.html' # Create Map html File tmap_save(st_map, filename = mapname)
示例数据
mtcars <- structure(list(schedule_type = c("WKD", "WKD", "WKD", "WKD", "WKD", "WKD", "WKD", "WKD", "WKD", "WKD", "WKD", "WKD"), timepd = c("03:00-07:00", "03:00-07:00", "07:00-09:00", "07:00-09:00", "09:00-14:30", "09:00-14:30", "14:30-18:00", "14:30-18:00", "18:00-22:00", "18:00-22:00", "22:00-30:00", "22:00-30:00"), place = c("AEEN", "AEEN", "AEEN", "AEEN", "AEEN", "AEEN", "AEEN", "AEEN", "AEEN", "AEEN", "AEEN", "AEEN"), stopid = c(2108, 4138, 2108, 4138, 2108, 4138, 2108, 4138, 2108, 4138, 2108, 4138 ), stopname = c("Elgin / Avenue", "Elgin / Avenue", "Elgin / Avenue", "Elgin / Avenue", "Elgin / Avenue", "Elgin / Avenue", "Elgin / Avenue", "Elgin / Avenue", "Elgin / Avenue", "Elgin / Avenue", "Elgin / Avenue", "Elgin / Avenue"), route_list = c("58", "58", "58", "58", "58", "58", "58", "58", "58", "58", "58", "58"), pc_late = c(11, 1, 19, 5, 12, 15, 21, 39, 11, 14, 6, 3), geometry = structure(list( structure(c(-80.306392, 43.378458), class = c("XY", "POINT", "sfg")), structure(c(-80.306576, 43.379437), class = c("XY", "POINT", "sfg")), structure(c(-80.306392, 43.378458), class = c("XY", "POINT", "sfg")), structure(c(-80.306576, 43.379437), class = c("XY", "POINT", "sfg")), structure(c(-80.306392, 43.378458), class = c("XY", "POINT", "sfg")), structure(c(-80.306576, 43.379437), class = c("XY", "POINT", "sfg")), structure(c(-80.306392, 43.378458), class = c("XY", "POINT", "sfg")), structure(c(-80.306576, 43.379437), class = c("XY", "POINT", "sfg")), structure(c(-80.306392, 43.378458), class = c("XY", "POINT", "sfg")), structure(c(-80.306576, 43.379437), class = c("XY", "POINT", "sfg")), structure(c(-80.306392, 43.378458), class = c("XY", "POINT", "sfg")), structure(c(-80.306576, 43.379437), class = c("XY", "POINT", "sfg"))), class = c("sfc_POINT", "sfc"), precision = 0, bbox = structure(c(xmin = -80.306576, ymin = 43.378458, xmax = -80.306392, ymax = 43.379437), class = "bbox"), crs = structure(list( input = "EPSG:4326", wkt = "GEOGCRS[\"WGS 84\",\n ENSEMBLE[\"World Geodetic System 1984 ensemble\",\n MEMBER[\"World Geodetic System 1984 (Transit)\"],\n MEMBER[\"World Geodetic System 1984 (G730)\"],\n MEMBER[\"World Geodetic System 1984 (G873)\"],\n MEMBER[\"World Geodetic System 1984 (G1150)\"],\n MEMBER[\"World Geodetic System 1984 (G1674)\"],\n MEMBER[\"World Geodetic System 1984 (G1762)\"],\n MEMBER[\"World Geodetic System 1984 (G2139)\"],\n ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n LENGTHUNIT[\"metre\",1]],\n ENSEMBLEACCURACY[2.0]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n CS[ellipsoidal,2],\n AXIS[\"geodetic latitude (Lat)\",north,\n ORDER[1],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n AXIS[\"geodetic longitude (Lon)\",east,\n ORDER[2],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n USAGE[\n SCOPE[\"Horizontal component of 3D system.\"],\n AREA[\"World.\"],\n BBOX[-90,-180,90,180]],\n ID[\"EPSG\",4326]]"), class = "crs"), n_empty = 0L)), row.names = c(NA, -12L), sf_column = "geometry", agr = structure(c(schedule_type = NA_integer_, timepd = NA_integer_, place = NA_integer_, stopid = NA_integer_, stopname = NA_integer_, route_list = NA_integer_, pc_late = NA_integer_ ), levels = c("constant", "aggregate", "identity"), class = "factor"), class = c("sf", "tbl_df", "tbl", "data.frame"))
问题原因与修复
核心问题
- 初始化
st_map <- NULL后,用%>%拼接tmap元素会导致最终对象不是tmap识别的有效格式 - 循环中错误地尝试用管道符累加
tmap对象,而非将每个时间段的图层存入列表
修复后的完整代码
# 加载必要包(简化冗余包加载) library(tidyverse) library(sf) library(tmap) # 示例数据重命名为脚本使用的sa_sf sa_sf <- mtcars # 地图标题 map_title <- 'Place Schedule Adherence Map' # 切换到交互式视图模式,初始化st_map为空列表 tmap_mode("view") st_map <- list() # 生成时间周期列表(简化代码) tp_list <- sa_sf %>% pull(timepd) %>% unique() %>% sort() # 循环生成每个时间段的tmap图层,存入列表 for (tp in tp_list) { current_layer <- tm_shape(sa_sf %>% filter(timepd == tp)) + tm_symbols( col = 'pc_late', # 原脚本中pgr_delay字段不存在,替换为数据中的pc_late size = .01, scale = 10, palette = 'YlOrRd', group = paste(tp, 'Place Schedule Adherence'), interactive = TRUE, popup.vars = c('schedule_type', 'timepd', 'place', 'stopid', 'stopname', 'route_list', 'pc_late') ) # 将当前图层加入列表 st_map <- append(st_map, list(current_layer)) } # 为所有图层统一添加布局设置 st_map <- st_map %>% tm_layout( title = map_title, title.size = 10, title.fontface = 'bold' ) # 保存交互式地图为HTML文件 mapname <- 'Schedule Adherence Map.html' tmap_save(st_map, filename = mapname)
额外修正说明
- 移除冗余包加载,仅保留核心依赖
- 修正原脚本中不存在的
pgr_delay字段,替换为数据实际包含的pc_late - 优化时间周期列表生成代码,更简洁高效
- 将
tmap图层存入列表后,tmap_save能正确识别格式,支持交互式视图的图层切换功能
内容的提问来源于stack exchange,提问作者wbm
相关产品推荐
相关产品推荐

