Как рассчитать среднее пространственное местоположение по группе - PullRequest
1 голос
/ 10 июня 2019

Мне нужно рассчитать среднее местоположение для пространственных данных с переменными долготы и широты. Операция должна быть сделана группой, что несколько усложняет ситуацию. Я смог сделать это для простого взвешенного среднего значения (пример ниже), но более сложный показатель не так легко реализовать.

Пример данных:

df <- data.frame(longitude = c(22, 23, 24, 25, 26, 27),
                 latitude = c(56, 57, 58, 59, 60, 61),
                 weight = c(1, 2, 3, 1, 2, 3),
                 group = c("A", "A", "A", "B", "B", "B"))

Простое взвешенное среднее:

dfMean <- df %>%
      group_by(group) %>%
      summarize_at(vars(longitude, latitude), list(~weighted.mean(., weight))) %>%
      ungroup

Я хочу вычислить это с помощью функции geopshere::geomean. Проблема в том, что вывод функции представляет собой матрицу из двух столбцов, которая не совместима с dplyr::summarize. Любые предложения о том, как добиться этого эффективно?

Ответы [ 2 ]

3 голосов
/ 10 июня 2019

Один из способов - вложить данные по группам, а затем использовать map() для перебора сгруппированных данных.

library(geosphere)
library(tidyverse)

df %>% 
  nest(-group) %>%
  mutate(gmean = map(data, ~data.frame(geomean(xy = cbind(.x$longitude, .x$latitude), w = .x$weight)))) %>%
  unnest(gmean)

# A tibble: 2 x 4
  group data                 x     y
  <fct> <list>           <dbl> <dbl>
1 A     <tibble [3 x 3]>  23.3  57.3
2 B     <tibble [3 x 3]>  26.3  60.3

Или то же самое, используя summarise:

df %>%
  group_by(group) %>%
  summarise(gmean = list(data.frame(geomean(cbind(longitude, latitude), w = weight)))) %>%
  unnest(gmean)
1 голос
/ 10 июня 2019

Один из вариантов - получить значение из geomean в строку через запятую и затем separate в разные столбцы.

library(dplyr)
library(tidyr)
library(geosphere)

df %>%
  group_by(group) %>%
  summarise(val = toString(geomean(cbind(longitude, latitude), weight))) %>%
  separate(val, c("cord1", "cord2"), sep = ",") %>%
  mutate_at(2:3, as.numeric)

# A tibble: 2 x 3
#    group cord1 cord2
#    <fct> <dbl> <dbl>
#1   A      23.3  57.3
#2   B      26.3  60.3
...