我有 2 个数据集,一个用于医院,另一个用于程序。每个数据集都有纬度和经度坐标。 程序要么在医院内进行,要么在医院外进行,但如果在医院进行,坐标不一定精确。 我试图在每个医院周围形成一定大小的半径,并确定平均有多少手术点落在该半径内。 因此,例如,如果我有 100 家医院和 3000 个程序,我想在所有医院周围形成一个半径,并查看平均有多少家医院属于该指定半径。 我的初始代码如下,但我知道这可以更快地完成。 用 R 编码。 谢谢!
for(i in 1:NROW(hospitals)){
hospital <- hospitals[i,]
radius <- .016
# find all the procedures that lie in the .016 sized radius from this hospital
hospital$latitude_low <- hospital$lat - radius
hospital$longitude_low <- hospital$long - radius
hospital$latitude_high <- hospital$lat + radius
hospital$longitude_high <- hospital$long + radius
in_rad <- procedures[(procedures$long >= hospital$longitude_low & procedures$long <=
hospital$longitude_high & procedures$lat <= hospital$latitude_high & procedures$lat >=
hospital$latitude_low),]
num <- NROW(in_rad)
hospitals[i,]$number_of_procedures <- num
}
当您提出问题时,应始终包含一些示例数据。喜欢这个
lat <- c(-23.8, -25.8)
lon <- c(-49.6, -44.6)
hosp <- cbind(lon, lat)
lat <- c(-22.8, -24.8, -29.1, -28, -20)
lon <- c(-46.4, -46.3, -45.3, -40, -30)
procedures <- cbind(lon, lat)
您的数据是否在经度/纬度?如果是这样,则需要使用适当的方法来计算距离。例如
library(geosphere)
dm <- distm(procedures, hosp)
或
library(raster)
d <- pointDistance(procedures, hosp, lonlat=TRUE)
两者都计算从所有程序到所有医院的距离。这对于非常大的数据集会失败,但从您的描述来看,它应该可以正常工作。 现在,您可以使用阈值(此处为400,000 m(来找出每个医院在该距离内的哪些程序
apply(d < 400000, 2, which)
#[[1]]
#[1] 1 2
#[[2]]
#[1] 1 2 3
因此,程序 1、2 和 3 与医院 2 的距离内
如果数据不是经度/纬度,则可以使用
d <- pointDistance(procedures, hosp, lonlat=FALSE)
这里有几件事可以改进。首先,您实际上不是在计算距离医院 0.16 个单位半径内完成的程序,而是在以医院为中心的 0.32 * 0.32 个单位正方形内完成的程序。对于特定问题来说可能没什么大不了的,但实际上可以更快地计算出特定距离内的点,正如您实际预期的那样。
其次,你倾向于存储你计算过的任何变量,即使你只打算使用它们一次。这有助于理解代码,但有时效率较低,并且肯定会使您的代码更长,特别是如果您喜欢使用long_descriptive_variable_names
.
第三,最后,你对procedures
进行子集化,然后测量行数,而不仅仅是使用子集本身的长度。
最后(但不太重要(,将结果一次写入一个新列。您可以使用sapply
一口气完成所有操作。
因此,您的代码可以替换为更简单的内容,例如:
hospitals$number_of_procedures <- sapply(1:NROW(hospitals), function(i)
{
d <- (procedures$long - hospitals[i,]$long)^2 + (procedures$lat - hospitals[i,]$lat)^2
length(which(d < 0.16^2))
})