В R base / dplyr найдите строку, ближайшую к каждой строке набора данных - PullRequest
0 голосов
/ 03 мая 2018

У меня есть фрейм данных с N строками, и я хотел бы рассчитать для подмножества строк, какая из них ближе всего к каждой строке в наборе данных, принадлежащих к той же группе.

Так, например:

> df
# A tibble: 8,014 x 4
     A      B       C      Group
    <dbl>  <dbl>   <dbl>    <int>
 1  -0.396 -0.621 -0.759      1
 2  -0.451 -0.625 -0.924      1
 3  -0.589 -0.624 -1.26       1
 4  -0.506 -0.625 -1.09       1
 5  NA      1.59  -0.593      1
 6  -0.286  4.22  -0.0952     1
 7  NA      2.91  -0.0952     1
 8  NA      4.22  -0.924      1
 9  -0.175  1.52  -0.0952     1
10  NA      1.74   1.56       1
# ... with 8,004 more rows

Так, например, я хотел бы проверить, какие строки ближе всего к строке 2 и строке 3 принадлежат группе == 1. Кроме того, я должен сделать это эффективно, поэтому цикл for на самом деле не вариант.

Я бы хотел использовать функцию dist, потому что она имеет хорошую функцию правильной обработки NA, но мне не нужно вычислять всю матрицу расстояний - это было бы пустой тратой.

Я попробовал это, но это не удалось, и это также расточительно:

res = Map(function(x,y) dist(as.matrix(rbind(x, y))), df[2:3, ] 
%>% group_by(Group), df %>% group_by(Group))

1 Ответ

0 голосов
/ 03 мая 2018

Один из способов сделать это, но он создает полную матрицу расстояний для каждой группы. Не уверен, почему это расточительно, учитывая то, что вы пытаетесь сделать:

library(tidyverse)
library(purrr)

min_dist <- function(x){

  dist(x, upper = T) %>% 
    as.matrix %>% 
    as.tibble %>% 
    na_if(0) %>%  #as.tibble adds zeros along the diagonal, so this removes them
    summarize_all(funs(which(. == min(.,na.rm=TRUE)))) %>% 
    gather %>% 
    pull(value)
}


df %>% group_by(Group) %>%
  mutate(group_row = row_number()) %>%
  nest(-Group) %>% 
  mutate(nearest_row = map(data, min_dist)) %>% 
  unnest
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...