我有一个包含 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
因此,例如,我想检查哪些是属于组 ==1 的第 2 行和第 3 行最接近的行。此外,我必须有效地做到这一点,因此for
循环实际上不是一种选择。
我想使用dist
函数,因为它具有正确处理 NA 的好功能,但我不需要计算整个距离矩阵 - 这将是一种浪费。
我试过这个,但它失败了,而且也很浪费:
res = Map(function(x,y) dist(as.matrix(rbind(x, y))), df[2:3, ]
%>% group_by(Group), df %>% group_by(Group))
一种方法可以做到这一点,但它确实为每个组创建了整个距离矩阵。 不知道为什么这是浪费,考虑到你想做什么:
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