使用需要四个向量的函数在R中迭代
我试图使用geosphere包中的Distaversine函数来计算多个城市之间的距离。此代码需要多种参数: 第一位的经度和纬度。 第二位的经纬度。 以任何单位表示的地球半径(我用r=3961表示英里) 当我将其作为向量输入时,它很容易工作:使用需要四个向量的函数在R中迭代,r,iteration,purrr,pmap,geosphere,R,Iteration,Purrr,Pmap,Geosphere,我试图使用geosphere包中的Distaversine函数来计算多个城市之间的距离。此代码需要多种参数: 第一位的经度和纬度。 第二位的经纬度。 以任何单位表示的地球半径(我用r=3961表示英里) 当我将其作为向量输入时,它很容易工作: HongKong <- c(114.17, 22.31) GrandCanyon <- c(-112.11, 36.11) library(geosphere) distHaversine(HongKong, GrandCanyon, r=3
HongKong <- c(114.17, 22.31)
GrandCanyon <- c(-112.11, 36.11)
library(geosphere)
distHaversine(HongKong, GrandCanyon, r=3961)
#[1] 7399.113 distance in miles
HongKongdistHaversine
一次只接受一对lat和lon值,因此我们需要将location1
和location2
行的所有组合逐一发送到函数。使用sapply的一种方法是
library(geosphere)
location1[paste0("dist_", stringr::word(location2$destination))] <-
t(sapply(seq_len(nrow(location1)), function(i)
sapply(seq_len(nrow(location2)), function(j) {
distHaversine(location1[i, c("lon", "lat")], location2[j, c("lon", "lat")], r=3961)
})))
location1$nearest <- location2$destination[apply(location1[5:8], 1, which.min)]
location1
# A tibble: 3 x 9
# person current_loc lon lat dist_Atlanta dist_Rome dist_Bangkok dist_Grand nearest
# <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
#1 Sally Bogota Colombia -74.1 4.71 2114. 5828. 11114. 3246. Atlanta United States
#2 Jane Paris France 2.35 48.9 4375. 687. 5871. 5329. Rome Italy
#3 Lisa Hong Kong China 114. 22.3 8380. 5768. 1075. 7399. Bangkok Thailand
库(geosphere)
位置1[paste0(“dist_u0;”,stringr::word(location2$destination))使用tidyverse
anmap
fuctionformpurr
正如您所问,我找到了一个解决方案,全部集中在一条管道中
library(tidyverse)
library(geosphere)
# renaming lon an lat variables in each df
location1 <- location1 %>%
rename(lon.act = lon, lat.act = lat)
location2 <- location2 %>%
rename(lon.dest = lon, lat.dest = lat)
# geting distances
merge(location1, location2, all = TRUE) %>%
group_by(person,current_loc, destination) %>%
nest() %>%
mutate( act = map(data, `[`, c("lon.act", "lat.act")) %>%
map(as.numeric),
dest = map(data, `[`, c("lon.dest", "lat.dest")) %>%
map(as.numeric),
dist = map2(act, dest, ~distHaversine(.x, .y, r = 3961))) %>%
unnest(data, dist) %>%
group_by(person) %>%
mutate(mindis = dist == min(dist))
库(tidyverse)
图书馆(地球圈)
#重命名每个df中的lon和lat变量
位置1%
重命名(lon.act=lon,lat.act=lat)
地点2%
重命名(lon.dest=lon,lat.dest=lat)
#到达距离
合并(位置1,位置2,全部=真)%>%
组员(人员、当前地点、目的地)%>%
嵌套()%>%
突变(act=map(数据,`[`,c(“lon.act”,“lat.act”))%>%
地图(如数字),
dest=map(数据,`[`,c(“lon.dest”,“lat.dest”))%>%
地图(如数字),
dist=map2(act,dest,~distHaversine(.x,.y,r=3961))%>%
unnest(数据,距离)%>%
分组单位(人)%>%
变异(mindis=dist==min(dist))
您能提供一个示例,说明如何组织输出吗?@MichaelScott,刚刚提供了更新谢谢!快速提问:当您调用location1[5:8]时的最后一行,有没有办法让R从名字而不是数字中提取信息?我使用的表格随每周识别的地点数量而变化。无论如何,谢谢!@J.Sabree是的,这取决于您在前面的sapply
步骤中给出的名称。因此,在本例中,我们使用前缀“dist”
所以我们可以做location2$destination[apply(location1[grep(^dist),names(location1))],1,which.min)]
我已经尝试将此代码应用于其他数据集,但对某些数据集有效,但对其他数据集无效。我尝试将其应用于其他数据集,但收到以下错误:hub\u locations\u list$hub\u loc[apply(dataset2[grep(^dist“,:无效的下标类型'list'(注意:我确认此数据集2是类数据帧)。是否有原因使其仅在某些情况下有效?@J.Sabree不确定,但您是否正确使用了语法?hub\u locations\u list$hub\u loc[apply(dataset2[grep(^dist),names(dataset2)),1,which.min)]
yes我检查了格式,它只对某些数据集给出了一个错误。例如,当类函数产生“spec\u tbl\u df”时,它在数据集上工作,但当它只是tbl_df、tbl和data.frame时,它就不工作了。你知道为什么会这样,或者如何将TIBLES类更改为spec_tbl_df吗?我尝试过取消列表,但它不工作。感谢发送此消息,但我得到一个错误:错误:在.data
中找不到列lon.act
,lat.act
。抱歉,现在可以了。在合并数据集之前,我只需更改每个df中lon
和lat
变量的名称。
library(geosphere)
location1[paste0("dist_", stringr::word(location2$destination))] <-
t(sapply(seq_len(nrow(location1)), function(i)
sapply(seq_len(nrow(location2)), function(j) {
distHaversine(location1[i, c("lon", "lat")], location2[j, c("lon", "lat")], r=3961)
})))
location1$nearest <- location2$destination[apply(location1[5:8], 1, which.min)]
location1
# A tibble: 3 x 9
# person current_loc lon lat dist_Atlanta dist_Rome dist_Bangkok dist_Grand nearest
# <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
#1 Sally Bogota Colombia -74.1 4.71 2114. 5828. 11114. 3246. Atlanta United States
#2 Jane Paris France 2.35 48.9 4375. 687. 5871. 5329. Rome Italy
#3 Lisa Hong Kong China 114. 22.3 8380. 5768. 1075. 7399. Bangkok Thailand
library(tidyverse)
library(geosphere)
# renaming lon an lat variables in each df
location1 <- location1 %>%
rename(lon.act = lon, lat.act = lat)
location2 <- location2 %>%
rename(lon.dest = lon, lat.dest = lat)
# geting distances
merge(location1, location2, all = TRUE) %>%
group_by(person,current_loc, destination) %>%
nest() %>%
mutate( act = map(data, `[`, c("lon.act", "lat.act")) %>%
map(as.numeric),
dest = map(data, `[`, c("lon.dest", "lat.dest")) %>%
map(as.numeric),
dist = map2(act, dest, ~distHaversine(.x, .y, r = 3961))) %>%
unnest(data, dist) %>%
group_by(person) %>%
mutate(mindis = dist == min(dist))