简体   繁体   English

将列表列添加到 rowwise() dataframe

[英]add list column to rowwise() dataframe

I'm trying to understand the behaviour of dplyr::rowwise() 'd dataframes.我试图了解dplyr::rowwise()的数据帧的行为。 Specifically whether I can apply dplyr::mutate() to them to create list columns that contain multiple objects.具体来说,我是否可以将dplyr::mutate()应用于它们以创建包含多个对象的列表列。

In the example below I'm attempting to add a column to mtcars where each element/row is a list of length two, containing two lm models.在下面的示例中,我尝试向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.

Created on 2021-06-06 by the reprex package (v1.0.0)代表 package (v1.0.0) 于 2021 年 6 月 6 日创建

I can't quite make sense of the error message.我无法完全理解错误消息。 Could anyone please help to clarify what's going on here?任何人都可以帮助澄清这里发生了什么吗?

Here are some related calls that do work, that led me to expect that the call above would also work.以下是一些有效的相关调用,这使期望上面的调用也可以正常工作。

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

Created on 2021-06-06 by the reprex package (v1.0.0)代表 package (v1.0.0) 于 2021 年 6 月 6 日创建

ps I understand that this can be achieved with other methods. ps 我知道这可以通过其他方法来实现。 This is mostly a learning opportunity:)这主要是一个学习机会:)

You can store a list of length 1 in a dataframe.您可以将长度为 1 的列表存储在 dataframe 中。

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

df$b <- tmp

But you cannot store a list of length more than 1.但是您不能存储长度超过 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

Error in $<-.data.frame ( *tmp* , b, value = list(mymod1 = list(coefficients = c( (Intercept) = 37.285126167342, : replacement has 2 rows, data has 1 $<-.data.frame ( *tmp* , b, value = list(mymod1 = list(coefficients = c( (Intercept) = 37.285126167342, : 替换有 2 行,数据有 1

For that again you need to make a list of length 1 which can be done as -为此,您需要制作一个长度为 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

So for your example this will work -因此,对于您的示例,这将起作用-

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

which is also what the error message suggests to do.这也是错误消息建议做的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM