Skip to content

read_csv() creates "spec" attributes which don't get updated nor lost by some tibble transformations #934

Description

@prosoitos

read_csv() (and probably the other read_delim funtions, though I haven't tested it) creates "spec" attributes which do not get updated nor lost when the tibble gets transformed and thus can end up being in total mismatch with the tibble they are associated with.

This does not create any problem, but it makes for very weird outputs to str() and creates unnecessarily lengthy outputs to dput().


Example:

I read a .csv file with read_csv() to create a tibble. I change its names, I select one variable out, I replace the remaining variables with vectors of different types and I end up with this tibble:

tbl <- structure(list(
  A = c("a", "b", "c"),
  B = 1:3),
  row.names = c(NA, -3L),
  spec = structure(list(
    cols = list(
      date = structure(list(format = ""), class = c("collector_date", "collector")),
      species = structure(list(), class = c("collector_character", "collector")),
      abundance = structure(list(), class = c("collector_double", "collector"))),
    default = structure(list(), class = c("collector_guess", "collector"))),
    class = "col_spec"), class = c("tbl_df", "tbl", "data.frame"))

So now, this is my tibble:

tbl
#>   A B
#> 1 a 1
#> 2 b 2
#> 3 c 3

And it gives these str() and dput() outputs:

str(tbl)
#> Classes 'tbl_df', 'tbl' and 'data.frame':    3 obs. of  2 variables:
#>  $ A: chr  "a" "b" "c"
#>  $ B: int  1 2 3
#>  - attr(*, "spec")=List of 2
#>   ..$ cols   :List of 3
#>   .. ..$ date     :List of 1
#>   .. .. ..$ format: chr ""
#>   .. .. ..- attr(*, "class")= chr  "collector_date" "collector"
#>   .. ..$ species  : list()
#>   .. .. ..- attr(*, "class")= chr  "collector_character" "collector"
#>   .. ..$ abundance: list()
#>   .. .. ..- attr(*, "class")= chr  "collector_double" "collector"
#>   ..$ default: list()
#>   .. ..- attr(*, "class")= chr  "collector_guess" "collector"
#>   ..- attr(*, "class")= chr "col_spec"

(Now the "spec" attribute has a wrong number of variables, wrong variable names, and wrong variable types 🤣 )

dput(tbl)
#> structure(list(A = c("a", "b", "c"), B = 1:3), row.names = c(NA, 
#> -3L), spec = structure(list(cols = list(date = structure(list(
#>     format = ""), class = c("collector_date", "collector")), 
#>     species = structure(list(), class = c("collector_character", 
#>     "collector")), abundance = structure(list(), class = c("collector_double", 
#>     "collector"))), default = structure(list(), class = c("collector_guess", 
#> "collector"))), class = "col_spec"), class = c("tbl_df", "tbl", 
#> "data.frame"))

(That's a long dput() output for such a simple tibble 😳 )

Of course, using the result of dput() to create the object in the first place in this example makes it look very circular and kind of silly, but I have to do that to demonstrate the idea without forcing you to download a .csv file or create one. But this is not just a theoretical point: a real life and very common scenario where this kicks in is this:

You create a tibble with read_csv(), you want to create a reprex, so you transform your tibble to make it very simple, then you use dput() to create the data of your very basic tibble and you end up with a ton of silly attributes in the output. Of course, you can simply get rid of the "spec" attribute from the result of dput() and all is good:

structure(list(
  A = c("a", "b", "c"),
  B = 1:3),
  row.names = c(NA, -3L))

gives the same tibble and it is easy enough to do. And even if you don't, those wrong attributes don't get in the way of anything. So not a big deal. But because it is somewhat hard to get new users to create good reproducible examples, it is a little quirk that doesn't help with explaining dput().

Activity

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