bind_cols当一个data_frame包含列表列

时间:2018-03-16 14:40:45

标签: r dplyr

背景

我有一个函数,它接受data.frame,估计模型,并应返回模型强化的原始数据。

到目前为止我有什么

如果输入数据已经分组,我依靠left_join使用分组变量作为要加入的列。但是,如果 no 分组,则left_join将无效,因为没有要加入的列。我想避免创建一个虚拟变量,因为这意味着我必须决定一个列名,它可能已经存在于数据中。因此,我认为我可以依靠bind_cols。但是,由于第二个list中有tibble列,bind_cols将无效。

问题

  1. 整个if(is.grouped_df(.))方法感觉有点hackish。是 有“更好”的方法来实现同样的目标吗?
  2. 我怎样才能bind_cols 第二个data_frame / tibble包含list列?
  3. 代码

    library(dplyr)
    g <- function(mdat) {
        ## am/mpg hard coded in this toy example
        addDat <- mdat %>%
           do(mod = lm(mpg ~ am, .), data = (.))
        if (is.grouped_df(mdat)) {
           left_join(mdat, addDat, by = group_vars(mdat))
        } else {
           bind_cols(mdat, addDat)
        }
    }
    
    g(mtcars) ## does not work
    # Error in cbind_all(x) : Argument 2 must be length 1, not 32
    
    g(mtcars %>% group_by(vs)) ## works as expected
    

1 个答案:

答案 0 :(得分:1)

为了使功能正常工作,我们可以在“addDat”中复制行。

g <- function(mdat) {
    ## am/mpg hard coded in this toy example
    addDat <- mdat %>%
       do(mod = lm(mpg ~ am, .), data = (.))
    if (is.grouped_df(mdat)) {
       left_join(mdat, addDat, by = group_vars(mdat))
    } else {
       bind_cols(as_tibble(mdat), addDat[rep(1, nrow(mdat)),])
    }
}

g(mtcars)

注意:但是,将整个数据集存储为每行的list效率不高