求和列基于 r 中 distHaversine 的 long/lat 的半径

Posted

技术标签:

【中文标题】求和列基于 r 中 distHaversine 的 long/lat 的半径【英文标题】:Sum column based on radius from long/lat from distHaversine in r 【发布时间】:2017-04-19 15:42:55 【问题描述】:

SO question 的延续

我有一个非常大的df,并且想为半径内的每个lat/long 求和列value

set.seed(1)
radius<-10000 # In meters
lat<-runif(10,-90,90)
long<-runif(10,-180,180)
value<- runif(10,200,7000)
id<-1:10
dat<-cbind(id,lat,long, value)

有没有一种高效的 RAM 方式来做到这一点?

原始帖子建议以下内容来计算半径内的出现次数,我想知道是否可以以类似的方式对列求和?

library(geosphere)
cbind(dat, X=rowSums(distm (dat[,3:2],
      fun = distHaversine) / 1000 <= 10000)) # number of points within distance 10000 km

【问题讨论】:

【参考方案1】:

天真的方式:

m <- distm(dat[, 3:2], fun = distHaversine) <= 1000*radius
X <- rowSums(m)
Y <- colSums(value * m)

cbind(dat, X, Y)
#       id       lat         long     value X         Y
#  [1,]  1 -42.20844 -105.8491530 6555.9956 5 18843.936
#  [2,]  2 -23.01770 -116.4395691 1642.5691 5 19627.074
#  [3,]  3  13.11361   67.3282248 4631.3816 5 10818.887
#  [4,]  4  73.47740  -41.7226614 1053.7747 6 17715.922
#  [5,]  5 -53.69725   97.1429112 2017.1005 4 15718.851
#  [6,]  6  71.71014   -0.8282728 2825.5758 6 17715.922
#  [7,]  7  80.04155   78.3426630  291.0543 6 17715.922
#  [8,]  8  28.94360  177.0861941 2800.2381 5  8613.212
#  [9,]  9  23.24053  -43.1873354 6113.8978 6 18482.867
# [10,] 10 -78.87847   99.8802797 2514.3732 4 12730.038

但如果你的数据真的很大,它就行不通了。在这种情况下,您必须避免计算所有距离。 This article 可能是一本好书。

【讨论】:

谢谢,distm 太大,所以您的建议无效 (cannot allocate vector of size 49142.8 Gb)。我有大约 250 万行。我会看一下这篇文章,但如果您有任何其他建议,请告诉我。 您的一些实际点是否靠近两极或第 180 条子午线?如果不是这样,实现文章的方法会更简单一些。 不,所有地点都在英国境内,我正在尝试按经度/纬度计算一定半径内的邮政编码(地点)数。【参考方案2】:

我在下面添加了一个使用 spatialrisk 包的解决方案。此包中的关键函数是用 C++ (Rcpp) 编写的,因此速度非常快。

首先,加载数据:

set.seed(1)
radius<-10000 # In meters
lat<-runif(10,-90,90)
long<-runif(10,-180,180)
value<- runif(10,200,7000)
id<-1:10
dat<-data.frame(id,lat,long, value)

然后:

spatialrisk::concentration(sub = dat, full = dat, 
                           value = value, lon_sub = long, 
                           lon_full = long, radius = 10000)

    id       lat         long     value concentration
 1   1 -42.20844 -105.8491530 6555.9956     6555.9956
 2   2 -23.01770 -116.4395691 1642.5691     1642.5691
 3   3  13.11361   67.3282248 4631.3816     4631.3816
 4   4  73.47740  -41.7226614 1053.7747     1053.7747
 5   5 -53.69725   97.1429112 2017.1005     2017.1005
 6   6  71.71014   -0.8282728 2825.5758     2825.5758
 7   7  80.04155   78.3426630  291.0543      291.0543
 8   8  28.94360  177.0861941 2800.2381     2800.2381
 9   9  23.24053  -43.1873354 6113.8978     6113.8978
 10 10 -78.87847   99.8802797 2514.3732     2514.3732

【讨论】:

以上是关于求和列基于 r 中 distHaversine 的 long/lat 的半径的主要内容,如果未能解决你的问题,请参考以下文章

优化 R 中大 df 的距离 distHaversine 模型

在 R 中,如何根据一列的值对所有其他列求和,而不指定列名?

基于日期键的 SQL 求和列

使用 dplyr 根据列值对 R 中的值求和

R Dataframe:根据其他2个列匹配对未定义的num列求和

用于在 R 中创建和求和子集的用户定义函数