R 计算数据帧中多个横向长点的中心点
我的数据集如下所示:R 计算数据帧中多个横向长点的中心点,r,geospatial,geosphere,R,Geospatial,Geosphere,我的数据集如下所示: site lat long bras2 41.21 -115.11 tex4 45.3 -112.31 bras2 41.15 -115.15 bras2 41.12 -115.19 对于具有相同站点名称的样本,我希望计算它们的中心点,然后将其作为列添加到数据集中。一些站点名称重复了两次,其他三次,其他四次 像这样: site lat long centre_lat centre_long bras2
site lat long
bras2 41.21 -115.11
tex4 45.3 -112.31
bras2 41.15 -115.15
bras2 41.12 -115.19
对于具有相同站点
名称的样本,我希望计算它们的中心点,然后将其作为列添加到数据集中。一些站点
名称重复了两次,其他三次,其他四次
像这样:
site lat long centre_lat centre_long
bras2 41.21 -115.11 value here value here
tex4 45.3 -112.31 45.3 -112.31
bras2 41.15 -115.15 value here value here
bras2 41.12 -115.19 value here value here
如何做到这一点?在使用
gsub
去除站点编号后,您可以使用ave
计算站点名称分组的平均值
within(dat, {
g <- gsub("\\d", "", site)
mid.lat <- ave(lat, g)
mid.long <- ave(long, g)
rm(g)
})
# site lat long mid.long mid.lat
# 1 bras2 41.21 -115.11 -115.150 41.160
# 2 tex4 45.30 -112.31 -112.310 45.300
# 3 bras2 41.15 -115.15 -115.150 41.160
# 4 bras2 41.12 -115.19 -115.150 41.160
# 5 foo1 42.10 -123.10 -123.225 42.225
# 6 foo2 42.20 -123.20 -123.225 42.225
# 7 foo11 42.30 -123.30 -123.225 42.225
# 8 foo12 42.30 -123.30 -123.225 42.225
数据:
datgeosphere软件包有一个功能centroid
,用于解决此类问题。
只要形状上有多个点,它就是笔直的。下面的大多数代码都涉及处理上面示例中的单点情况
df <- read.table(header=TRUE, text= "site lat long
bras2 41.21 -115.11
tex4 45.3 -112.31
bras2 41.15 -115.15
bras2 41.12 -115.19")
library(dplyr)
library(geosphere)
df %>% group_by(side) %>% centroid(.[ ,c(3,2)])
sites <- split(df, df$site)
results <-lapply(sites, function(x) {
if(nrow(x)>1 ) {
value <- as.data.frame(centroid(x[, c(3,2)]))
}
else {
value <- x[1, c(3,2)]
names(value) <- c("lon", "lat")
}
value$site <- x$site[1]
value
})
answer<-bind_rows(results)
lon lat site
1 -115.15 41.16001 bras2
2 -112.31 45.30000 tex4
df%group_by(side)%%>%centroid([,c(3,2)])
站点如果您使用的是空间数据,您应该考虑使用sf
包。它处理几何图形和函数,以便在其上运行良好
下面的代码显示了如何同时使用sf::st_形心
和geosphere::centroid
。我更喜欢sf的做事方式
df中点是位于测地线上的单个点,该测地线连接两个点,并且与这两个点等距。无论您认为三个点之间的中点是什么,这都不是middpoint
计算的计算。它只期望得到两点。你想的是多个点的质心吗?是的,质心。非常感谢,关于中点是什么,我搞错了。嗨!非常感谢。一个问题-在这种情况下,ave
是平均值吗?那么,它只是简单地取同一站点下所有纬度和经度的平均值吗?由于地球的曲率,我不确定是否可以计算出这样的中心?如果我错了,请纠正我。@fifigoblin Yes,ave
将第一个参数按第二个参数分组,并应用默认为mean
的函数,请参阅帮助(“ave”)
。我承认自己不是专家,但当考虑GPS坐标作为矩形投影时,曲率应该无关紧要。在中,他们用平均值类似地计算质心。@fifigoblin计算将基于。Hi!非常感谢。我可以问一下,这段代码将如何处理有2个点且无法生成多边形的情况吗?它会忽略这些情况吗?上面的geosphere
方法将删除少于3个点的位置。sf
方法适用于1、2和3+点。我建议使用sf
方法。谢谢-现在已经清楚了
dat <- structure(list(site = c("bras2", "tex4", "bras2", "bras2", "foo1",
"foo2", "foo11", "foo12"), lat = c(41.21, 45.3, 41.15, 41.12,
42.1, 42.2, 42.3, 42.3), long = c(-115.11, -112.31, -115.15,
-115.19, -123.1, -123.2, -123.3, -123.3)), class = "data.frame", row.names = c(NA,
-8L))
df <- read.table(header=TRUE, text= "site lat long
bras2 41.21 -115.11
tex4 45.3 -112.31
bras2 41.15 -115.15
bras2 41.12 -115.19")
library(dplyr)
library(geosphere)
df %>% group_by(side) %>% centroid(.[ ,c(3,2)])
sites <- split(df, df$site)
results <-lapply(sites, function(x) {
if(nrow(x)>1 ) {
value <- as.data.frame(centroid(x[, c(3,2)]))
}
else {
value <- x[1, c(3,2)]
names(value) <- c("lon", "lat")
}
value$site <- x$site[1]
value
})
answer<-bind_rows(results)
lon lat site
1 -115.15 41.16001 bras2
2 -112.31 45.30000 tex4