【问题标题】:Is there a dplyr or data.table equivalent to plyr::join_all? Joining by a list of data frames?是否有等效于 plyr::join_all 的 dplyr 或 data.table?通过数据框列表加入?
【发布时间】:2016-02-27 00:10:15
【问题描述】:

鉴于此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 来完成,但我想知道dplyrdata.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

【问题讨论】:

  • dplyr 格式为:df %&gt;% group_by(x) %&gt;% summarise(count_x = n(), sum_y = sum(y), mean_y = mean(y))。一步完成所有列。
  • @jeremycg 当然可以,但想象一下更复杂的函数,我无法将所有内容都传递到一个语句中。
  • @JasonAizkalns 你能演示一下这不起作用吗?
  • @TylerRinker @jeremycg 实际上,只需查看 jeremy 的 blog post 示例(哈!我知道我无耻地从某个地方偷走了这个概念/想法……那会教您可以在深夜阅读 Kaggle 帖子...)。我将不得不稍微修改一下我的示例,但他的博客文章指出了调用summarise 不起作用的情况(或者至少是更难以维护的情况)。

标签: r data.table dplyr plyr


【解决方案1】:

将@SimonOHanlon 的data.table 方法与@Jaap 的Reducemerge 技术相结合似乎可以产生最高效的结果:

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)))

更新以包含tidyverse / purrr (purrr::reduce) 方法:

library(tidyverse)
list(count_x(df), sum_y(df), mean_y(df)) %>% 
  reduce(left_join) 

【讨论】:

    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2021-03-02
      • 2023-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多