【问题标题】:R - Loop through df of IDs and Zipcodes to find next closest store (lat/longitude), return list of Store ID, and next closest StoreR - 遍历 ID 和 Zipcode 的 df 以查找下一个最近的商店(纬度/经度),返回商店 ID 列表和下一个最近的商店
【发布时间】:2017-07-24 22:40:05
【问题描述】:

我已经使用 zipcode 包来获取基于 zipcode 的一堆商店的 zipcode 的纬度和经度。

我希望找到一种循环遍历列表的方法,并针对 5000 家商店中的每家商店,根据 Long/Lat 找到下一个最近的商店。

我目前有这个数据框(删除了这篇文章的值):

'data.frame':   1206 obs. of  6 variables:
 $ zip      : Factor w/ 1182 levels "86645","43225",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ ID       : int  
 $ city     : chr  
 $ state    : chr  
 $ latitude : num  
 $ longitude: num  

【问题讨论】:

  • 您能否分享您的部分数据以便我们提出解决方案?你可以使用dput(head(mydataframe,10))
  • 我上面有一些示例数据 - 谢谢 :)

标签: r loops zipcode


【解决方案1】:

这是我能想到的一种解决方案:

library(data.table)
library(zipcode)
library(geosphere)
data(zipcode)
set.seed(151)
n <- 100
storeData <- data.table(storeID=sample(1:100000,n,replace = FALSE),zip=sample(zipcode$zip,n,replace = TRUE))
zipcode <- data.table(zipcode,key = "zip")
storeData <- zipcode[storeData,on="zip"][!is.na(latitude)|!is.na(longitude)]
storeData
storeData
# zip             city state latitude  longitude storeID
# 1: 22408   Fredericksburg    VA 38.23602  -77.46111   47945
# 2: 44515       Youngstown    OH 41.09901  -80.74545   86541
# 3: 48112       Belleville    MI 42.23993  -83.15082   77807
# 4: 80154        Englewood    CO 39.73875 -104.40835   53862
# 5: 73766       Pond Creek    OK 36.66271  -97.83063   44166
# 6: 32321          Bristol    FL 30.36007  -84.97668   61377
# 7: 49442         Muskegon    MI 43.23262  -86.19550   45492
# 8: 04537         Boothbay    ME 43.90781  -69.64608   82087
storeDistances <- distm(storeData[,.(longitude,latitude)],storeData[,.(longitude,latitude)])
colnames(storeDistances) <- rownames(storeDistances) <- storeData[,storeID]
getClosest <- function(number=1){
  apply(storeDistances,1,function(x) (colnames(storeDistances)[which(x==sort(x)[number+1])]))
}
storeData[,firstClosest:=getClosest(1)]
storeData[,secondClosest:=getClosest(2)]
storeData[,thirdClosest:=getClosest(3)]
storeData
# zip             city state latitude  longitude storeID firstClosest secondClosest
# 1: 22408   Fredericksburg    VA 38.23602  -77.46111   47945        70091         41024
# 2: 44515       Youngstown    OH 41.09901  -80.74545   86541        10806         78898
# 3: 48112       Belleville    MI 42.23993  -83.15082   77807        25906         94780
# 4: 80154        Englewood    CO 39.73875 -104.40835   53862        22347         91392
# 5: 73766       Pond Creek    OK 36.66271  -97.83063   44166         4816         90090
# 6: 32321          Bristol    FL 30.36007  -84.97668   61377         8187          1937
# 7: 49442         Muskegon    MI 43.23262  -86.19550   45492        95486         97241
# 8: 04537         Boothbay    ME 43.90781  -69.64608   82087        46720          7013
# 
# thirdClosest
# 1:        57562
# 2:        71232
# 3:        86541
# 4:        97986
# 5:          146
# 6:         8113
# 7:         6400
# 8:        10872

storeDistances 是每个商店之间的距离矩阵。 getClosest 函数获取最近的商店。

【讨论】:

  • @MegCantwell 我创建了一个示例数据,这只是一个参考,可能与您的数据不完全一致。您可能需要对其进行一些修改以使其适用于您的数据,例如更改名称、数据类型等。
  • @MegCantwell for 循环通常效率低下,所以我尽量避免使用它们。您是否需要解释任何特定功能?我在回答中写了一些解释,但我不知道这是否足够。
  • @A Gore - 看起来代码对于某些邮政编码有点错误......在 csv 输出中,有一堆 c("store ID", "Store ID", “商店 ID”) - storeID 是其他商店 IDS - 有趣的是它只发生在某些商店中......任何想法/我正在尝试 QC
  • @mcando 这可能会发生,因为如果两个商店与特定商店的距离相等,那么它们都会被选中。
猜你喜欢
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 2017-10-06
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多