在 R 中找到周长与周围邻居的比率
Finding ratio of perimeter with surrounding neighbors in R
我在 Sample Data
有一个形状文件
我将 R 中的数据读取为名为“SD”的 sf 对象,并包含“GEOID”和“geometry”列以及其他列。
我在名为“POP”的数据中创建了一个新列
SD$POP <- sample(2000:8000, 35)
首先,我想测量每个“GEOID”的面积和周长。
其次,我需要找出每个 GEOID 的周长与其周围的 GEOID 共享的比例。
例如:假设 GEOID 09 被 GEOID 06、08、10、13 包围。我想找出 GEOID 09 的周长与 06、08、10 和 13 分别共享的百分比。
然后创建新列“POP_PERCENT”和“ADJ_POP”这将是
ADJ-POP = SUM OF POP for GEOID 06, 08, 10, and 13' .
POP_PERCENT = Percent share with 06 + Percent share with 08 + Percent share with 10 +
Percent share with 13
对于冗长的问题,我深表歉意。如果有任何帮助,我将不胜感激。
我认为通常您需要的是 st_intersection
加上一些数据操作。数据集没有 GEOID
列,我不完全清楚 POP_PERCENT
的预期输出是什么(相邻人口按周长重叠百分比加权?)。所以这不是一个完全完整的答案。
这是使用 sf
和其他一些 tidyverse
函数的开始。这将计算每个多边形的面积、周长和交点。我从 rownames
创建了一个 GEOID
列。希望这足以让您朝着正确的方向前进。
先算出每个的面积和周长
library(tidyverse)
library(sf)
SD_ap <- SD %>%
st_transform(5070) %>% #convert from lat/long to projected coord system
mutate(area = st_area(.),
length_perim = lwgeom::st_perimeter(.))
#-----
GEOID POP geometry area perim
1 1 6582 MULTIPOLYGON (((860088.4 12... 357945281 [m^2] 139932.2 [m]
2 2 3199 MULTIPOLYGON (((843395.6 11... 137754181 [m^2] 100879.4 [m]
然后计算重叠周长。将多边形转换为线,然后 运行 st_intersection
。这 returns 141 条线段不是 35 个多边形,而是以原始重叠多边形 (origins
)
区分
SD_overlap <- SD_ap %>%
st_cast('MULTILINESTRING') %>%
st_intersection() %>%
mutate(length_intersection = st_length(.)) %>%
filter(length_intersection > units::as_units(0,'m'))
#----
GEOID POP area length_perim n.overlaps origins length_intersection
1 1 6559 357945281 [m^2] 139932.2 [m] 2 1, 2 6761.611 [m]
2 2 4781 137754181 [m^2] 100879.4 [m] 2 2, 3 24201.037 [m]
2.2 2 4781 137754181 [m^2] 100879.4 [m] 2 2, 4 31628.198 [m]
3 3 3424 295676500 [m^2] 212930.4 [m] 2 3, 4 22967.725 [m]
绘制前 4 GEOID
秒以检查是否按预期运行
ggplot(data = filter(SD, GEOID %in% 1:4),
aes(fill = as.factor(GEOID),
label = GEOID)) +
geom_sf(alpha = .2) +
geom_sf(data = filter(SD_overlap, map_lgl(origins, ~all(.x %in% 1:4))),
aes(color = map_chr(origins, ~paste(.x, collapse = ','))),
fill = NA,
lwd = 2,
show.legend = 'line') +
geom_sf_label(fill = "white", # override the fill from aes()
fun.geometry = sf::st_centroid) +
guides(fill = 'none')+
labs(color='Overlap')
要回答哪些种群相邻的问题,您可以尝试这样的方法。
sum_adj_pops <- function(GEOID_i){
ID_adj <- SD_overlap %>%
st_drop_geometry() %>%
filter(map_lgl(origins, ~GEOID_i %in% .x)) %>%
unnest_longer(origins) %>%
filter(origins != GEOID_i) %>%
pull(origins)
SD %>%
st_drop_geometry() %>%
filter(GEOID %in% ID_adj) %>%
summarize(POP_adj = sum(POP)) %>%
pull(POP_adj)
}
SD %>%
mutate(POP_adj = map_dbl(GEOID, sum_adj_pops))
#----
GEOID POP geometry POP_adj
1 1 6559 MULTIPOLYGON (((-86.64623 3... 24024
2 2 4781 MULTIPOLYGON (((-86.861 33.... 27132
3 3 3424 MULTIPOLYGON (((-86.97402 3... 21907
4 4 4230 MULTIPOLYGON (((-86.74407 3... 22259
5 5 7054 MULTIPOLYGON (((-87.78275 3... 22021
数据
url_shp <- 'https://github.com/ahadzaman1002/example_data/raw/main/fe_2007_01_sldu00.zip'
tmp_zip <- tempfile(fileext = '.zip')
tmp_dir <- tempdir()
download.file(url = url_shp, tmp_zip)
unzip(tmp_zip, exdir = tmp_dir)
path_shp <- list.files(tmp_dir, '.shp$', full.names = TRUE)
set.seed(415) #for reproducibility with sample()
SD <- st_read(path_shp) %>%
mutate(POP = sample(2000:8000, 35)) %>%
rowid_to_column('GEOID')
我在 Sample Data
有一个形状文件我将 R 中的数据读取为名为“SD”的 sf 对象,并包含“GEOID”和“geometry”列以及其他列。 我在名为“POP”的数据中创建了一个新列
SD$POP <- sample(2000:8000, 35)
首先,我想测量每个“GEOID”的面积和周长。
其次,我需要找出每个 GEOID 的周长与其周围的 GEOID 共享的比例。 例如:假设 GEOID 09 被 GEOID 06、08、10、13 包围。我想找出 GEOID 09 的周长与 06、08、10 和 13 分别共享的百分比。 然后创建新列“POP_PERCENT”和“ADJ_POP”这将是
ADJ-POP = SUM OF POP for GEOID 06, 08, 10, and 13' .
POP_PERCENT = Percent share with 06 + Percent share with 08 + Percent share with 10 +
Percent share with 13
对于冗长的问题,我深表歉意。如果有任何帮助,我将不胜感激。
我认为通常您需要的是 st_intersection
加上一些数据操作。数据集没有 GEOID
列,我不完全清楚 POP_PERCENT
的预期输出是什么(相邻人口按周长重叠百分比加权?)。所以这不是一个完全完整的答案。
这是使用 sf
和其他一些 tidyverse
函数的开始。这将计算每个多边形的面积、周长和交点。我从 rownames
创建了一个 GEOID
列。希望这足以让您朝着正确的方向前进。
先算出每个的面积和周长
library(tidyverse)
library(sf)
SD_ap <- SD %>%
st_transform(5070) %>% #convert from lat/long to projected coord system
mutate(area = st_area(.),
length_perim = lwgeom::st_perimeter(.))
#-----
GEOID POP geometry area perim
1 1 6582 MULTIPOLYGON (((860088.4 12... 357945281 [m^2] 139932.2 [m]
2 2 3199 MULTIPOLYGON (((843395.6 11... 137754181 [m^2] 100879.4 [m]
然后计算重叠周长。将多边形转换为线,然后 运行 st_intersection
。这 returns 141 条线段不是 35 个多边形,而是以原始重叠多边形 (origins
)
SD_overlap <- SD_ap %>%
st_cast('MULTILINESTRING') %>%
st_intersection() %>%
mutate(length_intersection = st_length(.)) %>%
filter(length_intersection > units::as_units(0,'m'))
#----
GEOID POP area length_perim n.overlaps origins length_intersection
1 1 6559 357945281 [m^2] 139932.2 [m] 2 1, 2 6761.611 [m]
2 2 4781 137754181 [m^2] 100879.4 [m] 2 2, 3 24201.037 [m]
2.2 2 4781 137754181 [m^2] 100879.4 [m] 2 2, 4 31628.198 [m]
3 3 3424 295676500 [m^2] 212930.4 [m] 2 3, 4 22967.725 [m]
绘制前 4 GEOID
秒以检查是否按预期运行
ggplot(data = filter(SD, GEOID %in% 1:4),
aes(fill = as.factor(GEOID),
label = GEOID)) +
geom_sf(alpha = .2) +
geom_sf(data = filter(SD_overlap, map_lgl(origins, ~all(.x %in% 1:4))),
aes(color = map_chr(origins, ~paste(.x, collapse = ','))),
fill = NA,
lwd = 2,
show.legend = 'line') +
geom_sf_label(fill = "white", # override the fill from aes()
fun.geometry = sf::st_centroid) +
guides(fill = 'none')+
labs(color='Overlap')
要回答哪些种群相邻的问题,您可以尝试这样的方法。
sum_adj_pops <- function(GEOID_i){
ID_adj <- SD_overlap %>%
st_drop_geometry() %>%
filter(map_lgl(origins, ~GEOID_i %in% .x)) %>%
unnest_longer(origins) %>%
filter(origins != GEOID_i) %>%
pull(origins)
SD %>%
st_drop_geometry() %>%
filter(GEOID %in% ID_adj) %>%
summarize(POP_adj = sum(POP)) %>%
pull(POP_adj)
}
SD %>%
mutate(POP_adj = map_dbl(GEOID, sum_adj_pops))
#----
GEOID POP geometry POP_adj
1 1 6559 MULTIPOLYGON (((-86.64623 3... 24024
2 2 4781 MULTIPOLYGON (((-86.861 33.... 27132
3 3 3424 MULTIPOLYGON (((-86.97402 3... 21907
4 4 4230 MULTIPOLYGON (((-86.74407 3... 22259
5 5 7054 MULTIPOLYGON (((-87.78275 3... 22021
数据
url_shp <- 'https://github.com/ahadzaman1002/example_data/raw/main/fe_2007_01_sldu00.zip'
tmp_zip <- tempfile(fileext = '.zip')
tmp_dir <- tempdir()
download.file(url = url_shp, tmp_zip)
unzip(tmp_zip, exdir = tmp_dir)
path_shp <- list.files(tmp_dir, '.shp$', full.names = TRUE)
set.seed(415) #for reproducibility with sample()
SD <- st_read(path_shp) %>%
mutate(POP = sample(2000:8000, 35)) %>%
rowid_to_column('GEOID')