Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 计算数据帧中多个横向长点的中心点_R_Geospatial_Geosphere - Fatal编程技术网

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