Skip to content

grouped_df throws errors in add_column #303

Closed

Description

@t-kalinowski
library(dplyr, warn.conflicts = FALSE)
library(tibble)

df <- tibble(x = 1:3, y = 1:3)

df %>% add_column(z = 4:6, .before = "y")
#> # A tibble: 3 x 3
#>       x     z     y
#>   <int> <int> <int>
#> 1     1     4     1
#> 2     2     5     2
#> 3     3     6     3
df %>% group_by(x) %>% add_column(z = 4:6, .before = "y")
#> Error: is.data.frame(df) is not TRUE

digging into this a little it seems to be caused by cbind() returning a matrix when called on a grouped_df

cbind(group_by(df, x), tibble(z = 1:3))
#>   [,1]      [,2]     
#> x Integer,3 Integer,3
#> y Integer,3 Integer,3
cbind(df, tibble(z = 1:3))
#>   x y z
#> 1 1 1 1
#> 2 2 2 2
#> 3 3 3 3

Activity

  1. krlmlr commented on Sep 6, 2017

    @krlmlr
    Member

    Does bind_cols() work?

  2. t-kalinowski commented on Sep 6, 2017

    @t-kalinowski
    Author

    Yes (with dev version of dplyr and tibble)

  3. krlmlr commented on Sep 12, 2017

    @krlmlr
    Member

    Is the behavior any different with the CRAN version?

  4. t-kalinowski commented on Sep 12, 2017

    @t-kalinowski
    Author
  5. krlmlr commented on Sep 12, 2017

    @krlmlr
    Member

    Closing, we don't currently support cbind().

  6. t-kalinowski commented on Sep 12, 2017

    @t-kalinowski
    Author

    The issue is aboutadd_column, not cbind.

  7. t-kalinowski commented on Sep 12, 2017

    @t-kalinowski
    Author

    The problem is caused by the call of cbind here:

    tibble/R/add.R

    Line 141 in 6320d77

    out <- cbind(df, .data)

  8. reopened this on Sep 13, 2017
  9. krlmlr commented on Sep 13, 2017

    @krlmlr
    Member

    Bummer. This seems to mean that we need to make add_column() generic, with an implementation in dplyr.

  10. t-kalinowski commented on Sep 13, 2017

    @t-kalinowski
    Author

    Hmm, seems not ideal.
    Would an approach based on [[<-to add the columns and then [ to reorder the columns be simpler?

  11. DavisVaughan commented on Sep 15, 2017

    @DavisVaughan
    Member

    @krlmlr I was just about to post an issue asking for add_column() to be generic.

    For packages that extend tibble, like my new tibbletime package, I have to handle the dropping of extra classes and attributes that occurs with most tidyverse functions. Normally I create a tidyverse_fun.tbl_time generic version that drops the classes and attributes that I dont want to lose, calls the function and then adds them back.

    Since add_column isn't generic, I can't do that there, and that call to cbind() removes the classes and attributes that I need to keep. At the end of add_column(), the classes are added back, but the attributes are not, which causes a lot of problems!

    So for my problem, either add_column would need to be generic or it should also try and add the attributes of the original .data back on. Any help there is definitely welcome!

  12. t-kalinowski commented on Sep 15, 2017

    @t-kalinowski
    Author

    Most classes that build on top of tbl_df I think already need to define a [ method.... my preference would be to try to minimize the total number of methods that need to be defined in order to extend and build ontop of tbl_df. I think building add_column with [ is one such opportunity.

  13. DavisVaughan commented on Sep 16, 2017

    @DavisVaughan
    Member

    Solution

    I think I have something that fixes everyone's problems using [.

    https://github.com/DavisVaughan/tibble/blob/master/R/add.R#L141

    Passes all tests for test-add.R.

    Fixes t-kalinowski's problem

    Details
    library(dplyr, warn.conflicts = FALSE)
    library(tibble)
    
    df <- tibble(x = 1:3, y = 1:3)
    
    df %>% add_column(z = 4:6, .before = "y")
    #> # A tibble: 3 x 3
    #>       x     z     y
    #>   <int> <int> <int>
    #> 1     1     4     1
    #> 2     2     5     2
    #> 3     3     6     3
    
    df %>% group_by(x) %>% add_column(z = 4:6, .before = "y")
    #> # A tibble: 3 x 3
    #> # Groups: x [3]
    #>       x     z     y
    #>   <int> <int> <int>
    #> 1     1     4     1
    #> 2     2     5     2
    #> 3     3     6     3

    Fixes my own problem

    Classes and attrs are no longer lost.
    Classes of the original .data are kept.

    Details
    library(tibbletime)
    #> 
    #> Attaching package: 'tibbletime'
    #> The following object is masked from 'package:stats':
    #> 
    #>     filter
    library(tibble)
    
    data(FB)
    FB <- as_tbl_time(FB, date)
    
    class(FB)
    #> [1] "tbl_time"   "tbl_df"     "tbl"        "data.frame"
    attr(FB, "index")
    #> <quosure: frame>
    #> ~date
    
    FB <- FB %>% add_column(adj2 = FB$adjusted + 1)
    
    class(FB)
    #> [1] "tbl_time"   "tbl_df"     "tbl"        "data.frame"
    attr(FB, "index")
    #> <quosure: frame>
    #> ~date
  14. krlmlr commented on Sep 16, 2017

    @krlmlr
    Member

    Thanks, happy to review a PR.

  15. added a commit that references this issue on Sep 17, 2017
  16. krlmlr commented on Oct 4, 2017

    @krlmlr
    Member

    Closed by #306.

  17. added a commit that references this issue on Nov 3, 2017
  18. added a commit that references this issue on Dec 28, 2017
  19. github-actions commented on Dec 12, 2020

    @github-actions
    Contributor

    This old thread has been automatically locked. If you think you have found something related to this, please open a new issue and link to this old issue if necessary.

  20. locked and limited conversation to collaborators on Dec 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions