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