如何在带有地图的ggplot2内部使用循环?

How to use for loops inside of ggplot2 with maps?

我不确定 for 循环是否就是这里的答案(我是 R 的新手),但我希望有人能给我建议。基本上,我有一个包含三列的数据框:城市、纬度和经度。每行代表给定城市发生的事件,所以每个城市出现不止一次,一个城市出现的次数代表该城市发生的事件的数量:

df1 <- data.frame(city = c("Alexandria", "Cairo", "Luxor", "Luxor", "Alexandria", "Cairo", "Luxor", "Cairo", "Luxor"),
                  latitude = c(31.1977, 30.0435, 25.6833, 25.6833, 31.1977, 30.0435, 25.6833, 30.0435, 25.6833),
                  longitude = c(29.8925, 31.2353, 32.65, 32.65, 29.8925, 31.2353, 32.65, 31.2353, 32.65)

(实际上我正在处理一个包含数千行的 csv 文件,但结构是相同的)。我想要做的是使用 ggplot 和 rnaturalearth 创建一个地图绘图,其中一个点出现在数据框中表示的每个城市的位置上(基于对应于每个城市的纬度和经度坐标),但大小和颜色点根据每个城市在数据框中出现的次数而有所不同(即出现次数越多,点越大越深)。

我已经了解了下面的代码,它生成了地图,其中代表了每个城市的点,但显然不会根据城市出现的次数改变点的大小和颜色.谁能帮我弄清楚该怎么做?我想这可能会涉及一个 for 循环,循环遍历 unique(df1$city) 并为 unique(df1$city) 中的每个项目找到长度(子集(df1))并使用它来填充大小和填充参数,但我我不知道该怎么做。非常感谢。

install.packages(c("cowplot", "googleway", "ggplot2", "ggrepel", 
                   "ggspatial", "libwgeom", "sf", "rnaturalearth", "rnaturalearthdata", "rgeos"))


library("ggplot2")
library("sf")
library("rnaturalearth")
library("rnaturalearthdata")


df1 <- data.frame(city = c("Alexandria", "Cairo", "Luxor", "Luxor", "Alexandria", "Cairo", "Luxor", "Cairo", "Luxor"),
                  latitude = c(31.1977, 30.0435, 25.6833, 25.6833, 31.1977, 30.0435, 25.6833, 30.0435, 25.6833),
                  longitude = c(29.8925, 31.2353, 32.65, 32.65, 29.8925, 31.2353, 32.65, 31.2353, 32.65)
)

world <- ne_countries(scale = "medium", returnclass = "sf")

ggplot(data = world)+
  geom_sf() +
  geom_point(data = df1, aes(x = df1$longitude, y = df1$latitude), size = 4,
             shape = 25, fill = "darkred")+
  coord_sf(xlim = c(24.6, 37.0), ylim = c(21.9, 32.0), expand = FALSE)

不需要 for 循环。相反,我建议您使用例如聚合数据dplyr::count 它为您提供了每个城市一行的数据集和一个包含事件数量的新列 n。然后可以将这个新变量映射到 sizefill:

library("ggplot2")
library("sf")
library("rnaturalearth")
library("rnaturalearthdata")
library(dplyr)

df1 <- data.frame(city = c("Alexandria", "Cairo", "Luxor", "Luxor", "Alexandria", "Cairo", "Luxor", "Cairo", "Luxor"),
                  latitude = c(31.1977, 30.0435, 25.6833, 25.6833, 31.1977, 30.0435, 25.6833, 30.0435, 25.6833),
                  longitude = c(29.8925, 31.2353, 32.65, 32.65, 29.8925, 31.2353, 32.65, 31.2353, 32.65)
)

world <- ne_countries(scale = "medium", returnclass = "sf")

# Aggregate data
df2 <- df1 %>% 
  count(city, latitude, longitude)

ggplot(data = world)+
  geom_sf() +
  geom_point(data = df2, aes(x = longitude, y = latitude, size = n, fill = n),
             shape = 25)+
  coord_sf(xlim = c(24.6, 37.0), ylim = c(21.9, 32.0), expand = FALSE)