/ / plyr :: join_allと同等のdplyrまたはdata.tableはありますか?データフレームのリストで参加しますか? -r、data.table、dplyr、plyr

plyr :: join_allに相当するdplyrまたはdata.tableはありますか?データフレームのリストに参加する? - r、data.table、dplyr、plyr

これを考えると data.frame

set.seed(4)
df <- data.frame(x = rep(1:5, each = 2), y = sample(50:100, 10, T))
#    x  y
# 1  1 78
# 2  1 53
# 3  2 93
# 4  2 96
# 5  3 61
# 6  3 82
# 7  4 53
# 8  4 76
# 9  5 91
# 10 5 99

の機能を作成するためのいくつかの簡単な機能(機能エンジニアリング)を書きたい x そして、結果のそれぞれに参加します data.frames 一緒に。例えば:

library(dplyr)
count_x <- function(df) df %>% group_by(x) %>% summarise(count_x = n())
sum_y   <- function(df) df %>% group_by(x) %>% summarise(sum_y = sum(y))
mean_y  <- function(df) df %>% group_by(x) %>% summarise(mean_y = mean(y))
# and many more...

これは、 plyr::join_all しかし、私はより良い(またはよりパフォーマンスの高い)メソッドがあるかどうか疑問に思っています dplyr または data.table

df_with_features <- plyr::join_all(list(count_x(df), sum_y(df), mean_y(df)),
by = "x", type = "full")

# > df_with_features
#   x count_x sum_y mean_y
# 1 1       2   131   65.5
# 2 2       2   189   94.5
# 3 3       2   143   71.5
# 4 4       2   129   64.5
# 5 5       2   190   95.0

回答:

回答№1の場合は3

@SimonOHanlonの組み合わせ data.table @Jaapを使用したメソッド Reduce そして merge 手法は、最もパフォーマンスの高い結果をもたらすようです。

library(data.table)
setDT(df)
count_x_dt <- function(dt) dt[, list(count_x = .N), keyby = x]
sum_y_dt   <- function(dt) dt[, list(sum_y = sum(y)), keyby = x]
mean_y_dt  <- function(dt) dt[, list(mean_y = mean(y)), keyby = x]

Reduce(function(...) merge(..., all = TRUE, by = c("x")),
list(count_x_dt(df), sum_y_dt(df), mean_y_dt(df)))

回答№2については2

data.table これは、ソートされたキー付きdata.tableを持ち、キーを使用してさまざまなdata.tablesを結合することと同等です。

例えば

require(data.table)
setDT(df)  #df is now a data.table
df_count <- df[ , list(count_x=.N),by=x]
df_sum <- df[ , list(sum_y = sum(y)),by=x]
#  merge.data.table executes a fast join on the shared key
merge(df_count,df_sum)
#   x count_x sum_y
#1: 1       2   129
#2: 2       2   128
#3: 3       2   154
#4: 4       2   182
#5: 5       2   151

あなたの例では、このようなものを書くかもしれません:

count_x <- function(dt) dt[ , list(N = .N) , keyby=x ]
sum_y <- function(dt) dt[ , list(Sum=sum(y)),keyby=x]

#  Then merge...
merge(sum_y(df),count_x(df))
#   x Sum N
#1: 1 129 2
#2: 2 128 2
#3: 3 154 2
#4: 4 182 2
#5: 5 151 2

回答№3の場合は0

これは可能だと思う dodplyr data.framesをスタックします。

library(dplyr)
mean_y_marg <- function(df) df %>% group_by(x) %>% summarise(mean_y_marginal = mean(y))
mean_y  <- function(df) df %>% group_by(x, z) %>% summarise(mean_y = mean(y))

set.seed(4)
df <- data.frame(x = rep(1:2, each = 6), z= rep(1:6, each = 2), y = sample(50:100, 12, T))

df_with_features <- plyr::join_all(list(mean_y_marg(df), mean_y(df)),
by = "x", type = "full")

# x mean_y_marginal z mean_y
# 1 1        71.66667 1   58.5
# 2 1        71.66667 2   91.0
# 3 1        71.66667 3   65.5
# 4 2        76.83333 4   94.5
# 5 2        76.83333 5   71.5
# 6 2        76.83333 6   64.5

df_with_features2 = df %>% group_by(x) %>%
do(data.frame(mean_y_marg(.), data.frame(mean_y(.))))

# x mean_y_marginal   x.1     z mean_y
# (int)           (dbl) (int) (int)  (dbl)
# 1     1        71.66667     1     1   58.5
# 2     1        71.66667     1     2   91.0
# 3     1        71.66667     1     3   65.5
# 4     2        76.83333     2     4   94.5
# 5     2        76.83333     2     5   71.5
# 6     2        76.83333     2     6   64.5

注意点は、1)キーを繰り返すことです(これは、 select); 2)繰り返されるキーが間違っている可能性があります:この例を削除してみてください group_by(x);および3)3つ以上のキーを使用した例でテストしていません。