8
votes

Fans of the Tidyverse regularly give several advantages of using tibbles rather than data frames. Most of them seem designed to protect the user from making mistakes. For example, unlike data frames, tibbles:

  • Don't need a ,drop=FALSE argument to not drop dimensions from your data.
  • Will not let the $ operator do partial matching for column names.
  • Only recycle your input vectors if they are of exactly length one.

I'm steadily becoming convinced to replace all of my data frames with tibbles. What are the primary disadvantages of doing so? More specifically, what can a data frame do that a tibble cannot?

Preemptively, I would like to make it clear that I am not asking about data.table or any big-picture objections to the Tidyverse. I am strictly asking about tibbles and data frames.

2
Tibbles are data frames - i.e. they have class data.frame, just with additional methods. So it's not so much what's different about a data frame, as how tibble modifies data frame behaviour. The differences are captured in the tibbles vignette. Personally I think the modified print method is the most useful feature.neilfws
Not an answer, but a long interesting thread on R-package-devel with several R authorities who discusses some of the implications of tibbles: tibbles are not data frames. In any case, Jim Lemon's metaphor on including tigers in the mixed martial arts competitions makes it worth reading thread.Henrik
@Henrik Certainly a fun read, but the summary seems to be as simple as "tibbles violate the Liskov substitution principle".J. Mini
Although "Matrix indexing [of a data.frame] x[i] with a logical or a 2-column integer matrix i using [ is not recommended" (?[.data.frame) it can be handy (e.g. here, here). It seems like such indexing can't be used on a tibble. tb = tibble(x = 1:3, y = 4:6); m = cbind(c(3, 2), c(2, 1)); tb[m]; df = as.data.frame(tb); df[m]Henrik
But again, this is supposedly just another example of protecting the tibble user from self-inflicted harm (coercion)Henrik

2 Answers

3
votes

From the trouble with tibbles, you can read :

there isn’t really any trouble with tibbles

However,

Some older packages don’t work with tibbles because of their alternative subsetting method. They expect tib[,1] to return a vector, when in fact it will now return another tibble.

This is what @Henrik pointed out in comments.

As an example, the length function won't return the same result:

library(tibble)
tibblecars <- as_tibble(mtcars)
tibblecars[,"cyl"]
#> # A tibble: 32 x 1
#>      cyl
#>    <dbl>
#>  1     6
#>  2     6
#>  3     4
#>  4     6
#>  5     8
#>  6     6
#>  7     8
#>  8     4
#>  9     4
#> 10     6
#> # ... with 22 more rows
length(tibblecars[,"cyl"])
#> [1] 1
mtcars[,"cyl"]
#>  [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
length(mtcars[,"cyl"])
#> [1] 32

Other example :

Invariants for subsetting and subassignment explains where the behaviour from tibble differs from data.frame.

These limitations being known, the solution given by Hadley in interacting with legacy code is:

A handful of functions don’t work with tibbles because they expect df[, 1] to return a vector, not a data frame. If you encounter one of these functions, use as.data.frame() to turn a tibble back to a data frame:

0
votes

Learned here: https://cran.r-project.org/web/packages/tibble/vignettes/tibble.html

There are three key differences between tibbles and data frames:

  • printing
  • subsetting
  • recycling rules

Tibbles:

  • Never change an input’s type (i.e., no more stringsAsFactors = FALSE!)
  • Never adjust the names of variables
  • Evaluate arguments lazily and sequentially
  • Never use row.names()
  • Only recycle vectors of length 1

Large data frames are displayed with as many rows as possible until the memory buffer is overwhelmed. R will stop in this situation at an arbitrary section of the data frame.

In tibble format only the first ten rows and all fitting columns are displayed. Colum data type and size of the data set is also displayed.