【发布时间】:2021-04-01 20:21:47
【问题描述】:
我希望将密度图裁剪为仅着陆,同时保持sf。
这是一个简单的示例问题:
library(tidyverse)
library(sf)
library(albersusa)
library(ggthemes)
library(jsonlite)
dat <-
fromJSON(
"https://services1.arcgis.com/Hp6G80Pky0om7QvQ/arcgis/rest/services/Fortune_500_Corporate_Headquarters/FeatureServer/0/query?where=1%3D1&outFields=LATITUDE,LONGITUDE,NAME,PROFIT&outSR=4326&f=json"
)
dat <- as.data.frame(dat$features$attributes)
top_50 <- dat %>%
arrange(desc(PROFIT)) %>%
head(50)
ggplot() +
geom_sf(data = usa_sf()) +
geom_density_2d_filled(aes(x = LONGITUDE, y = LATITUDE),
data = top_50,
alpha = .5) +
xlim(-125,-66.5) +
ylim(20, 50) +
theme_map() +
theme(legend.position = "none")
不确定我是否接近解决方案,但这是我一直在尝试的一些代码:
test <- (MASS::kde2d(
top_50$LONGITUDE, top_50$LATITUDE,
lims = c(-125,-66.5, 20, 50)
))
ggpoly2sf <- function(poly, coords = c("long", "lat"),
id = "group", region = "region", crs = 4326) {
sf::st_as_sf(poly, coords = coords, crs = crs) %>%
group_by(!! as.name(id), !! as.name(region)) %>%
summarize(do_union=FALSE) %>%
sf::st_as_sf("POLYGON") %>%
ungroup() %>%
group_by(!! as.name(region)) %>%
summarize(do_union = TRUE) %>%
ungroup()
}
v <- contourLines(test)
vv <- v
for (i in seq_along(v)) vv[[i]]$group <- i
vv <- do.call(rbind, lapply(vv, as.data.frame))
dsi_sf <- ggpoly2sf(vv, coords = c("x", "y"), region = "level") %>% st_as_sf()
usa <- usa_sf()
dsi_i_sf <- st_intersection(usa$geometry, dsi_sf)
ggplot() +
geom_sf(data=usa) +
geom_sf(data=dsi_i_sf,color="red") +
geom_density2d_filled(aes(x = LONGITUDE, y = LATITUDE),
data = top_50,alpha=.4) +
xlim(-125,-66.5) +
ylim(20, 50) +
theme(legend.position = "none")
【问题讨论】:
-
目前这是 R 中的一项艰巨任务。非矩形剪贴蒙版即将出现在 R4.1.0 中,但它们现在不存在于网格系统中。请参阅stat.auckland.ac.nz/~paul/Reports/GraphicsEngine/definitions/…,尤其是第一个示例和脚注。
-
我一直在与
sf::st_intersection合作,但我很难在 ggplot 之外生成密度图。似乎这是当前的工作答案:homepage.stat.uiowa.edu/~luke/classes/STAT4580-2020/maps.html -
我对 sf 框架一无所知,但不看 ggplot2 的 source code 允许您重建过程?
-
实现
MASS::kde2d()很容易,但将输出操作到一个有意义的交叉层是一条漫长的道路。