从 R 的 sf 包中并行化 st_union
Parallelize st_union from R's sf package
我有一些大型 shapefile,其中包含数百万个多边形,我需要对其进行溶解。根据 shapefile,我需要按组溶解或只对所有使用 st_union
。我一直在使用 st_par
function 并且它对大多数 sf 应用程序都非常有效。尽管当我在 st_union
上使用此函数时,它 returns 是一个列表,但我不知道如何并行化 sf 溶解函数 st_union
.
任何建议都会很有帮助!这是一个小代码片段来说明我的观点。
library(sf)
library(assertthat)
library(parallel)
us_shp <- "data/cb_2016_us_state_20m/cb_2016_us_state_20m.shp"
if (!file.exists(us_shp)) {
loc <- "https://www2.census.gov/geo/tiger/GENZ2016/shp/cb_2016_us_state_20m.zip"
dest <- paste0("data/cb_2016_us_state_20m", ".zip")
download.file(loc, dest)
unzip(dest, exdir = "data/cb_2016_us_state_20m")
unlink(dest)
assert_that(file.exists(us_shp))
}
usa <- st_read("data/cb_2016_us_state_20m/cb_2016_us_state_20m.shp", quiet= TRUE) %>%
filter(!(STUSPS %in% c("AK", "HI", "PR")))
test <- usa %>%
st_par(., st_union, n_cores = 2)
我认为你可以通过对原始文件进行小的修改来解决你的具体问题st_par
function。
然而,这只是一个快速而大胆的修复,这可能会破坏该函数其他用途的代码。
该函数的作者当然可以提供更好的修复...
library(parallel)
# Paralise any simple features analysis.
st_par <- function(sf_df, sf_func, n_cores, ...){
# Create a vector to split the data set up by.
split_vector <- rep(1:n_cores, each = nrow(sf_df) / n_cores, length.out = nrow(sf_df))
# Perform GIS analysis
split_results <- split(sf_df, split_vector) %>%
mclapply(function(x) sf_func(x), mc.cores = n_cores)
# Combine results back together. Method of combining depends on the output from the function.
if ( length(class(split_results[[1]]))>1 | class(split_results[[1]])[1] == 'list' ){
result <- do.call("c", split_results)
names(result) <- NULL
} else {
result <- do.call("rbind", split_results)
}
# Return result
return(result)
}
我试图将其用于 st_join
,但 运行 遇到了 returned 数据类型的问题。在更仔细地查看结果时,很明显 split_results
只是 sf
对象的列表。我最终修改了代码以使用 dplyr::bind_rows()
来获得我想要的。
“组合”可能需要更多逻辑来处理不同的 return 类型,但这适用于 st_join
函数。
# Parallelise any simple features analysis.
st_par <- function(sf_df, sf_func, n_cores, ...) {
# Create a vector to split the data set up by.
split_vector <- rep(1:n_cores, each = nrow(sf_df) / n_cores, length.out = nrow(sf_df))
# Perform GIS analysis
split_results <- split(sf_df, split_vector) %>%
mclapply(function(x) sf_func(x, ...), mc.cores = n_cores)
# Combine results back together. Method of combining probably depends on the
# output from the function. For st_join it is a list of sf objects. This
# satisfies my needs for reverse geocoding
result <- dplyr::bind_rows(split_results)
# Return result
return(result)
}
我有一些大型 shapefile,其中包含数百万个多边形,我需要对其进行溶解。根据 shapefile,我需要按组溶解或只对所有使用 st_union
。我一直在使用 st_par
function 并且它对大多数 sf 应用程序都非常有效。尽管当我在 st_union
上使用此函数时,它 returns 是一个列表,但我不知道如何并行化 sf 溶解函数 st_union
.
任何建议都会很有帮助!这是一个小代码片段来说明我的观点。
library(sf)
library(assertthat)
library(parallel)
us_shp <- "data/cb_2016_us_state_20m/cb_2016_us_state_20m.shp"
if (!file.exists(us_shp)) {
loc <- "https://www2.census.gov/geo/tiger/GENZ2016/shp/cb_2016_us_state_20m.zip"
dest <- paste0("data/cb_2016_us_state_20m", ".zip")
download.file(loc, dest)
unzip(dest, exdir = "data/cb_2016_us_state_20m")
unlink(dest)
assert_that(file.exists(us_shp))
}
usa <- st_read("data/cb_2016_us_state_20m/cb_2016_us_state_20m.shp", quiet= TRUE) %>%
filter(!(STUSPS %in% c("AK", "HI", "PR")))
test <- usa %>%
st_par(., st_union, n_cores = 2)
我认为你可以通过对原始文件进行小的修改来解决你的具体问题st_par
function。
然而,这只是一个快速而大胆的修复,这可能会破坏该函数其他用途的代码。
该函数的作者当然可以提供更好的修复...
library(parallel)
# Paralise any simple features analysis.
st_par <- function(sf_df, sf_func, n_cores, ...){
# Create a vector to split the data set up by.
split_vector <- rep(1:n_cores, each = nrow(sf_df) / n_cores, length.out = nrow(sf_df))
# Perform GIS analysis
split_results <- split(sf_df, split_vector) %>%
mclapply(function(x) sf_func(x), mc.cores = n_cores)
# Combine results back together. Method of combining depends on the output from the function.
if ( length(class(split_results[[1]]))>1 | class(split_results[[1]])[1] == 'list' ){
result <- do.call("c", split_results)
names(result) <- NULL
} else {
result <- do.call("rbind", split_results)
}
# Return result
return(result)
}
我试图将其用于 st_join
,但 运行 遇到了 returned 数据类型的问题。在更仔细地查看结果时,很明显 split_results
只是 sf
对象的列表。我最终修改了代码以使用 dplyr::bind_rows()
来获得我想要的。
“组合”可能需要更多逻辑来处理不同的 return 类型,但这适用于 st_join
函数。
# Parallelise any simple features analysis.
st_par <- function(sf_df, sf_func, n_cores, ...) {
# Create a vector to split the data set up by.
split_vector <- rep(1:n_cores, each = nrow(sf_df) / n_cores, length.out = nrow(sf_df))
# Perform GIS analysis
split_results <- split(sf_df, split_vector) %>%
mclapply(function(x) sf_func(x, ...), mc.cores = n_cores)
# Combine results back together. Method of combining probably depends on the
# output from the function. For st_join it is a list of sf objects. This
# satisfies my needs for reverse geocoding
result <- dplyr::bind_rows(split_results)
# Return result
return(result)
}