将不同的 sf 函数应用于数据框中的组

Apply different sf functions to groups in a data frame

我正在尝试使用一组管道 dplyr 函数调用在单个简单要素数据框中计算不同的欧几里德缓冲区(一个 400m 和一个 800m)。应根据分组变量的值为每个要素指定缓冲距离。我可以根据分组变量的已知值轻松拆分数据框,但我想让该方法尽可能通用。

以下代码有效,但显然只有 return所有组的单个 400m 缓冲区:

library(sf)
library(dplyr)

set.seed(42)
nc <- st_read(system.file("shape/nc.shp", package="sf"))
nc$grp <- sample(c(0,1), replace = TRUE, size = 100)

nc_buff <- nc %>%
  group_by(grp) %>%
  st_transform(32119) %>%
  group_map(~ st_buffer(.x, 400))

理想情况下,我会拆分数据帧,计算每个缓冲区,然后 return 将两组缓冲区组合在一起的单个简单特征数据帧。

如何 return 包含 grp == 0 的 400m 缓冲区和 grp == 1 的 800m 缓冲区的单个数据帧?

看起来这样就可以了。 bind_rows() 可通过管道传输,但目前无法在简单要素数据帧上正常工作。

library(sf)
library(dplyr)

set.seed(42)
nc <- st_read(system.file("shape/nc.shp", package="sf"))
nc$grp <- sample(c(0,1), replace = TRUE, size = 100)

nc_buff <- nc %>%
  group_by(grp) %>%
  st_transform(32119) %>%
  group_map(~ st_buffer(.x, case_when(.y$grp == 0 ~ 400, .y$grp == 1 ~ 800)))

# No way to bind_rows() with sf data frames yet so this extra step is needed
# https://github.com/r-spatial/sf/issues/798
nc_buff <- do.call(rbind, nc_buff)

注意:此处给出了更喜欢 do.call(rbind, ) 而不是 bind_rows() 的类似推理:.

您实际上不需要 group 数据并使用 group_map。你 实际上可以将缓冲区宽度向量直接传递给 st_buffer:

library(sf)
library(dplyr) 
set.seed(42)
nc <- st_read(system.file("/shape/nc.shp", package="sf")) %>% 
    st_transform(32119) %>%
    st_centroid() %>% 
    mutate(grp = sample(c(0,1), 100, replace = TRUE))

在这里,我即时“创建”缓冲区宽度列

nc_buff <- nc %>%
  st_buffer(., ifelse(.$grp == 0, 4000, 8000))

plot(nc_buff["NAME"])

对于更复杂的情况或提高可读性,您还可以使用 mutate 预先创建缓冲区列,例如使用 ifelsecase_when:

 nc_buff <- nc %>%
  mutate(buf_wdt = ifelse(.$grp == 0, 4000, 8000)) %>% 
  st_buffer(., .$buf_wdt) %>% 
  select(-buf_wdt)  

HTH!

reprex package (v0.3.0)

于 2019-12-27 创建