【问题标题】:add list column to rowwise() dataframe将列表列添加到 rowwise() 数据框
【发布时间】:2021-06-06 14:24:48
【问题描述】:

我正在尝试了解 dplyr::rowwise()'d 数据帧的行为。具体来说,我是否可以将dplyr::mutate() 应用于它们以创建包含多个对象的列表列。

在下面的示例中,我尝试向 mtcars 添加一列,其中每个元素/行都是长度为 2 的列表,包含两个 lm 模型。

suppressPackageStartupMessages(library(dplyr))

## attempt to output two objects into a list
## -----> this does not work <-----
## why not?
mtcars %>%
  nest_by(cyl) %>%
  mutate(mods = list(
    mymod1 = list(lm(mpg ~ wt, data = data)),
    mymod2 = list(lm(disp ~ wt, data = data))
  ))
#> Error: Problem with `mutate()` input `mods`.
#> x Input `mods` can't be recycled to size 1.
#> ℹ Input `mods` is `list(...)`.
#> ℹ Input `mods` must be size 1, not 2.
#> ℹ Did you mean: `mods = list(list(...))` ?
#> ℹ The error occurred in row 1.

由reprex package (v1.0.0) 于 2021-06-06 创建

我无法完全理解错误消息。谁能帮忙澄清一下这里发生了什么?

这里有一些相关的调用确实可以工作,这让我期望上面的调用也可以工作。

suppressPackageStartupMessages(library(dplyr))

## output one object
## this works
mtcars %>%
  nest_by(cyl) %>%
  mutate(mod = list(lm(mpg ~ wt, data = data)))
#> # A tibble: 3 x 3
#> # Rowwise:  cyl
#>     cyl                data mod   
#>   <dbl> <list<tbl_df[,10]>> <list>
#> 1     4           [11 × 10] <lm>  
#> 2     6            [7 × 10] <lm>  
#> 3     8           [14 × 10] <lm>

## output one object into a list
## this also works
mtcars %>%
  nest_by(cyl) %>%
  mutate(mod = list(
    mymod = list(lm(mpg ~ wt, data = data))
  ))
#> # A tibble: 3 x 3
#> # Rowwise:  cyl
#>     cyl                data mod         
#>   <dbl> <list<tbl_df[,10]>> <named list>
#> 1     4           [11 × 10] <list [1]>  
#> 2     6            [7 × 10] <list [1]>  
#> 3     8           [14 × 10] <list [1]>

由reprex package (v1.0.0) 于 2021-06-06 创建

附言我知道这可以通过其他方法来实现。这主要是一个学习机会:)

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    您可以在数据框中存储长度为 1 的列表。

    df <- data.frame(a = 1)
    tmp <- list(mymod1 = lm(mpg ~ wt, data = mtcars))
    length(tmp)
    #[1] 1
    
    df$b <- tmp
    

    但您不能存储长度超过 1 的列表。

    df <- data.frame(a = 1)
    tmp <- list(mymod1 = lm(mpg ~ wt, data = mtcars), 
                mymod2 = lm(mpg ~ wt, data = mtcars))
    length(tmp)
    #[1] 2
    
    df$b <- tmp
    

    $&lt;-.data.frame(*tmp*, b, value = list(mymod1 = list(coefficients = c((Intercept) = 37.285126167342, : 替换有 2 行,数据有 1

    为此,您需要再次制作一个长度为 1 的列表,可以这样做 -

    df <- data.frame(a = 1)
    tmp <- list(list(mymod1 = lm(mpg ~ wt, data = mtcars), 
                     mymod2 = lm(mpg ~ wt, data = mtcars)))
    length(tmp)
    #[1] 1
    df$b <- tmp
    

    因此,对于您的示例,这将起作用 -

    library(dplyr)
    
    mtcars %>%
      nest_by(cyl) %>%
      rowwise() %>%
      mutate(mods = list(list(mymod1 = list(lm(mpg ~ wt, data = data)),
                              mymod2 = list(lm(disp ~ wt, data = data))))) 
    
    #    cyl                data mods            
    #  <dbl> <list<tibble[,10]>> <list>          
    #1     4           [11 × 10] <named list [2]>
    #2     6            [7 × 10] <named list [2]>
    #3     8           [14 × 10] <named list [2]>
    

    这也是错误消息建议的操作。

    【讨论】:

    • 感谢@Ronak Shah 提供了如此清晰的答案。现在看起来很明显!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    • 2022-01-03
    • 2022-01-05
    • 1970-01-01
    • 2020-05-22
    • 2017-11-27
    相关资源
    最近更新 更多