Dplyr: доступ к текущей переменной группы

После использования data.table в течение некоторого времени я теперь подумал, что пришло время попробовать dplyr. Это весело, но я не мог понять, как получить доступ - текущая переменная группировки - возврат нескольких значений для каждой группы

Следующий пример показывает, что отлично работает с data.table. Как вы напишете это с помощью dplyr

foo <- matrix(c(1, 2, 3, 4), ncol = 2)
dt <- data.table(a = c(1, 1, 2), b = c(4, 5, 6))

# data.table (expected)
dt[, .(c = foo[, a]), by = a]
   a c
1: 1 1
2: 1 2
3: 2 3
4: 2 4

# dplyr (?)
dt %>% 
  group_by(a) %>% 
  summarize(c = foo[a])

Ответ 1

Мы можем использовать do из dplyr. (Другие пакеты не используются). do очень удобен для расширения строк. Нам нужно только обернуть data.frame.

dt %>% 
     group_by(a) %>%
     do(data.frame(c = foo[, unique(.$a)]))
#      a     c
#  <dbl> <dbl>
#1     1     1
#2     1     2
#3     2     3
#4     2     4

Или вместо unique мы можем подмножество 1-м наблюдением

dt %>% 
    group_by(a) %>%
    do(data.frame(c = foo[, .$a[1]]))
#     a     c
#  <dbl> <dbl>
#1     1     1
#2     1     2
#3     2     3
#4     2     4

Это можно сделать и без использования каких-либо пакетов

stack(lapply(split(dt$a, dt$a), function(x) foo[,unique(x)]))[2:1]
#   ind values
#1   1      1
#2   1      2
#3   2      3
#4   2      4

Ответ 2

Вы все равно можете получить доступ к групповой переменной, но она похожа на обычный вектор с одним уникальным значением для каждой группы, поэтому, если вы разместите вокруг него unique, он будет работать. И в то же время dplyr, похоже, не будет автоматически расширять строки, такие как data.table, вам понадобится пакет unnest from tidyr:

library(dplyr); library(tidyr)
dt %>% 
      group_by(a) %>% 
      summarize(c = list(foo[,unique(a)])) %>% 
      unnest()

# Source: local data frame [4 x 2]

#       a     c
#   <dbl> <dbl>
# 1     1     1
# 2     1     2
# 3     2     3
# 4     2     4

Или мы можем использовать first для ускорения, так как мы уже знаем, что групповой переменный вектор одинаковый для каждой группы:

dt %>% 
      group_by(a) %>% 
      summarize(c = list(foo[,first(a)])) %>% 
      unnest()

# Source: local data frame [4 x 2]

#       a     c
#   <dbl> <dbl>
# 1     1     1
# 2     1     2
# 3     2     3
# 4     2     4