我需要使用经度和纬度变量计算空间数据的平均位置。该操作需要按组完成,这使事情有些复杂。我已经能够为简单的加权平均值(下面的示例)执行此操作,但更复杂的度量并不容易实现。
示例数据:
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
不兼容。关于如何有效地实现这一目标的任何建议?
一种方法是按组嵌套数据,然后使用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)
一种选择是将值从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