我有一个数据集,列出了美国的所有邮政编码及其类型(标准、邮政信箱、大学等)。我想用下一个最接近的标准邮政编码替换邮政信箱和大学邮政编码。我按状态分解数据集,这样 R 就不必进行那么多计算。理论上,我想在第一列有标准邮政编码,在第一行有需要替换的邮政编码,并将两者之间的距离作为交点值。
例如,
REP 1 REP 2 REP 3 REP 4
STD 1 0.215 0.152 0.025 0.124
STD 2 0.365 0.410 0.074 0.234
STD 3 0.234 0.201 1.322 0.683
STD 4 0.543 0.282 0.483 0.094
MINS STD 1 STD 1 STD 2 STD 4
其中 STD 1 是标准邮政编码,具有自己的经纬度,REP 1 是需要替换的邮政编码(是大学/邮政信箱邮政编码),具有自己的经度和纬度。我只有大约 5 周的 R 经验,所以如果有些事情对我来说不是很有意义,请多多包涵。我曾尝试在 excel 中执行此操作,并且每次尝试计算所有距离时,由于计算太多,因此每次尝试计算所有距离时,都会有一张包含近 10,000 列乘以 40,000 行的表格崩溃。
我觉得这里需要apply()or函数。mapply()我想使用考虑地球曲率(欧几里得等)的公式dist()或geosphere包来计算距离,以保持准确性和可重复性。
如果还有什么可以在这里添加的,请告诉我,我会尽快上传。这是我在阿拉斯加的 R 代码,按字母顺序排列的第一个州。
AK<-subset(db,STAABBRV.x=="AK")
AKPO<-subset(AK,ZipCodeType!="STANDARD",select=c("ZIP_CODE","ZipCodeType","Long","Lat"))
AKPO<-within(AKPO,{IS_PO=ifelse(ZipCodeType!="STANDARD",1,0)})
AKSTANDARD<-subset(AK,ZipCodeType=="STANDARD",select=c("ZIP_CODE","ZipCodeType","Long","Lat"))
AKSTANDARD<-within(AKSTANDARD,{IS_PO=ifelse(ZipCodeType!="STANDARD",1,0)})
table<-rbind(AKSTANDARD,AKPO)
table$ZipCodeType<-NULL
rm(AK,AKPO,AKSTANDARD)
这将设置一个具有列名称“ZIP_CODE”、“Long”、“Lat”和“IS_PO”的表。“IS_PO”是邮政编码是标准还是 po/university 的数字指示符。1 表示邮政编码是 po/univ 邮政编码,0 表示标准邮政编码。我这样做是因为某些函数要求数据集中的数据是同一类型(数字)。
以下是我编写代码来计算最小距离的一些失败尝试。
lapply(bit::chunk(1, nrow(zipcode), 1e2), function(ridx) {
merge(zipcode, zipcode[ridx[1]:ridx[2]], by = "dum", allow.cartesian = T)[
, dist := distGeo(matrix(c(longitude.x, latitude.x), ncol = 2),
matrix(c(longitude.y, latitude.y), ncol = 2))/1609.34 # meters to miles
][dist <= 5 # necessary distance treshold
][, dum := NULL]
}) %>% rbindlist -> zip_nearby_dt
DOESITWORK<-apply(db, 1, function(x) spDistsN1(matrix(x[3:4], nrow=1),
x[5:6],
longlat=TRUE))
mins<-apply(Lat,1,function(x)return(array(which.min(x))))
mins<-data.frame(row=names(mins),col=mins)
Lat$mins<-apply(mins,1,FUN=function(x)return(paste(x["row"],colnames(Lat[as.numeric(x["col"])]),Lat[x["row"],as.numeric(x["col"])],sep="/")))