Агрегирование значений НЕ в группе, с dplyr - PullRequest
0 голосов
/ 27 ноября 2018

Рассмотрим фрейм данных, который захватывает значения, связанные с данной парой Кластер / Функция:

library(tidyverse)

set.seed(100)
X <- data_frame(Cluster = rep(1L:3L,2),
                Feature = rep(c("A","B"), each=3),
                Values  = map(rep(11:13,2), rnorm) )
# # A tibble: 6 x 4
#    Cluster Feature Values
#      <int> <chr>   <list>
#  1       1 A       <dbl [11]>
#  2       2 A       <dbl [12]>
#  3       3 A       <dbl [13]>
#  4       1 B       <dbl [11]>
#  5       2 B       <dbl [12]>
#  6       3 B       <dbl [13]>

Меня интересует создание нового столбца, который для любой данной пары Кластер / Функция объединяет все значенияэтой функции, которые находятся в других кластеров.Например, первая запись в таком столбце Not In Cluster (NIC) должна содержать 25 значений, связанных с компонентом A в кластерах 2 и 3.

Следующий цикл над строками даст правильный ответ:

X$NIC <- map( 1:nrow(X), ~c() )
for(i in 1:nrow(X) ) {
  cl <- X$Cluster[i]
  f  <- X$Feature[i]
  X$NIC[[i]] <- filter( X, Cluster != cl, Feature == f ) %>%
                  pull(Values) %>% unlist
}
# # A tibble: 6 x 4
#   Cluster Feature Values     NIC
#     <int> <chr>   <list>     <list>
# 1       1 A       <dbl [11]> <dbl [25]>
# 2       2 A       <dbl [12]> <dbl [24]>
# 3       3 A       <dbl [13]> <dbl [23]>
# 4       1 B       <dbl [11]> <dbl [25]>
# 5       2 B       <dbl [12]> <dbl [24]>
# 6       3 B       <dbl [13]> <dbl [23]>

## Spot-checking
with( X, identical(NIC[[1]], unlist(Values[2:3])) )      # TRUE
with( X, identical(NIC[[5]], unlist(Values[c(4,6)])) )   # TRUE

Мне было интересно, есть ли более чистый способ сделать это с помощью инструментов dplyr.Я чувствую, что это идеальная установка для решения group_by, но, похоже, что для его работы необходимо «перекрестное общение» между группами.

1 Ответ

0 голосов
/ 27 ноября 2018

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

library(dplyr)
library(purrr)

mutate(group_by(X, Feature),
       NIC = map(1:n(), ~ flatten_dbl(Values[-.])))
# # A tibble: 6 x 4
# # Groups:   Feature [2]
#   Cluster Feature Values     NIC       
#     <int> <chr>   <list>     <list>    
# 1       1 A       <dbl [11]> <dbl [25]>
# 2       2 A       <dbl [12]> <dbl [24]>
# 3       3 A       <dbl [13]> <dbl [23]>
# 4       1 B       <dbl [11]> <dbl [25]>
# 5       2 B       <dbl [12]> <dbl [24]>
# 6       3 B       <dbl [13]> <dbl [23]>
...