在Sf中使用group_by找到相距最远的两个点

问题描述

尽管有几个相关问题,但未能找到准确的Q / A来解决此问题。我正在尝试为ID列定义的所有点组计算距离矩阵。然后选择与每个组相距最远的两个点,并保留原始组ID。每组中的点数从2、4或6不等。

我的sf df:

    df <- data.frame(x = runif(12),y = runif(12),id = rep(1:3,each = 4)) %>% 
      st_as_sf(coords = c("x","y"),crs = 27700)

我尝试过以下代码

a <- df %>% 
      group_by(id) %>% 
      st_distance(.)

尽管这只会返回所有点的距离矩阵。

下面给出了我想要的内容,尽管我担心大型数据集会很慢:

  maxMin <- do.call(rbind,lapply(unique(allInts$id),function(x) {
      df <- allInts %>% filter(id == x)
      d <- st_distance(df)
      df %>% slice(unique(as.vector(which(d == max(d),arr.ind=T))))
    }))

解决方法

您可以使用dplyr::group_split将数据框分成每个组的列表。然后,您可以使用map / lapply将所需的任何功能应用于该列表。

下面的脚本将每组中距离最远的2个点保持不变。

library(sf)
library(tidyverse)

# dummy data
data <- data.frame(x = runif(12),y = runif(12),id = rep(1:3,each = 4)) %>% 
st_as_sf(coords = c("x","y"),crs = 27700)

# split it into a list per ID
data_group <- data %>% 
group_by(id) %>%
group_split()

#apply a function to each list
distance_per_group <- map(data_group,function(x){
distance_matrix <- st_distance(x)
biggest_distance <- as.numeric(which(distance_matrix == max(distance_matrix),arr.ind = TRUE)[1,])
farthest_apart <- x[biggest_distance,]
})