ggplot绘制MENA地区地图时filter筛选国家标签报错求助
问题描述
我尝试创建中东和北非(MENA)地区的地图并标注国家名称,通过经纬度坐标划定地图范围后,生成的地图包含部分非MENA国家。因此我想用filter函数结合国家名称向量,仅为目标区域内的国家标注名称,但添加filter后出现错误:
Error in data.matrix(data) : 'list' object cannot be coerced to type 'double'
未添加filter时可正常运行的代码:
ggplot(data = world) + geom_sf(fill= "antiquewhite") + geom_text(data = world_points , aes(x=X, y=Y, label=name), color = "darkblue", fontface = "bold", check_overlap = TRUE) + annotate(geom = "text", x = 20, y = 35, label = "MØNA", fontface = "italic", color = "grey22", size = 6) + coord_sf(xlim = c(-18.0, 72.0), ylim = c(11.5, 45.0), expand = FALSE) + xlab("经度") + ylab("纬度") + ggtitle("中东和北非地区") + theme(panel.background = element_rect(fill = "aliceblue"))
添加filter后报错的代码:
ggplot(data = world) + geom_sf(fill = "antiquewhite") + coord_sf(xlim = c(-18.0, 72.0), ylim = c(11.5, 45.0), expand = FALSE) + geom_text(data = world_points %>% filter(name %in% c('Egypt', 'Tunisia', 'Algeria', 'Libya', 'Morocco', 'Sudan', 'Jordan', 'Israel', 'Palestine', 'Syria', 'Iraq', 'Turkey', 'Iran', 'Afghanistan', 'Saudi Arabia', 'Kuwait', 'United Arab Emirates', 'Qatar', 'Oman', 'Yemen', 'Bahrain', 'Lebanon')), aes(x=X, y=Y, label=name), color = "darkblue", size = 3, check_overlap = FALSE) + annotate(geom = "text", x = 20, y = 35, label = "MØNA", fontface = "italic", color = "grey22", size = 6) + xlab("经度") + ylab("纬度") + ggtitle("中东和北非地区") + theme(panel.background = element_rect(fill = "aliceblue"))
解决方案
错误原因
world_points是sf空间对象,包含一个geometry列(数据类型为list)。使用filter后该列依然存在,而geom_text在处理数据时会尝试将整个数据集转换为数值矩阵,遇到list类型的geometry列就会触发报错。
解决方法1:转换为普通数据框
在filter后将sf对象转换为普通数据框,只保留需要的X、Y和name列:
ggplot(data = world) + geom_sf(fill = "antiquewhite") + coord_sf(xlim = c(-18.0, 72.0), ylim = c(11.5, 45.0), expand = FALSE) + geom_text( data = world_points %>% filter(name %in% c('Egypt', 'Tunisia', 'Algeria', 'Libya', 'Morocco', 'Sudan', 'Jordan', 'Israel', 'Palestine', 'Syria', 'Iraq', 'Turkey', 'Iran', 'Afghanistan', 'Saudi Arabia', 'Kuwait', 'United Arab Emirates', 'Qatar', 'Oman', 'Yemen', 'Bahrain', 'Lebanon')) %>% as.data.frame() %>% # 转换为普通数据框 select(X, Y, name), # 只保留需要的列 aes(x=X, y=Y, label=name), color = "darkblue", size = 3, check_overlap = FALSE ) + annotate(geom = "text", x = 20, y = 35, label = "MØNA", fontface = "italic", color = "grey22", size = 6) + xlab("经度") + ylab("纬度") + ggtitle("中东和北非地区") + theme(panel.background = element_rect(fill = "aliceblue"))
解决方法2:使用geom_sf_text
如果world_points是包含国家几何中心的sf对象,直接用geom_sf_text可以避免手动处理坐标列,它会自动读取sf对象的geometry列:
ggplot(data = world) + geom_sf(fill = "antiquewhite") + coord_sf(xlim = c(-18.0, 72.0), ylim = c(11.5, 45.0), expand = FALSE) + geom_sf_text( data = world_points %>% filter(name %in% c('Egypt', 'Tunisia', 'Algeria', 'Libya', 'Morocco', 'Sudan', 'Jordan', 'Israel', 'Palestine', 'Syria', 'Iraq', 'Turkey', 'Iran', 'Afghanistan', 'Saudi Arabia', 'Kuwait', 'United Arab Emirates', 'Qatar', 'Oman', 'Yemen', 'Bahrain', 'Lebanon')), aes(label=name), color = "darkblue", size = 3, check_overlap = FALSE ) + annotate(geom = "text", x = 20, y = 35, label = "MØNA", fontface = "italic", color = "grey22", size = 6) + xlab("经度") + ylab("纬度") + ggtitle("中东和北非地区") + theme(panel.background = element_rect(fill = "aliceblue"))
内容的提问来源于stack exchange,提问作者jacobhoi
相关产品推荐
相关产品推荐

