Вычисление попарных евклидовых расстояний для наблюдений из разных групп в R?

#r

#r

Вопрос:

У меня есть фрейм данных с наблюдениями с тремя переменными (от V1 до V3), разделенными на 3 группы:

   V1   V2   V3 group
0.59 0.78 0.91     1
0.72 0.91 0.73     2
1.31 1.21 0.90     3
4.32 1.53 3.20     2
....
  

Я хотел бы рассчитать евклидовы расстояния между наблюдениями. Легко вычислить попарные расстояния между всеми наблюдениями:

 df %>% 
    select(-group) %>% 
    dist()
  

Но меня также интересует вычисление попарных расстояний (а) только между наблюдениями в одной и той же группе (б) между наблюдениями, не принадлежащими к одной и той же группе (например, между каждым наблюдением в группе 1 и всеми наблюдениями в группах 2 и 3).

Для (a) я могу сделать:

 for (x in unique(df$group){
    df %>%
    filter(group == x) %>%
    select(-group) %>% 
    dist()
}
  

И добавьте результаты вместе; но я не уверен, как выполнить (b). Как это лучше всего сделать?

Спасибо!

Комментарии:

1. Под (b) вы имеете в виду, что вам нужны ВСЕ попарные расстояния, кроме тех, которые находятся внутри групп?

2. @Oka Да, точно. Это предназначено для того, чтобы дать некоторое представление о том, насколько далеко друг от друга находятся наблюдения в разных группах.

Ответ №1:

Вот подход, разделяющий вычисление расстояний и извлечение по заданным условиям.

 ##  distance as a matrix
d_m <- df %>% 
  select(-group) %>% 
  dist() %>% 
  as.matrix()

##  combination of groups
cb_g <- combn(df$group, m= 2)
##  combination of indices
cb_i <- combn(1:length(df$group), m= 2) 

##  extract the values that fit to given conditions
corr_same_grp <- apply(cb_g, 2, function(x) x[1] == x[2]) %>%  # same groups
  { cb_i[, ., drop= F] } %>%           # get indices
  apply(2, function(x) d_m[x[2], x[1]])

corr_diff_grp <- apply(cb_g, 2, function(x) x[1] != x[2]) %>%  # different groups 
  { cb_i[, ., drop= F] } %>%           # get indices
  apply(2, function(x) d_m[x[2], x[1]])
  

Ответ №2:

Как насчет применения функции, аналогичной в вашем примере, к матрице комбинаций переменных:

 library(dplyr)

## define the data frame
df = as.data.frame(cbind(c(.59, .72, 1.31, 4.32),
           c(.78, .91, 1.21, 1.52),
           c(.91, .73, .9, 3.2),
           c(1,2,3,2)), stringsAsFactors = FALSE)

names(df) = c("V1", "V2", "V3", "group")

## generate a matrix with the unique combinations of groups
combinations = combn(x = unique(df$group), m = 2)

## apply a function over the matrix of group combinations to determine
## the distance between the variable observations
distlist = lapply(seq(from = 1, to = ncol(combinations)), function(i){

  tmpdist = df %>% filter(group %in% combinations[,i]) %>%
    select(-group) %>%
    dist()

  return(cbind(combinations[1,i], combinations[2,i], tmpdist))

})

## combine the list into a dataframe 
dists = do.call(rbind, distlist)

names(dists) = c("group1", "group2", "dist")