计算组内项目之间的平均欧几里得距离

时间:2018-07-14 00:40:13

标签: r dplyr tidyverse

我想计算数据框中一组中每个项目与所有其他项目之间的平均欧几里得距离。我想在tidyverse中进行此操作,但似乎无法使其按我的意愿工作。

示例数据:

library(tidyverse)

DF <- data.frame(Item = letters[1:20], Grp = rep(1:4, each = 5), 
                  x = runif(20, -0.5, 0.5), 
                  y = runif(20, -0.5, 0.5))

我认为欧几里德距离的计算方法是:

sqrt(((x[i] - x[i + 1]) ^ 2) + ((y[i] - y[i + 1]) ^ 2))

我尝试用mutate做某事,但未成功。

DF %>%
  group_by(Grp, Item) %>%
  mutate(Dist = mean(sqrt(((x - lag(x, default = x[1])) ^ 2) + 
                           (y - lag(y, default = y[1])) ^ 2)))

但是,它不起作用,仅返回NA。

# A tibble: 20 x 5
# Groups:   Grp, Item [20]
   Item    Grp       x       y  Dist
   <fct> <int>   <dbl>   <dbl> <dbl>
 1 a         1 -0.212   0.390     NA
 2 b         1  0.288   0.193     NA
 3 c         1 -0.0910  0.141     NA
 4 d         1  0.383   0.494     NA
 5 e         1  0.440   0.156     NA
 6 f         2 -0.454   0.209     NA
 7 g         2  0.0281  0.0441    NA
 8 h         2  0.392   0.0941    NA
 9 i         2  0.0514 -0.211     NA
10 j         2 -0.0434 -0.353     NA
11 k         3  0.457   0.463     NA
12 l         3 -0.0467  0.402     NA
13 m         3  0.178   0.191     NA
14 n         3  0.0726  0.295     NA
15 o         3 -0.397  -0.475     NA
16 p         4  0.400  -0.0222    NA
17 q         4 -0.254   0.258     NA
18 r         4 -0.458  -0.284     NA
19 s         4 -0.172  -0.182     NA
20 t         4  0.455  -0.268     NA

如果我正确理解lag,它将仍然是顺序的(如果可行),而不是计算组中所有对之间的距离。

如何获取一组中每个项目的所有4个距离的平均值?

有人有什么建议吗?

1 个答案:

答案 0 :(得分:1)

DF %>% group_by(Grp) %>%
    mutate(Dist = colMeans(as.matrix(dist(cbind(x, y)))))
# # A tibble: 20 x 5
# # Groups:   Grp [4]
#      Item   Grp            x            y      Dist
#    <fctr> <int>        <dbl>        <dbl>     <dbl>
#  1      a     1 -0.197904299  0.363086055 0.4659160
#  2      b     1  0.090540444 -0.006314185 0.2031230
#  3      c     1  0.101018893 -0.025062949 0.2011672
#  4      d     1  0.006358616 -0.149784267 0.2323359
#  5      e     1  0.219596250 -0.341440596 0.3605274
#  6      f     2 -0.493124602 -0.002935820 0.5155365
# ...

要查看其工作原理,请从一个数据子集开始,然后逐步进行:

# run these one line at a time and have a look at ?dist
dd = DF[DF$Grp == "1", c("x", "y")]
dist(dd)
as.matrix(dist(dd))
colMeans(as.matrix(dist(dd)))