根据 R 中 sf 的分组变量计算点云的平均值
Calculate the average of a cloud of points based on a grouping variable with sf in R
我有一堆要计算每个分组变量汇总的平均值的点:
x = st_sfc(st_polygon(list(rbind(c(0,0),c(90,0),c(90,90),c(0,90),c(0,0)))), crs = st_crs(4326))
plot(x, axes = TRUE, graticule = TRUE)
plot(p <- st_sample(x, 7), add = TRUE)
p=st_as_sf(p)
p$test=c("A","A","B","C","C","D","D")
像这样使用dplyr
时,我得到了一个NA。
p %>%
group_by(test) %>%
summarize(geometry = mean(geometry))
我只想求几何的平均值,不是1点,也不是多点。
不确定是否完全理解您要查找的内容,但我正在试一试!
因此,请使用 sf
和 dplyr
库找到一种可能的解决方案,其中包含以下 reprex。我猜你是在寻找 aggregate()
函数而不是 group_by()
Reprex
- 代码
library(sf)
library(dplyr)
R1 <- p %>% aggregate(.,
by = list(.$test),
function(x) x = x[1]) %>%
st_centroid() %>%
select(-Group.1)
#> Warning in st_centroid.sf(.): st_centroid assumes attributes are constant over
#> geometries of x
- 输出 1(sf 对象)
R1
#> Simple feature collection with 4 features and 1 field
#> Attribute-geometry relationship: 0 constant, 1 aggregate, 0 identity
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: 2.7875 ymin: 12.91954 xmax: 59.60413 ymax: 51.81421
#> Geodetic CRS: WGS 84
#> test geometry
#> 1 A POINT (27.17167 12.91954)
#> 2 B POINT (2.7875 22.54184)
#> 3 C POINT (59.60413 46.90029)
#> 4 D POINT (56.34763 51.81421)
- 补充代码和输出 2(即,如果您只需要一个数据框)
R2 <- R1 %>%
st_coordinates() %>%
cbind(st_drop_geometry(R1),.)
R2
#> test X Y
#> 1 A 27.17167 12.91954
#> 2 B 2.78750 22.54184
#> 3 C 59.60413 46.90029
#> 4 D 56.34763 51.81421
- 可视化
plot(x)
plot(p, add = TRUE)
plot(R1, pch = 15, add = TRUE)
点是您的数据,小方块是每个组的质心
(仅供参考,出于再现性目的,我将种子设置为 427
)
- 注意: 以上使用球面几何。如果你想做平面计算,你只需要在脚本的开头添加
sf_use_s2(FALSE)
。为了向您展示差异,这里是使用 sf_use_s2(FALSE)
的结果(在这种情况下,您可以看到,对于每个组,质心恰好位于连接两点的线上;
由您根据需要选择)
由 reprex package (v2.0.1)
创建于 2022-01-03
我有一堆要计算每个分组变量汇总的平均值的点:
x = st_sfc(st_polygon(list(rbind(c(0,0),c(90,0),c(90,90),c(0,90),c(0,0)))), crs = st_crs(4326))
plot(x, axes = TRUE, graticule = TRUE)
plot(p <- st_sample(x, 7), add = TRUE)
p=st_as_sf(p)
p$test=c("A","A","B","C","C","D","D")
像这样使用dplyr
时,我得到了一个NA。
p %>%
group_by(test) %>%
summarize(geometry = mean(geometry))
我只想求几何的平均值,不是1点,也不是多点。
不确定是否完全理解您要查找的内容,但我正在试一试!
因此,请使用 sf
和 dplyr
库找到一种可能的解决方案,其中包含以下 reprex。我猜你是在寻找 aggregate()
函数而不是 group_by()
Reprex
- 代码
library(sf)
library(dplyr)
R1 <- p %>% aggregate(.,
by = list(.$test),
function(x) x = x[1]) %>%
st_centroid() %>%
select(-Group.1)
#> Warning in st_centroid.sf(.): st_centroid assumes attributes are constant over
#> geometries of x
- 输出 1(sf 对象)
R1
#> Simple feature collection with 4 features and 1 field
#> Attribute-geometry relationship: 0 constant, 1 aggregate, 0 identity
#> Geometry type: POINT
#> Dimension: XY
#> Bounding box: xmin: 2.7875 ymin: 12.91954 xmax: 59.60413 ymax: 51.81421
#> Geodetic CRS: WGS 84
#> test geometry
#> 1 A POINT (27.17167 12.91954)
#> 2 B POINT (2.7875 22.54184)
#> 3 C POINT (59.60413 46.90029)
#> 4 D POINT (56.34763 51.81421)
- 补充代码和输出 2(即,如果您只需要一个数据框)
R2 <- R1 %>%
st_coordinates() %>%
cbind(st_drop_geometry(R1),.)
R2
#> test X Y
#> 1 A 27.17167 12.91954
#> 2 B 2.78750 22.54184
#> 3 C 59.60413 46.90029
#> 4 D 56.34763 51.81421
- 可视化
plot(x)
plot(p, add = TRUE)
plot(R1, pch = 15, add = TRUE)
点是您的数据,小方块是每个组的质心
(仅供参考,出于再现性目的,我将种子设置为 427
)
- 注意: 以上使用球面几何。如果你想做平面计算,你只需要在脚本的开头添加
sf_use_s2(FALSE)
。为了向您展示差异,这里是使用sf_use_s2(FALSE)
的结果(在这种情况下,您可以看到,对于每个组,质心恰好位于连接两点的线上; 由您根据需要选择)
由 reprex package (v2.0.1)
创建于 2022-01-03