使用 gdist() 为分组子集计算点之间的距离

Calculate distance between points using gdist() for grouped subsets

可以找到我的 2 个人 (squirrelID) 数据的子集 here

我的数据如下(仅显示相关列):

lat                  lon                NatalMidden   squirrelID    type
60.9577819984406    -138.0347849708050  -27           NA            Nest2017
60.9574120212346    -138.0345689691600  -27           NA            NatalMidden
60.9578209742904    -138.0346520338210  -27           23054         Foray
60.9575380012393    -138.0348329991100  -27           23054         Foray
60.9576250053942    -138.0339069664480  -27           23054         Foray
60.957643026486     -138.0338829942050  -27           23054         Foray
60.9575670026243    -138.0348739866170  -27           23054         Foray

例如,对于 squirrelID 23054,它被定位 (Foray) 多次(type 列)并且我有相应的纬度 (lat) 和每个 Foray 的经度 (lon)。我正在尝试分别计算每个人(squirrelID)的每个 Foraytype 列)和 Nest2017type 列)之间的距离。

下面的代码有效(并为我提供了 15.11501 米的值),但它需要我手动输入每个点。据说这不是问题,但我正在处理 +2000 个观察结果,每个 gridNatalMiddensquirrelID 列有 2 个以上的选项。

library(Imap)

gdist(60.9578209742904,-138.0346520338210, 60.9577819984406, -138.0347849708050, units="m", verbose=FALSE)

有什么方法可以让我在 dplyr 框架内工作到 group_by(squirrelID) 然后计算每个Foray与其对应的Nest2017之间的距离(有相同的 NatalMidden 对于 Foray Nest2017)?

我的最终目标是为每个 squirrelID.

ForayNest2017 之间的距离创建一个新列

更新:

我试过以下方法:

nests<-df %>% #creating a new data frame for Nest2017 points only
    filter(type %in% "Nest2017") %>%
    select(ID,lat,lon,ele,grid,NatalMidden,type)

foray<-df %>% #creating a new data frame for Foray points only
    filter(type %in% "Foray") %>%
    mutate(sq_id=as.factor(sq_id)) %>%
    group_by(sq_id)

但是这些子集在 gdist 函数中不起作用(我得到这个错误):

gdist(nests$lat, nests$lon, foray$lat, foray$lon, units="m", verbose=FALSE)

Error in while (abs(lamda - lamda.old) > 1e-11) { : 
  missing value where TRUE/FALSE needed
In addition: Warning messages:
1: In Ops.factor(lon.1, rad) : ‘*’ not meaningful for factors
2: In Ops.factor(lat.1, rad) : ‘*’ not meaningful for factors
3: In Ops.factor(lon.2, rad) : ‘*’ not meaningful for factors
4: In Ops.factor(lat.2, rad) : ‘*’ not meaningful for factors
5: In lon.1 - lon.2 :
  longer object length is not a multiple of shorter object length
6: In while (abs(lamda - lamda.old) > 1e-11) { :
  the condition has length > 1 and only the first element will be used

我对 dplyr 包不是很熟悉,但我认为这会满足您的兴趣:

# read data from the FigShare linked file
squirrel_data <- read.table("figshare.txt", header=T)

# split into 'Forays' and 'Nests'
nests <- squirrel_data %>%
  filter(type %in% "Nest2017")
foray <- squirrel_data %>%
  filter(type %in% "Foray")

# merge 'Forays' and 'Nests' by 'NatalMidden'
nests_foray <- inner_join(
  nests, foray, by = "NatalMidden", suffix = c(".nest", ".foray"))

# calculate the distance for each row, keep 'SquirrelID' and 'Dist'
results <- nests_foray %>%
  rowwise() %>%
  mutate(dist = gdist(lat.nest, lon.nest,
                      lat.foray, lon.foray, units = "m")) %>%
  select(squirrelID.foray, dist)
head(results, n = 3)
## A tibble: 3 x 2
#  squirrelID.foray     dist
#             <int>    <dbl>
#1            22684 14.03843
#2            22684 59.06996
#3            22684 13.40567

这基本上是我在第一条评论中提出的,但使用 dplyr 函数而不是 base。这个想法只是通过 "NatalMidded" 在 "Foray" 行和 "Nest2017" 行之间创建内部连接,然后简单地计算每行的距离并用 "SquirrelID" 报告它。希望对您有所帮助。