从 R 的 sf 包中并行化 st_union

nat*_*e-m 5 r r-sf

我有一些包含数百万个多边形的大型 shapefile 需要解散。根据 shapefile,我需要按组溶解或仅st_union用于所有人。我一直在使用该st_par 功能,它对大多数科幻应用程序都非常有效。虽然当我在st_union它上面使用这个函数时会返回一个列表,但我无法弄清楚如何并行化 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)
Run Code Online (Sandbox Code Playgroud)

Gil*_*les 2

st_par我认为您可以通过对原始功能进行小修改来解决您的具体问题。
然而,这只是一个快速而大胆的修复,这可能会破坏该函数其他用途的代码。
该函数的作者当然可以提供更好的修复......

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)
}
Run Code Online (Sandbox Code Playgroud)

  • st_par 函数的创建者 Phil Donovan 对其进行了更新,使其对其他类型的 sf 对象更加稳健...... http://www.spatialanalytics.co.nz/post/2018/04/01/fixing-st-标准杆/ (4认同)