Skip to content

as_tibble.data.table() method?  #5698

Description

@ccsarapas

(I originally requested this at tidyverse/tibble/issues/1555, but they suggested requesting here instead.)

Would you consider adding a data.table method to as_tibble()? On extremely cursory testing, it may be as simple as adapting as_tibble.data.frame() with an extra line to remove the .internal.selfref attribute:

library(tibble)
library(data.table)
data(mpg, package = "ggplot2")

# two identical tibbles
mpg2 <- copy(mpg)
identical(mpg, mpg2)
#> [1] TRUE

# after converting to data.table and back to tibble, no longer identical
setDT(mpg2)
mpg2 <- as_tibble(mpg2)
identical(mpg, mpg2)
#> [1] FALSE

# identical again after removing ".internal.selfref" attribute
attr(mpg2, ".internal.selfref") <- NULL
identical(mpg, mpg2)
#> [1] TRUE

Created on 2023-09-22 with reprex v2.0.2

Activity

  1. jangorecki commented on Oct 4, 2023

    @jangorecki
    Member

    Adding such method means extending dependencies of DT. We rather would like to reduce them, also Suggested dependencies. In this case there are many recursive dependencies as well.

    Is there a reason why as_tibble.data.frame method doesn't work?
    going via data.frame should work after looking at as.data.frame.data.table and what is under

    setattr(x, ".internal.selfref", NULL)


    I believe there reason is presented by this minimal example, which doesn't need tibble to reproduce:

    library(data.table)
    data(mpg, package = "ggplot2")
    
    mpg2 <- copy(mpg)
    identical(mpg, mpg2)
    #> [1] TRUE
    
    setDT(mpg2)
    mpg2 = as.data.frame(mpg2)
    identical(mpg, mpg2)
    #> [1] FALSE
  2. MichaelChirico commented on Oct 4, 2023

    @MichaelChirico
    Member

    Isn't this the Enhances: dependency, and isn't the direction reversed, i.e., {data.table} would provide as.data.table.tibble() and {tibble} would provide as_tibble.data.table()?

  3. jangorecki commented on Oct 4, 2023

    @jangorecki
    Member

    So the problem is that initial dataset to which you want to compare to isn't just data.frame. If we use normal data.frame it works as expected.

    iris2 = copy(iris)
    identical(iris, iris2)
    # [1] TRUE
    
    setDT(iris2)
    iris2 = as.data.frame(iris2)
    identical(iris, iris2)
    # [1] TRUE

    if as_tibble would go via as.data.frame then all should work seamlessly, but it must be dispatching to second class attribute "data.frame" instead.
    Defining the following should be sufficient

    as_tibble.data.table = function(x) as_tibble(as.data.frame(x))

    because as.data.frame.data.table method handles removing its attributes.

    I believe this problem is not only related to data.table but any package that defines class extending data.frame and uses custom attributes. as_tibble will assume it is standard data.frame and not go via as_tibble.default. Therefore to resolve problem at the root it should be rather something like that

    as_tibble.data.frame = function(x) {
      if (!identical(class(x), "data.frame")) return(as_tibble(as.data.frame(x)))
      ... # continue old as_tibble.data.frame body
    }

    I noticed data.table would suffer from the same issue as tibble so I filled #5699 so problem can be addressed nicely without needing any package to add dependencies.

  4. jangorecki commented on Oct 4, 2023

    @jangorecki
    Member

    Indeed proposed one line change works as expected: https://github.com/Rdatatable/data.table/pull/5700/files

  5. TimTaylor commented on Oct 25, 2023

    @TimTaylor
    Contributor

    @jangorecki - do you want to raise this suggestion over at {tibble}? (I'm happy to do so if you'd prefer not to but didn't want to jump in over the top).

  6. added a commit that references this issue on Oct 27, 2023
  7. AngelFelizR commented on Nov 4, 2023

    @AngelFelizR
    Contributor

    Thanks @TimTaylor

    @ccsarapas I think that this issue is ready to be closed.

  8. added a commit that references this issue on Dec 19, 2023
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