Skip to Content

dput() reveal the secret behind S3 class

The rotation project in Zhang Lab gives me reason and time to master Rcpp

Beginning

library(magrittr)

After learning the basics of Rcpp, I can’t wait to chieve something. When a C++ function needs to return a data.frame, I decide that rather than DataFrame, I want to return a tibble.

Development

I think it’s a small dish, since “Advanced R” already teaches me how to add attributes.

tibble::tibble(x = 1:2) %>% attributes()
## $class
## [1] "tbl_df"     "tbl"        "data.frame"
## 
## $row.names
## [1] 1 2
## 
## $names
## [1] "x"

I assume the following code is enough:

auto x = IntegerVector::create(1, 2);
auto df = List::create(Named("x") = x;

df.attr("class") = CharacterVector::create("tbl_df", "tbl", "data.frame");
df.attr("row.names") = IntegerVector::create(1, 2);

But actually it’s NOT (note the *)

# A tibble: 2 x 2
  a         b
* <chr> <int>
1 23        1
2 hao       2

Then I tried to not set df.attr("row.names"), and get a 0 row tibble.

Finally I give up and use a R function wrapper to convert data.frame to tibble.

Climax

Some days later, I find the secret

tibble::tibble(x = 1:2) %>% dput()
## structure(list(x = 1:2), class = c("tbl_df", "tbl", "data.frame"
## ), row.names = c(NA, -2L))

My God, df.attr("row.names") should be IntegerVector::create(NA_INTEGER, -2), whoever can know that?

Afterword

The point of this story is no matter how complicated an object is, you can always inspect the secret by dput() .