【问题标题】:Parallelize st_union from R's sf package从 R 的 sf 包中并行化 st_union
【发布时间】:2022-04-17 21:58:24
【问题描述】:

我有一些包含数百万个多边形的大型 shapefile,需要解散。根据 shapefile,我需要按组解散,或者只使用st_union。我一直在使用st_parfunction,它对大多数科幻应用程序都非常有效。虽然当我在st_union 上使用此函数时,它会返回一个列表,但我无法弄清楚如何使 sf 溶解函数 st_union 并行化。

任何建议都会很有帮助!这是一个小代码sn-p来说明我的观点。

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)

【问题讨论】:

  • 不错的主题和很好的例子,但us_prefix 没有定义,你还应该添加使用的包。
  • 感谢您的提示 - 我修复了未定义的对象(以为我在编写过程中摆脱了它)并添加了库。

标签: r sf


【解决方案1】:

我认为您可以通过对原始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_union 非常有效,但不适用于其他操作——这正是我所希望的。这是向前迈出的一大步,将使我能够继续我的工作。同时我想我会听取你的建议并尝试联系该函数的作者,看看它是否可以更适应sf 包。
  • 太棒了!如果您从作者那里收到有趣的反馈,您能否在此处发帖让我了解情况?谢谢!
  • 我一定会的。再次感谢您的帮助,我会与您联系。
  • st_par 函数的创建者 Phil Donovan 对其进行了更新,使其对其他类型的 sf 对象更加健壮...spatialanalytics.co.nz/post/2018/04/01/fixing-st-par
【解决方案2】:

我试图将它用于st_join,但遇到了返回数据类型的问题。在更仔细地查看结果时,很明显split_results 只是sf 对象的列表。我最终修改了代码以使用dplyr::bind_rows() 来获得我想要的。

围绕“组合”可能需要更多逻辑来处理不同的返回类型,但这适用于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)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 2019-05-07
    • 2016-03-06
    • 2015-03-21
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    相关资源
    最近更新 更多