これを考えると 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
これは可能だと思う do
に dplyr
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つ以上のキーを使用した例でテストしていません。