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

У меня есть кадр данных с наблюдениями с тремя переменными (от 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).

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

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

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

Спасибо!

Ответы [ 2 ]

0 голосов
/ 15 апреля 2019

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

##  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]])
0 голосов
/ 15 апреля 2019

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

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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...